JAVA OkHTTP3 Library gives me a 415 HTTP Error

395 Views Asked by At

I have found a solution to solve this issue.

Check the first answer to this topic


I've a problem with the library OkHTTP3. I want to join an API endpoint with the library.


Firstly, I've created my request with Postman to test the API endpoint. After configuring the URL, the access token and the JSON Body, I've launched my request. Postman gived me a positive response (JSON response + HTTP Code 200). All works fine.

After that, I've coded my Java method. The first request to get the access token works fine.
But the second request return me a 415 HTTP Code. When I dump the JSON body given to the JAVA request and I paste it into Postman, I don't have any problem.

Also, the headers between my JAVA method with OkHTTP3 and my Postman configuration are litterally the same... I don't know why it doesn't work !

Below, my JAVA code and a screen capture of my Postman configuration.
If anyone has an idea... thanks in advance !


public static void getAlertModels(OAuthToken oAuthToken, int customerId) throws IOException {

    ApiRequest apiRequest = new ApiRequest(
        new ApiRequestSearch(
            Arrays.asList("triggers", "customers"),
            Arrays.asList(
                Arrays.asList("product"),
                Arrays.asList(9)
            )
        )
    );
    
    ObjectMapper objectMapper = new ObjectMapper();

    String jsonBody = objectMapper.writeValueAsString(apiRequest);

    OkHttpClient client = new OkHttpClient().newBuilder().build();

    MediaType mediaType = MediaType.parse("application/json");

    RequestBody body = RequestBody.create(jsonBody, mediaType);

    Request request = new Request.Builder()
        .url("https://api.anonymous.tld/alertModels")
        .method("POST", body)
        .addHeader("Authorization", "Bearer " + oAuthToken.getAccessToken())
        .addHeader("Content-Type", "application/json")
        .addHeader("Accept", "application/json")
        .build()
    ;

    Response response = client.newCall(request).execute();

    System.out.println(jsonBody);
    System.out.println(response.code());
    System.out.println(response.body().string());
}

Postman Body Configuration : https://i.stack.imgur.com/YFOXV.png
Postman Headers Configuration : https://i.stack.imgur.com/7cBI7.png

1

There are 1 best solutions below

0
Alexandre On

So, I have finally found a solution to solve this problem.

For all people who use the OkHttp3 library, when you build the RequestBody object, you specify the RequestBody and the MediaType like that :

MediaType mediaType = MediaType.parse("application/json");

RequestBody body = RequestBody.Companion.create(jsonBody, mediaType);

Request request = new Request.Builder()
    .url("https://api.anonymous.tld/alertModels")
    .post(body)
    .addHeader("Authorization", oAuthToken.getAccessToken())
    .build()
;

The MediaType.parse(...) method concat charset=utf-8 to the Content-Type.
Some API doesn't accept header like that : Content-Type: application/json; charset=utf-8 but accept that : Content-Type: application/json

So, remove the MediaType object, create the RequestBody without the MediaType and specify the Content-Type into the Request.Builder() method. The final code looks like that :

// Remove the below line
// MediaType mediaType = MediaType.parse("application/json");

// Set the second parameter to "null"
RequestBody body = RequestBody.Companion.create(jsonBody, null);

// Add a new header with the desired Content-Type
Request request = new Request.Builder()
    .url("https://api.anonymous.tld/alertModels")
    .post(body)
    .addHeader("Authorization", oAuthToken.getAccessToken())
    .addHeader("Content-Type", "application/json")
    .build()
;

For more informations, you can referer to the discussion of the following GitHub issue : https://github.com/square/okhttp/issues/3081