Java 如何使用NanoHTTPD显示日志文件
我已经编写了一个java桌面应用程序,它使用嵌入式NanoHTTPD web服务器接受http请求,在收到http请求后,我的桌面应用程序进行一些活动,并在执行其作业时不断写入日志文本文件,目前,客户端打开网页必须等到整个工作完成,整个页面被发送,日志文件被查看,我希望日志数据被添加到本地日志文件后立即发送到客户端,我知道这是使用ajax完成的,但我还没有时间学习它,简单地说,如何使java中某些对象的更新直接反映到web页面,而无需发送整个页面Java 如何使用NanoHTTPD显示日志文件,java,javascript,ajax,logging,nanohttpd,Java,Javascript,Ajax,Logging,Nanohttpd,我已经编写了一个java桌面应用程序,它使用嵌入式NanoHTTPD web服务器接受http请求,在收到http请求后,我的桌面应用程序进行一些活动,并在执行其作业时不断写入日志文本文件,目前,客户端打开网页必须等到整个工作完成,整个页面被发送,日志文件被查看,我希望日志数据被添加到本地日志文件后立即发送到客户端,我知道这是使用ajax完成的,但我还没有时间学习它,简单地说,如何使java中某些对象的更新直接反映到web页面,而无需发送整个页面 import java.util.ArrayLi
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);
}
}
import java.util.ArrayList;
导入java.util.LinkedList;
导入java.util.Map;
导入通用日志;
导入common.text文件;
进口fi.iki.elonen.NanoHTTPD;
导入fi.iki.elonen.ServerRunner;
导入fi.iki.elonen.SimpleWebServer;
公共类TestServer扩展了NanoHTTPD{
静态布尔值isDoingAJob=false;
公共测试服务器(){
超级(8080);
}
@覆盖公共响应服务(IHTTP会话){
Method=session.getMethod();
Map params=session.getParms();
字符串uri=session.getUri();
System.out.println(方法+“'+uri+”);
String msg=“h1{color:green;background color:black;}p{color:gray;background color:black;}div{color:gray;background color:black;}body{color:gray;background color:black;}远程测试服务”;
Map parms=session.getParms();
for(字符串paramKey:parms.keySet()){
字符串job=params.get(paramKey);
msg+=“状态:”+(isDoingAJob?“正在队列中等待。”:“立即运行”);
if(“tcl”.equalsIgnoreCase(paramKey)){
试一试{
//如果正在执行另一个请求,请等待完成
while(isDoingAJob){
睡眠(3000);
}
//在执行测试运行时引发标志
isDoingAJob=true;
SomeJobClass.doSomeWork(job.split(“”));
isDoingAJob=false;
ArrayList lines=TextFiles.load(Logging.getLogFile().toString());
用于(字符串行:行){
味精+=“”+line+“”;
}
}捕获(例外e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}否则{
//如果参数键不是tcl,则回显帮助
ArrayList lines=TextFiles.load(“some help.txt”);
用于(字符串行:行){
味精+=“”+line+“”;
}
}
}
//未传递任何参数时显示此选项
if(parms.isEmpty()){
ArrayList lines=TextFiles.load(“some help.txt”);
用于(字符串行:行){
味精+=“”+line+“”;
}
}
味精+=”;
返回新的NanoHTTPD.Response(msg);
}
公共静态void main(字符串[]args){
ServerRunner.run(TestServer.class);
}
}
我找到了这个代码,但不适用于我
<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">
jQuery(document).bind(“ready”,function()){
jQuery('#logcontent').logViewer({logUrl:'log.html'});
});
实时日志:
最简单的方法如下:
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();
}
}
}
包fi.iki.elonen;
导入org.apache.commons.io.FileUtils;
导入java.io.File;
导入java.io.IOException;
导入java.util.List;
导入java.util.Map;
公共类Stackoverflowtest扩展了NanoHTTPD{
静态布尔值isDoingAJob=false;
公共堆栈溢出测试(){
超级(8080);
}
@覆盖公共响应服务(IHTTP会话){
Method=session.getMethod();
Map params=session.getParms();
字符串uri=session.getUri();
System.out.println(方法+“'+uri+”);
String msg=“h1{color:green;background color:black;}p{color:gray;background color:black;}div{color:gray;background color:black;}body{color:gray;background color:black;}远程测试服务”;
试一试{
列表行=FileUtils.readLines(新文件(“”);
用于(字符串行:行){
味精+=“”+line+“”;
}
}捕获(例外e){
e、 printStackTrace();
}
msg+=“设置超时(函数(){\n”+
“窗口.位置.重新加载(1);\n”+
"}, 5000);";
返回新的NanoHTTPD.Response(msg);
}
公共静态void main(字符串[]args){
试一试{
新建Stackoverflowtest().start();
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
请注意底部的脚本。它只是让浏览器每5秒重新加载一次。对于一个简单的解决方案,您不需要ajax或任何东西。如果您想构建更复杂的东西,比如只将新添加的行添加到浏览器中,那么解决方案需要做一些更改
注意:为了实现这一点,在NanoHTTPD类的run()方法中,我将myThread.setDeamon(true)更改为false。否则,您将需要让主线程长时间睡眠。否则程序将退出。通过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);
}
公共类TestServer扩展了NanoHTTPD{
公共静态布尔isting=false;
公共测试服务器(){
超级(8080);
}
@覆盖公共响应服务(IHTTP会话){
Method=session.getMethod();
Map params=session.getParms();
字符串uri=session.getUri();
if(uri.length()>1){
//拆下起动马达/
uri=uri.substring(1.toLowerCase();
}否则{
uri=“”;
}
System.out.println(“方法:[“+method+”]uri:[“+uri+”]);
字符串msg=“”;
Map parms=session.getParms();
如果(“.”等于(uri)){
//TextFiles.loadString只在单个字符串中加载整个文件。
<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>