A step-by-step guide on displaying log files using NanoHTTPD

I have developed a Java desktop application that can receive HTTP requests using the embedded NanoHTTPD web server from https://github.com/NanoHttpd/nanohttpd. Once an HTTP request is received, my application performs certain tasks and logs the activity to a text file. Currently, when a client accesses the webpage, they have to wait until the entire process is completed, including viewing the log file. I am looking for a way to update the client with the log data in real-time as it is being added to the local log file.

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 isExecutingJob = 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: "+(isExecutingJob?"Waiting in queue.":"Immediate run.");
          if ("tcl".equalsIgnoreCase(paramKey)){
              try {
                  //if another request is being executed, wait until finished
                  while(isExecutingJob){
                    Thread.sleep(3000);
                  }
                  isExecutingJob=true;
                  SomeJobClass.doSomeWork(job.split(" "));
                  isExecutingJob=false;
                  ArrayList<String> lines=TextFiles.load(Logging.getLogFile().toString());
                  for(String line: lines){
                      msg+="<p>"+line+"</p>";
                  }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else{
            ArrayList<String> lines=TextFiles.load("some help.txt");
            for(String line: lines){
                msg+="<p>"+line+"</p>";
            }
        }
    }

    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);
    }
}

I came across this code snippet at , but unfortunately, it didn't work for my situation.

<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">

Answer №1

If you're looking for the simplest way to accomplish this task, consider using the code snippet below:

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();
        }
    }
}

Take note of the script at the end that triggers browser reload every 5 seconds. This eliminates the need for complex AJAX implementations. However, if you require a more sophisticated solution such as displaying only newly added lines in real-time, then the approach would need modifications.

Note: To ensure proper functionality, make sure to adjust the myThread.setDeamon(true) in the NanoHTTPD class run() method to false. Failure to do so might result in unexpected program termination unless the main thread is set to sleep for an extended period.

Answer №2

Finally managed to make it work, all thanks to jQuery!

server

public class TestServer extends NanoHTTPD {
  
  public static boolean isTesting = false;
    
  // Constructor
  public TestServer() {
      super(8080);
  }
    
