1

ユーザーがボタンを押して、所有権のあるアプリ(Tomcatにある)でアクションを開始するWebページがあります。

そのアクションは長時間実行されるプロセスであり、何が起こっているかを確認する必要がある唯一の方法は、サーバーにログオンしてログファイルを確認することです。

ログファイルを読み取り、何が起こっているかについてフィードバックを提供する簡単なJava関数を作成しました。(基本的には、ファイルをテールし、必要なものを解析します)

サーバーにログインせずに出力を表示できるjspを追加できるようにしたいと思います。

===

設計の観点からは、JSPは処理を続けるだけでなく、結果を迅速に返す必要があることを理解しています。

したがって、私の考えは、jspに更新を照会し、最新の情報を画面に書き込む単純なWebページを作成することです。30秒待ってから、サーバーを再度ポーリングして、最新の更新を追加します。

私が把握するのに苦労しているのは、JSPをバックエンドプロセスと通信させる方法と、そのバックエンドプロセスをどのように生成/強制終了するかです。

これは非常にまれなことです(2週間に1回、開始から完了までに1〜2時間かかります)ので、デーモンを常に実行したくありません。一時的にオンにしてオフにできるようにしたい。

単純なサーブレット内からプロセスを生成する場合、完了したらそのプロセスを終了するにはどうすればよいですか?そして、どうすればそれと通信できますか?

4

2 に答える 2

2

java.lan.Runnableファイルの内容を読み取り、バッファに保存するウィッチを作成できます。whileRunnableは、ブレーク条件を外部から設定できるループ内でファイルの内容を読み取ります。Runnableを実行しているスレッドは、Runnable のrunメソッドが終了すると終了します。

JSP ではjava.lang.Thread、Runnable のインスタンスを作成してそれに渡すことができます。実行可能ファイルのインスタンスを に保存ServletContextして、リクエスト間でアクセスできるようにします。JSP から Runnable のブレーク条件を設定するだけでなく、ポーリングを終了したい場合は、rum メソッドが終了し、スレッドも終了します。

JavaScriptsetInterval()関数を使用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 の testet) では動作しません。行のレスポンスに書き込まれたデータのようです

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

ホールページの HTML が含まれています。ターゲット div IE に追加すると、レンダリングできないようです。

単純な静的 HTML ファイルとサーブレットを使用して別のバージョンを作成しました。これは、応答に書き込まれる内容をより詳細に制御できるためです。

コードに興味がある場合は、お知らせください。

于 2013-02-28T17:05:01.873 に答える
1

バックグラウンドプロセスを制御するには、 JMSなどの使用を検討する必要があります。

制御のために、フロントエンドコードはプロセスの開始/停止/検査のメッセージを送信できます。
監視のために、プロセスはフロントエンドコードが読み取るためにJMSトピックに公開できます。

于 2013-02-28T17:11:11.620 に答える