0

I have a device which sends a JSON message via HTTP POST, to a web server. The server receives the JSON message as payload and decodes and prints it on the web page and also sends back a 200 OK response to the post.

Now, I am trying to replicate the same with a fake Java client code to act as the device and a fake server using servlet and JSP. The servlet code and JSP run as one project and the Java code run as another project.

I am using Eclipse and Tomcat server.

My code is as follows: Servlet Code: (This is saved in Java Resources > src > DefaultPackage)

import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import org.json.JSONException;
import org.json.JSONObject;

@WebServlet("/HelloWorld")
public class HelloWorld extends HttpServlet {  
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        StringBuilder sb = new StringBuilder();

        BufferedReader reader = request.getReader();
        try {
            String line;

            while ((line = reader.readLine()) != null) {

                    sb.append(line).append('\n');
            }
        } finally {
            reader.close();
        }
        System.out.println(sb.toString());

        String api_key = null; 
        try {
            //JSONObject jsonObj = new JSONObject(sb.toString().substring(sb.toString().indexOf('{')));
            //JSONTokener t = new JSONTokener(sb.toString());
                JSONObject obj = new JSONObject(sb.toString().replace("\uFEFF", ""));
                System.out.println(obj.toString());
                api_key= (String) obj.get("api_key");
                //String node_number = (String) obj.get("node_number");
                //String tag_statuses = (String) obj.get("tag_statuses");
                //String voltage = (String) obj.get("voltage");

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        System.out.println("api_key:"+ api_key+"\n");
        response.setStatus(response.SC_OK);

        //response.setContentType("text/html");  
        //PrintWriter out = response.getWriter();  
        //out.println("<h1>"+out +"</h1>");

        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/NewFile.jsp");
        request.setAttribute("api_key", api_key); // set your String value in the attribute
        dispatcher.forward( request, response );
    }
    public void doGet(HttpServletRequest req, HttpServletResponse res) throws  ServletException, IOException {
        doPost(req, res);
    }
}

JSP Code: (saved in WebContent)

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<table>
    <tr>
        <td><%=request.getAttribute("api_key")%></td>
    </tr>
</table>
</body>
</html>

Java Application Code:

    import java.io.*;
