Java HttpClient changing content-type?
Asked Answered
K

2

6

I am building a small app for my Android phone to forward text messages to a webserver using a very basic REST interface.

I am using the android 4.0.3 SDK. I developed the webservice in python using the Django and the Django restframework package. The setup is completely out of the box. There is basically one endpoint that receives a POST of a JSON object holding the message info (sender, body, date). I have tested the service using cURL with the following command:

curl -X POST -H 'Content-Type: application/json' --data '{"sender":"+xxxxxxxx", "body": "test", "send_date":"2011-03-20 16:32:02"}' http://[...]/messages.json

This all works fine and I get the expected response:

{"body": "test", "send_date": "2011-03-20T16:32:02", "id": 25, "sender": "+xxxxxxxxxx"}

Now I set up the android app. It is a simple BroadcastReceiver child class that includes a private AsyncTask class:

private class httpPost extends AsyncTask<String, Void, JSONObject> {
    protected JSONObject doInBackground(String... args) {
        // Create a new HttpClient and Post Header
        HttpClient httpclient = new DefaultHttpClient();
        HttpParams myParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(myParams, 10000);
        HttpConnectionParams.setSoTimeout(myParams, 10000);

        String url = args[0];
        String json=args[1];            
        JSONObject JSONResponse = null;
        InputStream contentStream = null;
        String resultString = "";

        try {
            HttpPost httppost = new HttpPost(url);
            httppost.setHeader("Content-Type", "application/json");
            httppost.setHeader("Accept", "application/json");

            StringEntity se = new StringEntity(json); 
            se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
            httppost.setEntity(se);

            for (int i=0;i<httppost.getAllHeaders().length;i++) {
                Log.v("set header", httppost.getAllHeaders()[i].getValue());
            }

            HttpResponse response = httpclient.execute(httppost);

            // Do some checks to make sure that the request was processed properly
            Header[] headers = response.getAllHeaders();
            HttpEntity entity = response.getEntity();
            contentStream = entity.getContent();

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //convert response to string
        try{
            BufferedReader reader = new BufferedReader(new InputStreamReader(contentStream,"iso-8859-1"),8);
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            contentStream.close();
            resultString = sb.toString();
        }catch(Exception e){
            e.printStackTrace();
        }

        Log.v("log", resultString);
        return new JSONObject();
    }


}

As you can see I am just starting to get familiar with Java and the android SDK so please bear with me. This setup actually worked fine in another app that I build to send JSON strings to a Neo4J webservice.

The problem is that when I post the message via Android to my webservice, at some point the content-type gets changed from 'application/json' to 'application/json, application/json'. The log entry in the headers loop still outputs the correct values for each header, however, the webservice returns this error message:

{"error": "Unsupported media type in request 'application/json, application/json'."}

I am puzzled, any help is welcome.

Khanna answered 21/4, 2012 at 23:8 Comment(4)
Why do you write two "Content-Type" headers? Once with http.setHeader and the other through entities. Maybe it is the cause of the error.Anglonorman
As far as I understood, the second one (at the StringEntity) is merely to set the decoding of the entity and does not affect the post headers. I have tested this by not adding the post header. In that case the header that ended up in the request was the standard text/plain header.Khanna
Not saying I am sure about that, but I would try without the entity. Apart from that, an HTTP sniffer (like wireshark) can help you diagnose if the failure is in the client or the server.Anglonorman
Downloading wireshark now, see what that brings us. Thanks a lot for the pointerKhanna
S
7

Change this:

StringEntity se = new StringEntity(json); 
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httppost.setEntity(se);

To this only:

httppost.setEntity(new StringEntity(json.toString(), HTTP.UTF_8));
Synergy answered 21/4, 2012 at 23:33 Comment(3)
Thanks mate!! That was all I needed. @Anglonorman you were right as well, cheers guys, very helpful!Khanna
Should be se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));Luby
Addition of HTTP.UTF_8 as charset fixed my issue ... thank you :)Aquilar
S
2

easy :

import org.apache.http.client.methods.HttpPost;

httppost.setEntity(new StringEntity(json.toString(), org.apache.http.entity.ContentType.APPLICATION_JSON));
Sacred answered 3/6, 2019 at 10:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.