gpt4 book ai didi

java - 如何使用 Tomcat 管理后端进程?

转载 作者:行者123 更新时间:2023-11-28 22:09:02 27 4
gpt4 key购买 nike

我有一个网页,用户按下按钮并在专有应用程序(驻留在 Tomcat 中)中启动操作。

该操作是一个长时间运行的过程,我必须查看正在发生的事情的唯一方法是登录到服务器并查看日志文件。

我编写了一个快速的 Java 函数来读取日志文件并提供有关正在发生的事情的反馈。 (本质上它只是跟踪文件并解析出我需要的东西)

我希望能够添加一个 jsp,我可以在不登录服务器的情况下查看输出。

===

从设计的角度来看,我理解 JSP 应该快速返回结果,而不是继续处理。

所以我的想法是创建一个简单的网页,查询 jsp 的更新并将最新信息写入屏幕。等待 30 秒,再次轮询服务器,并附加最新的更新。

我正在努力掌握的是如何让 JSP 与后端进程进行通信,以及应该如何生成/终止该后端进程。

这是一个非常偶然的事情(每两周一次,开始到完成需要一两个小时),所以我不希望守护进程一直运行。我希望能够临时打开和关闭它。

如果我从一个简单的 servlet 中生成一个进程,我如何在完成后结束该进程?我如何与它沟通?

最佳答案

您可以创建一个 java.lan.Runnable 女巫读取文件内容并将其保存到缓冲区中。 Runnable 使用 while 循环读取文件内容,因为可以从外部设置中断条件,执行 Runnable 的线程将在 Runnable 的 run 方法终止时终止终止。

在您的 JSP 中,您可以创建一个 java.lang.Thread 并将您的 Runnable 实例传递给它。将可运行对象的实例保存在 ServletContext 中,以便您可以跨请求访问它。如果您想终止轮询而不只是从 JSP 设置 Runnable 的中断条件,则 rum 方法将终止,因此线程也会终止。

您可以使用 javascript setInterval() 函数和 XMLHttpRequest 刷新页面。

下面是一个基本实现示例(希望能满足您的要求):

轮询可运行

package com.web;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

public class FilePollingThread implements Runnable {

private String filepath = null;
private boolean polling = false;
private StringBuffer dataWritenAfterLastPoll = null;
private String error = null;

public FilePollingThread(String filepath) {
this.filepath = filepath;
}

@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(filepath)));
dataWritenAfterLastPoll = new StringBuffer();
polling = true;

String line = null;

while(polling) {
try {
line = br.readLine();
while(line == null) {
try {
Thread.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
error = e.toString();
}
line = br.readLine();
}
dataWritenAfterLastPoll.append(markUp(line));
} catch (IOException e) {
e.printStackTrace();
error = e.toString();
}
}

} catch (FileNotFoundException e) {
e.printStackTrace();
error = e.toString();
} finally {
if(br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
error = e.toString();
}
}
}
}

private String markUp(String line) {
String markup = "";
if(line != null) {
markup = "<div style=\"height: 6px\"><span style=\"line-height: 1.1;\">" + line + "</span></div>\n";
}
return markup;
}

public synchronized void stopPolling() {
polling = false;
}

public synchronized String poll() {
String tmp = markUp(error == null ? "Not ready" : error);
if(dataWritenAfterLastPoll != null) {
tmp = dataWritenAfterLastPoll.toString();
dataWritenAfterLastPoll = new StringBuffer();
}
return tmp;
}
}

然后一个 JSP 女巫发起轮询并继续检索数据

<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ page import="com.web.FilePollingThread" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Poll file</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<link rel="stylesheet" type="text/css" href="style/default.css"></link>
<script type="text/javascript">
var c = 1;
var ih;
var polling = false;
var filepath = null;
function startPolling(interval) {
ih = setInterval(function () {
try {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function () {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
var w = getElementById('ajax_content');
w.innerHTML = w.innerHTML + xmlHttp.responseText;
getElementById('page_refresh').innerHTML = c++;
polling = true;
window.scrollTo(0, document.body.scrollHeight);
} else {
polling = false;
throw 'HTTP ' + xmlHttp.status;
}
}
};
xmlHttp.open('GET', 'pollfile.jsp?filepath=' + filepath + '&c=' + c, true);
xmlHttp.send();
} catch(e) {
alert('Error at startPolling: ' + e);
clearInterval(ih);
}
}, interval);
}

