1

I'm trying to send JSON formatted string from Android device to Flask server. I'm using Apache MultiPartEntityBuilder for sending because I also want to send image file in same http post message. I have no problem with sending and receiving the file, but for some reason JSON data is not handled as I expected on Flask side. I'm expecting that the JSON data can be accessed in Flask using request.get_json() but for some reason this gives nothing. Instead the JSON data seems to be accessible with request.form. So maybe Flask server doesn't recognize the JSON data for some reason. Or does the request.get_json() even work with multipart data?

Sending JSON in Android:

public void postJson() {

        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("message", "Hello World!");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        try{
            HttpClient httpclient = createHttpClient();
            HttpPost httpPost = new HttpPost("http://server/jsontest/");

            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

            builder.addTextBody("json", jsonObject.toString(), ContentType.APPLICATION_JSON);

            httpPost.setEntity(builder.build());
            HttpResponse response = httpclient.execute(httpPost);

            int code = response.getStatusLine().getStatusCode();
            Toast.makeText(getBaseContext(), "Status code = " + code, Toast.LENGTH_LONG).show();

        } catch(Exception e){
            Log.e(LOG_TAG, "Error in http connection" + e.toString());
        }

    }

Receiving JSON in FLASK:

from flask import Flask
from flask import jsonify
from flask import request

app = Flask(__name__)

if not app.debug:
    import logging
    from logging.handlers import RotatingFileHandler
    file_handler = RotatingFileHandler('app.log', 'a', 1 * 1024 * 1024, 10)
    file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(filename)s:%(lineno)d]'))
    app.logger.setLevel(logging.DEBUG)
    file_handler.setLevel(logging.DEBUG)
    app.logger.addHandler(file_handler)
    app.logger.info('App startup')

@app.route('/', methods=['GET', 'POST'])
def get_json():
    app.logger.info('Start of get_json')

    app.logger.info('Form data')
    app.logger.info(request.form)

    app.logger.info('Json data')
    app.logger.info(request.get_json())

    return 'OK'

Log file content:

2013-12-31 11:57:10,600 INFO: App startup [in app.py:15]
2013-12-31 11:57:10,622 INFO: Start of get_json [in app.py:19]
2013-12-31 11:57:10,624 INFO: Form data [in app.py:21]
2013-12-31 11:57:10,629 INFO: ImmutableMultiDict([('json', u'{"message":"Hello World!"}')]) [in app.py:22]
2013-12-31 11:57:10,632 INFO: Json data [in app.py:24]
2013-12-31 11:57:10,635 INFO: None [in app.py:25]

1 Answer 1

3

You are creating a multipart-encoded POST body with a json parameter, which is great when you are posting form data.

To POST just JSON (for request.json and request.get_json() to work), you must post just the data without encoding it to a multi-part body:

HttpClient httpclient = createHttpClient();
HttpPost httpPost = new HttpPost("http://server/jsontest/");

httpPost.setHeader(ContentType.APPLICATION_JSON);
httpPost.setEntity(jsonObject.toString());
HttpResponse response = httpclient.execute(httpPost);

Note that you need to set the application/json content type header. Not being too familiar with Android Java classes, I guessed that ContentType.APPLICATION_JSON is a Header object you can set directly on the httpPost object.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.