Can't Deserialize JSON in Java Servlet
I don't know which JSON Serializer you are using but most probably this will be Jettison or Jackson. As far as I know they don't support converting an instance of org.json.JSONObject
directly. The more common way is to simply use custom Java Beans:
public class Foo implements Serializable {
private String platform;
// getters + setters
}
@POST
@Path("/{department}/{team}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response handleJson(Foo foo, @PathParam("department") String department, @PathParam("team") String team) {
...
myObj.setPlatform(foo.getPlatform());
...
}
Foo
should be annotated with @XmlRootElement if you are using Jettison.
If you don't want to create a custom Bean for every Entity you are expecting you can use Object
, Map
or String
as parameter and serialize on your own:
@POST
@Path("/{department}/{team}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response handleJson(String json, @PathParam("department") String department, @PathParam("team") String team) {
...
JSONObject jsonObject = new JSONObject(json);
myObj.setPlatform(json.optString("platform"));
...
}
Last solution is implementing a MessageBodyReader which handles JSONObject
. Simple example:
@Provider
public class JsonObjectReader implements MessageBodyReader<JSONObject> {
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return type == JSONObject.class && MediaType.APPLICATION_JSON_TYPE.equals(mediaType);
}
@Override
public JSONObject readFrom(Class<JSONObject> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
return new JSONObject(IOUtils.toString(entityStream));
}
}
This might not be an ideal solution, but i do think it could work.
Hopefully you have the Jackson JSON dependency already...
you can find it here: http://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
I would try the following code:
@POST
@Path("/{department}/{team}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response handleJSON(String json, @PathParam("department") String department, @PathParam("team") String team){
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readValue(json, JsonNode.class);
MyObj myObj = new MyObj();
myObj.setDepartment(department);
myObj.setTeam(team);
if (node.get("platform") != null) {
myObj.setPlatform(node.get("platform").textValue());
}
saveObj(myObj);
return Response.ok(true).build();
}
Notice that I am asking your WS Framework to just pass me the JSON as a String and just handling it myself. Maybe its not ideal, but should work.
Cheers!