1
votes

I have a RESTful Java web service that I built using Jersey. The client for it defines a resource with the following method:

@Override
public String saveWidget(Widget widget) {
    return webResource.path("user").type(MediaType.APPLICATION_JSON).entity(widget).post(String.class, Widget.class);
}

Then, a driver using this client:

public class Driver {
    public static void main(String[] args) {
        WidgetClient client;
        WidgetClientBuilder builder = new WidgetClientBuilder();
        client = builder.withUri("http://localhost:8080/myapi").build();

        Widget w = getSomehow();

        String widgetUri = client.getWidgetResource().saveWidget(w);
        System.out.println("Widget was saved URI was returned: " + widgetUri);
    }
}

When I run this I get:

Exception in thread "main" com.sun.jersey.api.client.UniformInterfaceException: POST http://localhost:8080/myapi/widget returned a response status of 400 Bad Request
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:688)
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
    at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:570)
    at com.my.myapi.WidgetResource.saveWidget(WidgetResource.java:27)
    at com.my.myapi.Driver.main(Driver.java:32)

I know the service endpoint is valid because I can hit it from another (non-Java) web client without issues. This means that either my Widget instance is malformed or that there is something with my Java client method (saveWidget). I ruled out my w Widget being bad by serializing it into JSON, and then copying it into my non-Java web client and POSTing to the same endpoint (no issues arose). So this tells me I have the client method configured wrong. Any ideas?

2
There's not enough information here, post or link the widget class, the non java request that succeeds and any message body readers you have registeredLev Kuznetsov

2 Answers

4
votes

This is regarding making a call POST call using Jersey client.

For jersey client, default client configuration uses ChunkedEncoding and gzip. This can be checked in request headers for POST call. Content length of payload (JSON String or any object mapper pojo) and request headers received by post call i.e. header name CONTENT-LENGTH, CONTENT-ENCODING. If there is difference, POST call might return 400 bad request. (Something like unable to process JSON). To solve this, you can disable ChunkedEncoding, gzip encoding. Code snippet for the same:

clientConfiguration.setChunkedEncodingEnabled(false);
clientConfiguration.setGzipEnabled(false);

Client client = (new JerseyClientBuilder(environment)).using(clientConfiguration).using(environment).build("HTTP_CLIENT");
WebTarget webTarget = client.target(endpoint);
Response response = webTarget.path(path).request(MediaType.APPLICATION_JSON).post(Entity.json(jsonString));
1
votes

.post(String.class, Widget.class);

You appear to be posting a Class object, not a Widget object.