我编写了一个java桌面应用程序,它接受使用嵌入式NanoHTTPD Web服务器https://github.com/NanoHttpd/nanohttpd的http请求,在收到http请求后,我的桌面应用程序进行了一些活动,并在执行其作业时保持写入日志文本文件,当前客户端打开网页必须等到整个作业完成并发送整个页面并查看日志文件,我希望将日志数据一旦添加到本地日志文件就发送到客户端,我知道这个是使用ajax完成但我还没有时间去学习它,只是如何使java中的某些对象更新直接反映到网页而不需要发送整个页面。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Map;
import common.Logging;
import common.TextFiles;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.ServerRunner;
import fi.iki.elonen.SimpleWebServer;
public class TestServer extends NanoHTTPD {
static boolean isDoingAJob=false;
public TestServer() {
super(8080);
}
@Override public Response serve(IHTTPSession session) {
Method method = session.getMethod();
Map<String,String> params = session.getParms();
String uri = session.getUri();
System.out.println(method + " '" + uri + "' ");
String msg = "<html><style>h1 { color: green; background-color: black;}p { color: gray; background-color: black;}div { color: gray; background-color: black;}body { color: gray; background-color: black;}</style><body><h1>Remote Test Service</h1>";
Map<String, String> parms = session.getParms();
for(String paramKey:parms.keySet()){
String job=params.get(paramKey);
msg+="Status: "+(isDoingAJob?"Waited in queue.":"Immediate run.");
if ("tcl".equalsIgnoreCase(paramKey)){
try {
//if another request is being executed wait until finished
while(isDoingAJob){
Thread.sleep(3000);
}
//Raise a flag while executing a test run
isDoingAJob=true;
SomeJobClass.doSomeWork(job.split(" "));
isDoingAJob=false;
ArrayList<String> lines=TextFiles.load(Logging.getLogFile().toString());
for(String line: lines){
msg+="<p>"+line+"</p>";
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else{
//echo help if parameter key is not tcl
ArrayList<String> lines=TextFiles.load("some help.txt");
for(String line: lines){
msg+="<p>"+line+"</p>";
}
}
}
//show this when no parameters passed
if (parms.isEmpty()){
ArrayList<String> lines=TextFiles.load("some help.txt");
for(String line: lines){
msg+="<p>"+line+"</p>";
}
}
msg += "</body></html>";
return new NanoHTTPD.Response(msg);
}
public static void main(String[] args) {
ServerRunner.run(TestServer.class);
}
}
我发现此代码http://www.binpress.com/app/jquery-log-viewer/570但对我不起作用
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="jquery.logviewer.js"></script>
<script type="text/javascript">
jQuery(document).bind("ready", function() {
jQuery('#logcontent').logViewer({logUrl: 'log.html'});
});
</script>
</head>
<body>
Live log:<br/>
<textarea id="logcontent" autocomplete="off">
答案 0 :(得分:1)
最简单的方法如下:
package fi.iki.elonen;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class Stackoverflowtest extends NanoHTTPD{
static boolean isDoingAJob=false;
public Stackoverflowtest() {
super(8080);
}
@Override public Response serve(IHTTPSession session) {
Method method = session.getMethod();
Map<String,String> params = session.getParms();
String uri = session.getUri();
System.out.println(method + " '" + uri + "' ");
String msg = "<html><style>h1 { color: green; background-color: black;}p { color: gray; background-color: black;}div { color: gray; background-color: black;}body { color: gray; background-color: black;}</style><body><h1>Remote Test Service</h1>";
try {
List<String> lines= FileUtils.readLines(new File("<fileloc>"));
for(String line: lines){
msg+="<p>"+line+"</p>";
}
} catch (Exception e) {
e.printStackTrace();
}
msg += "</body><script>setTimeout(function(){\n" +
" window.location.reload(1);\n" +
"}, 5000);</script></html>";
return new NanoHTTPD.Response(msg);
}
public static void main(String[] args) {
try {
new Stackoverflowtest().start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意底部的脚本。它只是让浏览器每5秒重新加载一次。对于简单的解决方案,您不需要ajax或任何东西。如果你想构建更复杂的东西,比如只将新添加的行添加到浏览器中,那么解决方案需要稍微改变一下。
注意:为了实现这一点,在NanoHTTPD类中,在run()方法中,我将myThread.setDeamon(true)更改为false。否则你需要让你的主线程长时间睡眠。否则该程序将退出。
答案 1 :(得分:1)
成功地让它工作,它是通过jquery
服务器强>
public class TestServer extends NanoHTTPD {
public static boolean isTesting=false;
public TestServer() {
super(8080);
}
@Override public Response serve(IHTTPSession session) {
Method method = session.getMethod();
Map<String,String> params = session.getParms();
String uri = session.getUri();
if (uri.length()>1){
//remove the starting /
uri=uri.substring(1).toLowerCase();
} else{
uri="";
}
System.out.println("method: ["+method + "] uri: [" + uri +"]");
String msg = "";
Map<String, String> parms = session.getParms();
if ("".equals(uri)){
//TextFiles.loadString just loads the whole file in a single string.
msg=TextFiles.loadString("C:/server/index.html");
return new NanoHTTPD.Response(msg);
}else//handle log refreshing
if ("log".equals(uri)){
System.out.println("Log requested ...");
while(!Logging.webLogQueue.isEmpty()){
msg+="<p>"+Logging.webLogQueue.poll()+"</p>";
}
return new NanoHTTPD.Response(msg);
}else if ("suites".equals(uri)){
System.out.println("suites requested ...");
// fill msg with suites ...
return new NanoHTTPD.Response(msg);
} else if (("status".equals(uri))){
System.out.println("status requested ...");
msg=(isTesting?"Testing...":"Idle");
return new NanoHTTPD.Response(msg);
}else{
for(String paramKey:parms.keySet()){
String[] value=params.get(paramKey).split(" ");
Logging.log("<p>"+Logging.getTimeStamp()+" Parameter: "+paramKey+"="+ params.get(paramKey)+"</p>");
if ("tcl".equalsIgnoreCase(paramKey)){
Logging.log("run started : "+params.get(paramKey));
while(isTesting){
try {
Logging.log("test pending : "+params.get(paramKey));
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Logging.log("test starting: "+params.get(paramKey));
//Raise a flag while executing a test run
isTesting=true;
try {
Logging.log("Attempting to execute: "+params.get(paramKey));
BananaTest.execute(value);
Logging.log("Ttest finished: "+params.get(paramKey));
} catch (Exception e) {
e.printStackTrace();
}
isTesting=false;
}
}
}
msg=TextFiles.loadString("C:/server/index.html");
return new NanoHTTPD.Response(msg);
}
public static void main(String[] args) {
ServerRunner.run(TestServer.class);
}
}
<强>的index.html 强>
<html>
<style>
h1 {
color: green;
background-color: black;
}
p {
color: gray;
background-color: black;
}
div {
color: gray;
background-color: black;
}
body {
color: gray;
background-color: black;
}
</style>
<head>
<script src="file///jquery-1.8.2.min.js"></script>
<script>
// tail effect
function tailScroll() {
if (document.getElementById("auto-scroll").checked) {
var height = $("#log-container").get(0).scrollHeight;
$("#log-container").animate({
scrollTop: height
}, 500);
}
}
var auto_refresh_log = setInterval(
function() {
var statusDiv = document.getElementById("status");
if (statusDiv.innerHTML.indexOf("Idle.") < 0) {
$.get("log",
function(data, status) {
if (data) {
var logDiv = document.getElementById("log");
$("#log").append(data);
tailScroll();
};
}
)
}
}, 500
);
var auto_refresh_status = setInterval(
function() {
$('#status').load("status").fadeIn("slow");
}, 500);
$(document).ready(function() {
$('#suites').load("suites").fadeIn("slow");
$('#status').load("status").fadeIn("slow");
$('#war-info').load("war-info").fadeIn("slow");
$('#log').load("log").fadeIn("slow");
$('#build').load("build").fadeIn("slow");
$("#results").hide();
document.getElementById("auto-scroll").checked = true;
});
function getSuites() {
$('#suites').load("suites").fadeIn("slow");
}
function runSuites() {
//clearLog();
var collection = document.getElementById("suites").getElementsByTagName('INPUT');
var suiteList = "";
for (var x = 0; x < collection.length; x++) {
if (collection[x].type.toUpperCase() == 'CHECKBOX')
if (collection[x].checked) {
suiteList = suiteList + " " + collection[x].id;
}
}
//if no suite selected don't send
if (suiteList) {
$.get("/get?tcl=" + suiteList.substring(1));
}
}
function execute() {
var text = $('textarea#gtester').val();
//if no suite selected don't send
if (text) {
$.get("/get?tcl=" + text);
$('textarea#gtester').val('');
}
}
function clearLog() {
var logDiv = document.getElementById("log");
logDiv.innerHTML = "";
}
function restartServer() {
$.get("restart");
window.location.reload(1);
}
function restartSolr() {
$.get("restart-solr");
}
function restartSonar() {
$.get("restart-sonar");
}
function pause() {
$.get("pause");
}
function abort() {
$.get("abort");
}
$("form#data").submit(function() {
var formData = new FormData($(this)[0]);
$.ajax({
url: window.location.pathname,
type: 'POST',
data: formData,
async: false,
success: function(data) {
alert(data)
},
cache: false,
contentType: false,
processData: false
});
return false;
});
function selectAll(cb){
var collection = document.getElementById("suites").getElementsByTagName('INPUT');
for (var x=0; x<collection.length; x++) {
if (collection[x].type.toUpperCase()=='CHECKBOX')
collection[x].checked = cb.checked;
}
}
function toggleLog(){
if ($('#log').is(':visible')) {
$('#log').hide();
$('#results').show();
}else{
$('#log').show();
$('#results').hide();
}
}
</script>
</head>
<body >
<dev id="build" style="float:right;"> </dev>
<h1>Remote Test Service</h1>
<dev>
<dev>
<!--<button id="get-suites" onclick="getSuites()">Get latest suite list</button> -->
<button id="run-suites" onclick="runSuites()" style="background: lightgreen; ">Run Tests</button>
<button id="pause" onclick="pause()">Pause Test</button>
<button id="abort" onclick="abort()">Abort Test</button>
</dev>
<dev style="float=right">
<button id="restart-test" onclick="restartServer()">Restart Test Server</button>
<button id="restart-solr" onclick="restartSolr()">Restart Solr Server</button>
<button id="restart-sonar" onclick="restartSonar()" >Restart Sonar Service</button>
</dev>
<h3>
<b>Status:</b>
<dev id="status" >
</dev>
</h3>
</dev>
<dev id="main" >
<dev style="width: 30%; float:left; height: 80%; overflow: auto;">
<dev>
<hr>
<h2>Banana Tests: </h2>
<input type="checkbox" id="selectAll" onclick='selectAll(this);'>Select All <br> </input>
</dev>
<hr>
<dev id="suites" style="overflow-y: auto; white-space: nowrap;">
</dev>
<hr>
<h3>WAR file Upload: </h3>
<form id="datafiles" method="post" enctype="multipart/form-data">
<input name="warfile" type="file" />
<!-- <input type="text" name="Description" value="WAR file description..." /> !-->
<button>Submit</button>
</form>
<dev>
<h3> <a href="file///D:/solr-4.8.1/searchlogs/webapps/banana.war" download>Download current War file</a></h3>
<hr>
<dev>
<h3>Current WAR file info: </h3> </dev>
<dev id="war-info"> </dev>
</dev>
<hr>
<dev>
<h3>
<b>GTester Console:</b> <button id="execute" onclick="execute()">Execute</button>
</h3>
<textarea id="gtester" cols="50" rows="1" onkeydown="if (event.keyCode == 13) { execute(); return false; }">
</textarea>
</dev>
</dev>
<dev id="log-super-container" style="width: 70%; float:right; height: 80%; overflow-y:auto; overflow-x:auto; white-space: nowrap;">
<dev style="float:left;">
<button id="clear-log" onclick="clearLog()" >Clear log</button>
<button id="toggle-log" onclick="toggleLog()" >Log/TCs state</button>
<input type="checkbox" id="auto-scroll" >Auto scroll <br> </input>
</dev>
<dev style="float:left;">
</dev>
<dev id="log-container" style="width: 100%; height: 95%; float:right; overflow:auto; ">
<dev id="log" style="overflow: auto; white-space: nowrap;">
</dev>
<dev id="results" style="overflow: auto; white-space: nowrap;">
<h3>Passed:<br></h3>
<dev id="passed">
0
</dev>
<h3>Current:<br></h3>
<dev id="current">
0
</dev>
<h3>Failed:<br></h3>
<dev id="failed">
0
</dev>
</dev>
</dev>
</dev>
</dev>
</body>
</html>