  @Override 
  public Response serve(IHTTPSession session) {
      Method method = session.getMethod();
      Map<String,String> params = session.getParms();
      String uri = session.getUri();
        
      // Process URI
      if (uri.length() > 1){
          uri = uri.substring(1).toLowerCase();  // Remove leading '/'
      } else{
          uri = "";
      }

     // More server logic here...
      
      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>
    // JavaScript functions

</script>



</head>

<body >


    <h1>Remote Test Service</h1>

    <dev>

        <!-- UI Buttons and Controls -->

    </dev>

    <hr>
    
    <h3>Application content goes here...</h3>

    <dev id="main" style="width: 100%;">
    
        <dev id="content-container" style="float: left;">
            <!-- Content Block -->
        </dev>
        
        <hr>
        
        <dev id="log-container" style="float: right;">
            <!-- Log and Status Display -->
        </dev>
    
    </dev>
    

</body>

</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Attempting to duplicate Codepen's code onto my local machine

Trying to figure out how to make this work locally after finding it on codepen https://codepen.io/oxla/pen/awmMYY Seems like everything works except for the functionality part. I've included the JS File and the latest Jquery in my code. <head&g ...

Making an AJAX request in a Java controller without using jQuery

Currently, I am utilizing the code below to perform an AJAX request using jQuery. $.ajax({ url : "http://localhost:8080/v1/student?studentId=a3a802fcc7604a46a49d5c57150d8d99", type : "GET", crossDomain : true, timeout : 50000, success ...

Having trouble binding form data to a React component with the onChange() method?

I've been working on developing an email platform exclusively for myself and encountered a roadblock with this React form not updating state when data is entered. After identifying the issue, it appears that the main problem lies in the React form not ...

What is the best way to convert a string in JavaScript to be case-insensitive?

Can anyone assist me? Challenge: Develop a function called indexOfIgnoreCase which takes in two strings and identifies the first instance of the second string within the first string. This function should be insensitive to letter case. For example, indexO ...

Is there a way to efficiently line up and run several promises simultaneously while using just one callback function?

I am currently utilizing the http request library called got. This package makes handling asynchronous http connections fast and easy. However, I have encountered a challenge with got being a promisified package, which presents certain difficulties for me ...

Drawing recursive 2D tree fractals using WebGL technology

Attempting to create a binary fractal tree in webgl, but struggling with the branch angles not aligning as desired. The approach involves plotting vertex points into an array, converting it into a float32array, and then utilizing drawArrays(LINE_STRIPE) fo ...

Difficulties encountered while attempting to modify a class using Javascript

Recently, I've encountered an issue with my JavaScript where I am unable to keep a particular element's class changed. Despite attempting to change the class to "overlist", it only stays that way briefly before switching back to its original stat ...

Transforming Excel data into JSON format using ReactJS

Currently, I am in the process of converting an imported Excel file to JSON within ReactJS. While attempting to achieve this task, I have encountered some challenges using the npm XLSX package to convert the Excel data into the required JSON format. Any as ...

Acquire information asynchronously in JavaScript while inside a for loop

Recently, I've been exploring this particular function snippet: function add_cnh(arr_clelem){ var id=arr_clelem.getElementsByClassName("present")[0].id; var date=arr_clelem.getElementsByClassName("present")[0].getAttribute('date'); v ...

Symfony 2.8 upgrade for enhanced loading capabilities

Currently, I have a Task.php entity that retrieves chat messages from the database and displays them on the page. Here is how the messages are retrieved in the entity: /** * @return \Doctrine\Common\Collections\Collection|static */ p ...

Steps to opening a second hyperlink in the same window after initially clicking on Hyperlink1

I'm currently working on a project that involves a main web page with three links: Link1, Link2 and Link3. The requirement is for Link1 to open in a new window (window1) when clicked, while Link2 and Link3 should open in the same window as Link1 (wind ...

The Persistence of Java String Memory Leak

Although I am not a Java expert, I am facing an issue with my code. It reads a file into a String, and this process occurs every 5 minutes. The size of the file can vary, sometimes being 100 lines and other times 1000 lines. Unfortunately, I am experienci ...

Loading React.js components before data fetch is complete

My app is encountering an issue where it renders before the fetch operation is completed, resulting in incorrect rendering. Below is the code snippet: componentWillMount() { fetch('http://localhost:8081/milltime/login?users='+this.state.e ...

inserting a dynamic variable into a JSON string

My goal is to create a javascript object, var systemName = {"system" : varA}; However, I want the object to be structured like `{"system" :"varA"} where varA contains the variable value but is enclosed in double quotes. I attempted {"system" : "'+ ...

Converting JavaScript functions to Java remote method interfaces

Experience: A while back, I was involved in developing a Java Server-Client application for building automation purposes. Initially, we used Java RMI to connect the server and client but soon realized that utilizing JavaScript for the client side would be ...

Warning in module-info class about the service interface being provided but not exported or utilized

Java9 - jdk-9+181 intelliJ - 2017.2.2 built on August 9,2017 The java.management.rmi's module-info.java implementation is akin to the following: module java.management.rmi { ... requires transitive java.management; exports com.sun.jmx.r ...

Receiving a notification when attempting to log in with incorrect credentials

I am currently working on an Angular login page implementation using a username and password setup. When the user enters incorrect credentials, I want to display an alert message indicating the same. Here is the HTML code snippet for the form: <form [f ...

Unusual conduct when employing basic directive for validation messages

Within my code, I have implemented the following directive: App.directive("validateMsgFor", function(){ return{ templateUrl : "view/templates/validateMsgFor.html", restrict: "E", scope: { field : "=" } ...

What is the best way to locate a particular JSON key value pair through JavaScript?

I'm in the process of creating a unique app that forecasts the weather for an upcoming event based on the city location specified. To achieve this, I am utilizing two APIs - one API provides an array of objects representing each event by an artist ent ...

The useEffect function is failing to execute when deploying on Vercel with Vite and React Router

After successfully deploying a React site using Vite on Vercel, with React Router for routing and a separate backend service, everything seemed to be working fine on my local machine. However, when testing the deployment on Vercel, I encountered an issue w ...