Jersey client Post Request with x-www-form-urlencoded Fails

VelNaga picture VelNaga · Jul 18, 2016 · Viewed 13.3k times · Source

Hi I am using Glassfish jersey-client to get oauth-Token from REST URL. I am able to get the token via postman client & CURL,please find the below image for reference,

$ curl 'https://sample.com/oauth2/token' -X POST -d'g
rant_type=samples&id=2ZwqWBdksfjkads6Q8yNW3s58LNeOMucJeb&s                                                                                                                
ecret=dkfflJTZOqA1GCEH&scope=GROUP'

But unable to achieve it via code,

<dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>2.22.2</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.22.2</version>
    </dependency>

I am using following code to get the token

Form form = new Form();
        form.param("grant_type", "samples");
        form.param("id", "2ZwqWBdksfjkads6Q8yNW3s58LNeOMucJeb");
        form.param("secret", "HGoslJTZOqA1GCEH");
        form.param("scope", "dkfflJTZOqA1GCEH");
JerseyClientBuilder jerseyClientBuilder = new JerseyClientBuilder()
            .register(new LoggingFilter());
    JerseyWebTarget jerseyWebTarget =      jerseyClientBuilder.build().target(hostname);
        response = jerseyWebTarget.request().accept(MediaType.APPLICATION_FORM_URLENCODED).post(Entity.form(form));

Keep on getting StatusCode=406(Not acceptable) as a response. Shall i passing the URL parameters properly?

I would highly appreciate if someone give me a hint to resolve this issue.

Answer

Paul Samsotha picture Paul Samsotha · Jul 18, 2016

Get rid of this .accept(MediaType.APPLICATION_FORM_URLENCODED). This sets the Accept header. You are saying here that you want a response with data type application/x-www-form-urlencoded. The server doesn't know how to response with that type so it's telling you that that response type is not acceptable.

What you want is to send the Content-Type header, not the Accept header. Using Entity.form(Form) automatically sets the Content-Type to application/x-www-form-urlencoded so you really don't need to do anything else. Just remove the accept method call.


UPDATE

Seems the client is setting an Accept header the server doesn't like, so you can explicitly set the Accept header to application/json since that is the content-type sent back by the server for the token response.

If you want to get the token as a Java object, you can just create a Token class with all the JSON properties in the token

public class Token {
    @JsonProperty("access_token")
    private String accessToken;

    // other properties

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public String getAccessToken() {
        return this.accessToken;
    }

    // other getters and setters
}

Then just do

Token token = response.readEntity(Token.class);

If you don't know all the other properties in the token response, just look at the contents of the logging filter. You should see the response. But you need to configure the logging filter to show the body

.register(new LoggingFilter(Logger.getAnonymousLogger(), true));