3

I am using loopj (1.4.7) and AsyncHttpClient to post Json to a Web API server. My (simplified) code is:

private void createCode() {
    // 1. Get the current data and time
    DateFormat df = DateFormat.getDateTimeInstance();
    df.setTimeZone(TimeZone.getTimeZone("UTC"));
    String gmtTime = df.format(new Date());

    // 2. Setup few things
    AsyncHttpClient client = new AsyncHttpClient();
    Context context = this.getApplicationContext();
    connCode = "1234";

    JSONObject jsonData = new JSONObject();
    try {
        jsonData.put("ClientCode", connCode);
        jsonData.put("CodeCreated", gmtTime);
    } catch (Exception ex) {
        // Should not really happen
    }

    // 3. Authorization/Authentication
    String userName = "TestUser";
    String userPassword = "TestPassword";
    String userNamePassword = userName + ":" + userPassword;
    byte[] loginString = userNamePassword.getBytes();
    String loginStringEncoded = Base64.encodeToString(loginString, Base64.DEFAULT);

    client.setAuthenticationPreemptive(true);

    // This is the line that cause the problem
    client.addHeader("Authorization", loginStringEncoded);

    // 4. Setup various options
    StringEntity entity = null;
    try {
        entity = new StringEntity(jsonData.toString());
    } catch (UnsupportedEncodingException e) {
        return;
    }
    entity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));

    // 5. Post the code to the database
    client.post(context, CODE_URL, entity, "application/json", new JsonHttpResponseHandler() {

        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
            // TODO - Process results...
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, java.lang.Throwable throwable, org.json.JSONArray errorResponse) {
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, java.lang.Throwable throwable, org.json.JSONObject errorResponse) {
        }
    });
}

The response is “400 - Bad Request” because not everything makes it to the server if I use the "Authorization" header. What shows up on the server is (verified using Fiddler):

{"ClientCode":"1234","CodeCreated":"Jul 17, 2015 1:03:00 AM

If I get rid of the "client.addHeader("Authorization", loginStringEncoded);" line, everything works fine and the server receives everything (but I need the Authorization header to limit access):

{"ClientCode":"1234","CodeCreated":"Jul 17, 2015 1:10:00 AM"}

I can tell that the server is processing the authorization properly but the response fails because of the missing "}". I have verified that the whole string is part of the “entity” variable before the “client.post” command gets executed.

If it makes a difference, I am running Android Studio on a Mac and I have verified using WireShark that the missing "}" is already not there when the Mac connects to the Web API server. What could be causing it? A similar setup works fine for GET but I cannot make it work for POST. Is there perhaps a better way to do this? Thanks.

Shivam Kumar
  • 1,892
  • 2
  • 21
  • 33
Colca
  • 41
  • 1
  • 5

1 Answers1

2

This works with me:

 AsyncHttpClient client2 = new SyncHttpClient();
//check if needs this header or I can take off this and leave just the url+token2
                client2.addHeader("x-auth-token", token2);

                client2.post(String.valueOf(url), params, new BaseJsonHttpResponseHandler(String.valueOf(Looper.getMainLooper())) {

                    /**
                     * Base abstract method, handling defined generic type
                     *
                     * @param statusCode      HTTP status line
                     * @param headers         response headers
                     * @param rawJsonResponse string of response, can be null
                     * @param response        response returned by {@link #parseResponse(String, boolean)}
                     */
                    @Override
                    public void onSuccess(int statusCode, cz.msebera.android.httpclient.Header[] headers, String rawJsonResponse, Object response) {

                        onPostExecute((JSONObject)response);

                    }

                    /**
                     * Base abstract method, handling defined generic type
                     *
                     * @param statusCode    HTTP status line
                     * @param headers       response headers
                     * @param throwable     error thrown while processing request
                     * @param rawJsonData   raw string data returned if any
                     * @param errorResponse response returned by {@link #parseResponse(String, boolean)}
                     */
                    @Override
                    public void onFailure(int statusCode, cz.msebera.android.httpclient.Header[] headers, Throwable throwable, String rawJsonData, Object errorResponse) {

                    }

                    /**
                     * Should return deserialized instance of generic type, may return object for more vague
                     * handling
                     *
                     * @param rawJsonData response string, may be null
                     * @param isFailure   indicating if this method is called from onFailure or not
                     * @return object of generic type or possibly null if you choose so
                     * @throws Throwable allows you to throw anything from within deserializing JSON response
                     */
                    @Override
                    protected Object parseResponse(String rawJsonData, boolean isFailure) throws Throwable {
                        return null;
                    }

I hope it will help you.

Alexiscanny
  • 581
  • 7
  • 15