Reputation: 678
I in my controller class a have the following method:
import javax.json.Json;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
@POST
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.TEXT_PLAIN})
@Path("/message")
public String postMessage(Json json,
@Context HttpServletRequest request) {
System.out.println("message");
return "ok";
}
The problem is when I send POST
by executing curl
by:
curl -H "Content-Type: application/json" -X
POST -d '{"key":"value"}' http://localhost:8080/message
I get HTTP Status 415 - Unsupported Media Type
as if I didn't send JSON. When I change Json json,
to String body
the controller works fine.
In web.xml
I have:
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
EDIT
I had wrong JSON as suggested in the comments. However, even with a correct one like {"key":"value"}
the code won't work.
Upvotes: 4
Views: 670
Reputation: 678
I solved the problem. In a class that extends ResourceConfig
there has to be register(JacksonFeature.class)
instruction, e.g.:
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
super(MyController.class);
property(CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true);
register(JacksonFeature.class);
}
}
Upvotes: 1
Reputation: 887
As far as I know jersey uses jackson's ObjectMapper to deserialize stuff. I think the problem may be that object mapper dont know how to map your request to javax.json.Json
object, a simple test:
import javax.json.Json;
import com.fasterxml.jackson.databind.ObjectMapper;
// (...)
ObjectMapper mapper = new ObjectMapper();
Json json = mapper.readValue("{\"key\": \"value\"}", Json.class);
This produces an exception:
UnrecognizedPropertyException: Unrecognized field "key" (class javax.json.Json)
I think you should create a POJO instead of raw json objects, for example:
class MyMessage {
public String key; //for simplicity, you probably will use accessor methods
}
And the same test works fine:
MyMessage msg = mapper.readValue("{\"key\": \"value\"}", MyMessage.class);
and then your controller method should look like this:
@POST
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.TEXT_PLAIN})
@Path("/message")
public String postMessage(MyMessage msg) {
System.out.println(msg.key);
return "ok";
}
Upvotes: 1
Reputation: 7521
Make sure that you have an implementation of MessageBodyReader in your classpath, that could consume JSON
Upvotes: 0