2014-09-23 39 views
0

我已经写了一个java桌面应用程序,它接受http请求使用嵌入式NanoHTTPD网络服务器https://github.com/NanoHttpd/nanohttpd,接收到http请求后,我的桌面应用程序进行一些活动并在执行作业时一直写入日志文本文件,当前打开网页的客户端必须等到整个作业完成并且整个页面被发送并且查看日志文件时,我希望日志数据一旦被添加到本地日志文件就发送到客户端,我知道这是使用ajax完成的,但我没有时间去学习它,只是如何使更新java中的某些对象直接反映到网页而无需发送整个页面。如何使用NanoHTTPD显示日志文件

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

需要多一点的解释存在。 。 我很困惑。 。 网页? Java桌面应用程序?桌面应用程序是否读取日志文件并通过nanohttpd将其发送到网页? – sethu 2014-09-23 08:43:27

+0

@sethu是的,我增加了更多的细节。 – 2014-09-23 11:25:43

回答

0

顺利地拿到了它的工作,它是由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> 
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。否则,你将需要让主线程睡很长时间。否则程序将会退出。

+0

不错的工作!问题是定期刷新页面将重新发送相同的http请求到服务器,在我的情况下导致一个新的工作(与最后一个相同)被执行,除了一个长日志文件,我认为它会使UI故障。 – 2014-09-24 14:40:57

+1

是的。你需要重新编码serve()方法来处理这个问题。 :)但我希望它能让你开始。 – sethu 2014-09-24 14:49:32