If you must stick to Gson, you need to write a MessageBodyReader
/MessageBodyWriter
pair to handle deserialization/serialization. This is how the request stream is converted into our domain objects and domain objects serialized to the response stream.
You can find a good explanation about this subject here and you can find a simple implementation here at Integrating Gson into a JAX-RS based application. I will post the implementation at the bottom (in case the side ever goes down).
However you register all your other Jersey components, i.e. resource classes and providers, register this GsonMessageBodyHandler
the same way. If you have package scanning enabled, the class should be automatically picked up from the @Provider
annotation. In any case the @RequestBody
annotation shouldn't be needed (I don't work much with Spring, but I would guess it's ignored either way).
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@Provider
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public final class GsonMessageBodyHandler implements MessageBodyWriter<Object>,
MessageBodyReader<Object> {
private static final String UTF_8 = "UTF-8";
private Gson gson;
private Gson getGson() {
if (gson == null) {
final GsonBuilder gsonBuilder = new GsonBuilder();
gson = gsonBuilder.create();
}
return gson;
}
@Override
public boolean isReadable(Class<?> type, Type genericType,
java.lang.annotation.Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws Exception, ApplicationException {
InputStreamReader streamReader = new InputStreamReader(entityStream, UTF_8);
try {
Type jsonType;
if (type.equals(genericType)) {
jsonType = type;
} else {
jsonType = genericType;
}
return getGson().fromJson(streamReader, jsonType);
} finally {
streamReader.close();
}
}
@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public long getSize(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return -1;
}
@Override
public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8);
try {
Type jsonType;
if (type.equals(genericType)) {
jsonType = type;
} else {
jsonType = genericType;
}
getGson().toJson(object, jsonType, writer);
} finally {
writer.close();
}
}
}