import java.net.*;
import org.json.JSONObject;
public class Client {
    public static void main( String [] args ) {

        try
        {
          JSONObject jsonObj = new JSONObject("{\"api_key\" : \"rien\", \"node_number\" : \"40\", \"tag_statuses\" : [[100,\"MISSING\"]], \"voltage\": \"345\", \"location\": [42.3432,23.0098]}"); 
          URL url = new URL("http://localhost:95/sample/HelloWorld");
          URLConnection uc = url.openConnection();
          HttpURLConnection conn = (HttpURLConnection) uc;
          conn.setDoInput(true);
          conn.setDoOutput(true);
          conn.setRequestMethod("POST");
          conn.setRequestProperty("Content-type", "application/json");        
          PrintWriter pw = new PrintWriter(conn.getOutputStream());
          //pw.write(jsonObj.toString());
          pw.write(jsonObj.toString());
          pw.close();
          BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
          bis.close();

          int responseCode = conn.getResponseCode();
          System.out.println("Response Code recieved is: " + responseCode);

        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
    }
}

Here, I would like to see the content received by the servlet to be updated on the JSP, whenever some new content appears on the servlet, maybe by refreshing the webpage.

Now, When I try to run the code, without a jsp page I am receiving the content from the application and the java application is getting a 200 status update.

But when I try to include the JSP code, the JSP will run and I get a 'null' printed on JSP, but I get the data on console of servlet and I get the following exception on Java application code (instead of a 200 status message),

java.io.FileNotFoundException: http://localhost:95/sample/HelloWorld
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at Client.main(Client.java:21)

Could someone please help me in getting the content printed on the JSP real time and to avoid the error on the Java application? What am I doing wrong here?

Thanks.

Mi_Onim
  • 412
  • 2
  • 12
Qkxx
  • 29
  • 1
  • 4
  • Are you sure about your URL "http://localhost:95/sample/HelloWorld"? (the port is usually 8080 not 95) –  Aug 10 '15 at 16:34
  • Port numbers can be anything you want (there is an upper limit). Limitations depend on OS (for *unix, bellow 1024 if you are not superuser) and whether there are other processes with the same port bound to the same IP. – Akira Aug 10 '15 at 16:38
  • @RC. for accessing the Servlet, Yes. The data is being sent from the client to Servlet, but I am not able to get it displayed on a webpage using JSP. – Qkxx Aug 10 '15 at 16:48

2 Answers2

0

First thing I recommend you to do is to debug things not with your own client but using curl, which is stable and already tested ad nauseam.

See the following: How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?

It looks like that your response is either 500 or 404 error code. I bet 500 since your server-side does not seem to be producing a 404.

Also, consider migrating both client and server to Jersey, which already solves all your problems.

https://jersey.java.net/

But if you want to stick to your implementation, it looks like the problem is on the way you are writing your client. The client thinks that you are trying to read a file (URL may also point to files, not only network URLs). Here again Jersey is your friend since, as I said before, it also has an HTTP client library.

Community
  • 1
  • 1
Akira
  • 4,001
  • 1
  • 16
  • 24
  • Hi Akira, Thanks for the reply. Is there any other way without using additional platforms. I have seen similar questions to this on stack overflow, and I followed the solutions, but it seems to be not working in my case. – Qkxx Aug 10 '15 at 16:52
  • Your code looks fine. But I suspect that you are getting an HTTP 400 error as I said. It seems that you are getting an exception generated by this line: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/net/www/protocol/http/HttpURLConnection.java#1259 That is why I suggested first checking if the URL is reachable and which HTTP code you are getting by accessing it using CURL. This way you first check the server and only after making sure that the server is working you can start trying to fix the client. – Akira Aug 10 '15 at 17:13
  • But the client and server works fine without the JSP page, when I try to include the JSP, I get an error on the client side. Also, do you suggest some other method to display the content received from the client on webpage . – Qkxx Aug 10 '15 at 17:50
  • It seems that what you see on the browser is different from what your Java client sees. In your browser you see the result of a GET request if you type the URL directly. I see that you shortcircuited POST and GET but still, the request might not be exactly the same. Im sorry you did not like my previous suggestions of ways to see what your client is receiving. Another option would be to use JMeter to record the request and replay it. It really seems that you are getting a 404. – Akira Aug 10 '15 at 18:12
  • Hi Akira, your suggestions are really great. I tried running the servlet with the JSP code, then I get 404 error, on servlet. But the JSP runs fine and displays 'null'. But when there is no JSP page, the servlet does not show any 404 error. Sorry, I did not mention it earlier and sorry for all the confusion. Is this what you are expecting. – Qkxx Aug 10 '15 at 18:21
0

From my personal experience with Java Servlets and JSPs the functionality of real time updating is not achievable through the method you are implementing. This is because when the request for the JSP is rendered, it will be rendered with whatever information your app contains when the request is received, then is sent to the browser. Once in the browser is all html/css, no java scriptlets, so it won't update automatically.

You can use web sockets to achieve this live-content feature or simply run a javascript function that calls the some servlet (ajax calls), retrieve the information, and change the html content.

Example of Ajax Call for email verification, used in the old days.

  $.ajax(
            {
                url: "/validation",     //URL of request
                data:
                {
                    param1:  form.email.value   //Parameter that will be sent.
                },
                async: false,                   // You can make it Async.
                type: "POST",                   // Type of request.
                dataType: "text",               // Expected data type, might be json.
                success: function(data)         // If Ajax is success it will execute this function
                {
                    if(data=="true")
                    {
                        missingStuff =" This email is already registered \n";
                        correoDiv.attr("class", "form-inline has-error");

                    }
                    else
                    {
                        correoDiv.attr("class", "form-inline has-success");
                    }
                }

            }
        );

Another think you might want to check out it is : Socket.io, they offer many features for realtime content.

  • Hi Danny, could you direct me to some example or sample code which does what you suggested. – Qkxx Aug 10 '15 at 17:52