Home Up Back Forward Leave Message


Overview

The code is available for download from:

This code is also making use of the following:

JSON handling in Java

For JSON handling I'm using gson by Google (see link above). Although there are other libraries to do this (see the JSON website gson does what I want for this purposes. To encode a class for example to JSON one would do the following:
    public class LogonStr {
        public String username;
        public String password;

        public LogonStr(String username, String password) {
            this.username = username;
            this.password = password;
        }
    }

    ............

    GsonBuilder builder = new GsonBuilder();
    Gson gson = builder.create();
    String body = gson.toJson(new LogonStr("daffy","duck"));    
This is really straight forward, you just create a builder then you tell it to convert the object (instantiated class) to a JSON representation.

To do the inverse is just as easy:
    GsonBuilder builder = new GsonBuilder();
    Gson gson = builder.create();
    LogonStr logon = gson.fromJson("{\"username\": \"daffy\", \"password\": \"duck\" }", LogonStr.class);
Once the builder has been created tell it to take the JSON input (String in this case) and convert it based on the LogonStr class definition.

The only fun is because our return JSON in the client can have either a string (for errors) or some other value depending on the call for the data field we need to sort of not parse all of it. First we parse at the top level to get the status, if it is true then we parse according to what is expected else if it is false we parse it to a string.
    public static  T parseBody(String body, Class cls) throws MsgError {
        JsonParser parser = new JsonParser();
        JsonElement tmp = parser.parse(body);
        JsonObject tmp2 = tmp.getAsJsonObject();
        if (tmp2.get("status").getAsBoolean()) {
            GsonBuilder builder2 = new GsonBuilder();
            Gson gson2 = builder2.create();
            return (T) gson2.fromJson(tmp2.get("data").toString(), cls);
        } else {
            throw new MsgError(tmp2.get("data").getAsString());
        }    
    }
    
    ..................

    try {
        long sesskey = parseBody("{\"status\": true, \"data\": 1093098234},Long.class);
    } catch (MsgError ex) {
        System.err.println(ex.getMessage());
    }

    try {
        long sesskey = parseBody("{\"status\": false, \"data\": \"Invalid credentials\"},Long.class);
    } catch (MsgError ex) {
        System.err.println(ex.getMessage());
    }
For the purposes of explanation I've shown a function parseBody that will parse whatever was returned from a call to a service. It expects the body (as JSON in a String) and the class of what is expected in the data part of the JSON object. It either returns the decoded JSON for the data part or it throws an error with the message if status is false.

A parser is created and then our JSON body is parsed (to an internal form), we know this is a JSON object so we retrieve it as such and place it in tmp2. Now we can query the value of status by telling tmp2 to return the "status" field as a boolean. If it is true then the data part is decoded to the definition of cls else if status is false data is decoded to a string and thrown as an error.

HTTP handling of requests

For the handling of HTTP requests on the server side I'm using the build in HTTP server of Java. For what we want to do the full J2EE approach is a total overkill. A basic use of the server is as follows:
    static class LogonHandler implements HttpHandler {

        @Override
        public void handle(HttpExchange he) throws IOException {
            // Handling the input
            String tmpcl = he.getRequestHeaders().getFirst("Content-Length");
            int cl = -1;
            String response;
            if (tmpcl != null && tmpcl.length() > 0) { // Check if Content-Length is present in header
                try {
                    cl = Integer.parseInt(tmpcl);  // Convert Content-Length to an integer
                    byte[] buf = new byte[cl];     // Create a buffer where we can put the body
                    he.getRequestBody().read(buf); // Read the body into the buffer, now we can use it
                    ....
                    //process body
                    ...                    

                    response = "{\"status\": true, \"data\": 1092348}";
                } catch (IOException ex) {
                    response = "{\"status\": false, \"data\": \"Error retrieving body\"}";
                }
            } else {
                response = "{\"status\": false, \"data\": \"No body\"}";                
            }

            // Handling output

            // Set headers
            he.getResponseHeaders().add("Access-Control-Allow-Origin", "*");
            he.getResponseHeaders().add("Content-Type", "text/json;charset=UTF-8");

            // Set the response status and Content-Length of the returned response
            he.sendResponseHeaders(200, response.length());
            // Convert the response to bytes and send it
            he.getResponseBody().write(response.getBytes());
            // We must close the stream else the data is not send
            he.getResponseBody().close();            
        }
    }    

    ............................

    HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
    server.createContext("/logon", new LogonHandler());
    .....
    server.start();
As a real basic implementeation one creates a HttpServer for the specific port you want to listen on, then you add contexts (also called routes is other implementations) with the path that will trigger it and the handler that will handle it. And then you start the server.

The handler is a class which implements HttpHandler which only have one function it requires public void handle(HttpExchange he) throws IOException. The HttpExchange have the request and response information all in one. See the body of the example above how the various member functions are called.

HTTP handling of calls

To handle calls to a service one uses URL and HttpURLConnection which is standard to Java to do the request, post the body and then read the response body:
    URL url = new URL("http://localhost:8080/logon");
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setRequestMethod("POST");
    con.setRequestProperty("Content-Type", "text/json;charset=UTF-8");
    con.setDoOutput(true);
    String body = "{\"username\": \"daffy\", \"password\": \"duck\" }";
    DataOutputStream wr = new DataOutputStream(con.getOutputStream());
    wr.writeBytes(body);
    wr.flush();
    wr.close();

    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuilder response = new StringBuilder();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
Once sets up the url and open a connection to the server, then the request method is set to POST the body is then written to the output stream of the connection. Once it is written you open the input stream and read the response body.