function startStopPolling() {
var orgPolling = polling;
try {
if(polling) {
polling = false;
clearInterval(ih);
doPolling();
} else {
polling = true;
doPolling();
startPolling(1000);
}
flipStartStopButtonsLabel();
} catch(e) {
polling = orgPolling;
flipStartStopButtonsLabel();
alert('Error at startStopPolling: ' + e);
}
}

function flipStartStopButtonsLabel() {
var label;
if(polling) {
c = 1;
label = 'Stop polling';
getElementById('page_refresh').innerHTML = '0';
} else {
label = 'Sart polling';
getElementById('page_refresh').innerHTML = 'stoped';
}
var buttons = document.getElementsByName('start_stop_polling');
if(buttons) {
for(var i = 0; i < buttons.length; i++) {
buttons[i].value = label;
}
}
}

function doPolling() {
var url = 'pollfile.jsp?polling=';
if(polling) {
filepath = getElementById('filepath');
if(filepath && filepath.value && filepath.value.length > 0) {
url += 'true&filepath=' + encodeURIComponent(filepath.value);
} else {
throw 'No filepath specified.';
}
} else {
url += 'false';
}
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function () {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status != 200) {
throw 'HTTP ' + xmlHttp.status;
}
}
};
xmlHttp.open('POST', url, false);
xmlHttp.send();
}

function clearWindow() {
var w = getElementById('ajax_content');
if(w) {
w.innerHTML = '';
}
}

function getElementById(id) {
try {
if(id) {
elm = document.getElementById(id);
return elm;
}
} catch(e) {
alert('Error at getElementById: ' + e);
}
return null;
}
</script>
</head>
<body>


<%
String polling = request.getParameter("polling");

if("true".equals(polling)) {
String filepath = request.getParameter("filepath");
if(filepath != null && filepath.length() > 0) {
FilePollingThread pollingThread = new FilePollingThread(filepath);
new Thread(pollingThread, "polling thread for file '" + filepath + "'").start();
request.getServletContext().setAttribute("pollingThread", pollingThread);
}
} else if("false".equals(polling)) {
FilePollingThread pollingThread = (FilePollingThread) request.getServletContext().getAttribute("pollingThread");
if(pollingThread != null) {
pollingThread.stopPolling();
}
} else {
FilePollingThread pollingThread = (FilePollingThread) request.getServletContext().getAttribute("pollingThread");
if(pollingThread != null) {
response.getWriter().println(pollingThread.poll());
response.getWriter().close();
return;
}
}
%>
<div class="label">
<span>Page polling:</span>
</div>
<div style="float: left;">
<span id="page_refresh">0</span>
</div>
<div class="clear_both">&nbsp;</div>
<form id="input_form" action="pollfile.jsp" method="get">
<div>
<div style="float: left;">
<label>Filepath:
<input style="height: 24px;" id="filepath" type="text" size="120" value=""/>
</label>
</div>
<div style="clear: both;"/>
<div style="float: left;">
<input style="height: 24px;" name="start_stop_polling" id="start_stop_polling_button" type="button" onclick="startStopPolling(); return false;" value="Start polling"/>
</div>
<div style="float: left;">
<input style="height: 24px;" name="clear_window" id="clear_window_button" type="button" onclick="clearWindow(); return false;" value="Clear"/>
</div>
<div style="clear: both;">&nbsp;</div>
</div>
</form>
<div id="ajax_content">
</div>
<div>
<div style="float: left;">
<input style="height: 24px;" name="start_stop_polling" id="start_stop_polling_button" type="button" onclick="startStopPolling(); return false;" value="Start polling"/>
</div>
<div style="float: left;">
<input style="height: 24px;" name="clear_window" id="clear_window_button" type="button" onclick="clearWindow(); return false;" value="Clear"/>
</div>
<div style="clear: both;">&nbsp;</div>
</div>
</body>
</html>

编辑

FilePollingThread 中存在错误:如果文件中没有可用数据,线程可能会陷入内部 while 循环。应该是

while(line == null && polling)

JSP 也不能在 IE 上运行(在 IE9 上测试)。似乎是将数据写入行中的响应

response.getWriter().println(pollingThread.poll());

包含漏洞页面的HTML。如果添加到目标 div IE 似乎无法呈现它。

我使用一个简单的静态 HTML 文件和一个 servlet 制作了另一个版本,因为它可以更好地控制写入响应的内容。

如果您对代码感兴趣,请告诉我。

关于java - 如何使用 Tomcat 管理后端进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15132726/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com