Search code examples
jsonhttpservletsurl-encoding

Sending JSON message from Android device to Server


I have an Android device that creates a JSON formatted message and sends it to a Tomcat server. The server is running a Java Web Application that receives this JSON formatted message and will then process it.

My issue is that when the message is received by the server, the server replaces certain characters ( '{', '[', '"', ']' and '}' ) with what looks like their Hex representation, which causes a JSON error where the server doesn't recognize the message.

My question is whether anyone knows what is causing this issue and how I would go about fixing this (I'm certain it's not the JSON code, but rather way the message is handled in terms of being sent/received).

Here is my server-side code:

@Override
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // Setup response
    PrintWriter out = response.getWriter();

    // Store input message as String
    StringBuilder sb = new StringBuilder();
    String message;

    // Build String
    while ((message = request.getReader().readLine()) != null) {
        sb.append(message);
    }

    // Full message as String
    message = sb.toString();

    // Convert message to JSON format
    Gson gson = new Gson();
    ImageFeatures features = gson.fromJson(message, ImageFeatures.class);

    out.println("Normal data: " + features);
    out.println();
}

Here is the error I am receiving:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 12
com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
com.google.gson.Gson.fromJson(Gson.java:795)
com.google.gson.Gson.fromJson(Gson.java:761)
com.google.gson.Gson.fromJson(Gson.java:710)
com.google.gson.Gson.fromJson(Gson.java:682)

This is the JSON formatted message that is produced before the Android device sends the message to the server:

{
"image_x_size":800,
"image_y_size":1600,
"features":
    [
        {"cart_x":5.0,"cart_y":124.0,"polar_angle":0.0,"polar_dist":0.0,"size":15.0},
        {"cart_x":5.0,"cart_y":124.0,"polar_angle":0.0,"polar_dist":0.0,"size":15.0}
    ]
}

This is how the message is seen by the server (i.e. the contents of the message String):

%7B+%09%22image_x_size%22%3A800%2C+%09%22image_y_size%22%3A1600%2C+%09%22features%22%3A+%09%09%5B+%09%09%09%7B%22cart_x%22%3A5.0%2C%22cart_y%22%3A124.0%2C%22polar_angle%22%3A0.0%2C%22polar_dist%22%3A0.0%2C%22size%22%3A15.0%7D%2C+%09%09%09%7B%22cart_x%22%3A5.0%2C%22cart_y%22%3A124.0%2C%22polar_angle%22%3A0.0%2C%22polar_dist%22%3A0.0%2C%22size%22%3A15.0%7D+%09%09%5D+%7D+

As you can see, the message String has various hex values replacing certain characters.

Many Thanks in Advance!

EDIT: I thought I should include my Android code for further clarity

HttpClient http_client = new DefaultHttpClient();

// Set long timeout limit
HttpConnectionParams.setConnectionTimeout(http_client.getParams(), 10000);
HttpConnectionParams.setSoTimeout(http_client.getParams(), 10000);
HttpResponse response;

// Setup json_object
JSONObject json_object = convertImageFeaturesToJSON(data, x, y);

try {
HttpPost http_post = new HttpPost(URL_BASE + "/featureuploader");

Log.i(TAG, json_object.toString());

StringEntity se = new StringEntity(json_object.toString());
se.setContentType("application/json; charset=UTF-8");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json; charset=UTF-8"));

http_post.setEntity(se);
http_post.setHeader("Accept", "application/json");
http_post.setHeader("Content-Type", "application/json");

response = http_client.execute(http_post);

if (response != null) {
    String response_string = httpResponseToString(response.getEntity().getContent());
    if (! response_string.startsWith("Received: <html>")) {
        Log.i(TAG, "Received: ERROR! - " + response_string.substring(0, 20));
    } else {
        Log.i(TAG, "Received: " + response_string);
    }
} else {
    Log.e(TAG, "Did not receive from server");
}               
} catch (Exception e) {
    Log.e(TAG, "Error: " + e.getMessage());
}

Solution

  • This is how the message is seen by the server...

    That's a URL encoded version of the JSON that you're seeing on the server. You need to either decode it first (using something like URLDecoder), or retrieve it from the request in a way that it comes to you decoded.