0

我编写了一个 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">
4

2 回答 2

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。否则你需要让你的主线程休眠很长时间。否则程序将退出。

于 2014-09-24T12:30:50.200 回答
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);
}

}

索引.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>
于 2014-10-01T07:07:35.217 回答