This tutorial explains how to use google Gson with Jersey 2.x. There are some other java libraries also capable of doing this conversion e.g. MOXy, Jackson or JSONP; but Gson stands among very few which do not require any pre-annotated java classes OR sourcecode of java classes in any way.
Table of Contents Maven dependencies/changes Create Gson Provider Register Gson Provider Extending Gson Functionality Demo
Jersey does not provide any inbuilt support for Gson, as it provide for MOXy and JSONP etc. But Jersey provides discovery mechanism to scan various configurable components of application, via implementing some interfaces and registering implementations to application configuration.
Gson can be used with Jersey as JSON serializer/deserializer by implementing interfaces javax.ws.rs.ext.MessageBodyWriter
and javax.ws.rs.ext.MessageBodyReader
, and register to configuration either using @Provider
annotation OR using ResourceConfig.register()
method.
Let’s see all steps one by one.
Maven dependencies
First include Gson dependencies.
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.2.4</version> </dependency>
Create Gson Provider
Now create a class implementing interfaces javax.ws.rs.ext.MessageBodyWriter
and javax.ws.rs.ext.MessageBodyReader
, and override it’s methods.
package com.howtodoinjava.jersey.provider; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; 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 com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class GsonMessageBodyHandler implements MessageBodyWriter<Object>, MessageBodyReader<Object> { private static final String UTF_8 = "UTF-8"; private Gson gson; //Customize the gson behavior here private Gson getGson() { if (gson == null) { final GsonBuilder gsonBuilder = new GsonBuilder(); gson = gsonBuilder.disableHtmlEscaping() .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) .setPrettyPrinting() .serializeNulls() .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) { InputStreamReader streamReader = null; try { streamReader = new InputStreamReader(entityStream, UTF_8); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } try { Type jsonType; if (type.equals(genericType)) { jsonType = type; } else { jsonType = genericType; } return getGson().fromJson(streamReader, jsonType); } finally { try { streamReader.close(); } catch (IOException e) { e.printStackTrace(); } } } @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(); } } }
Register Gson Provider
Now register above class with application resource config.
package com.howtodoinjava.jersey; import org.glassfish.jersey.filter.LoggingFilter; import org.glassfish.jersey.server.ResourceConfig; import com.howtodoinjava.jersey.provider.GsonMessageBodyHandler; public class CustomApplication extends ResourceConfig { public CustomApplication() { packages("com.howtodoinjava.jersey"); register(LoggingFilter.class); register(GsonMessageBodyHandler.class); } }
Extending Gson Functionality
You can extend/customize Gson behavior anytime inside GsonMessageBodyHandler.getGson()
method.
private Gson getGson() { if (gson == null) { final GsonBuilder gsonBuilder = new GsonBuilder(); gson = gsonBuilder.disableHtmlEscaping() .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) .setPrettyPrinting() .serializeNulls() .create(); } return gson; }
Demo
Now if you access any REST resource through any REST client, you will get desired JSON output.
Hit the URL : http://localhost:8080/JerseyDemos/rest/employees
Now the output will be:
{ "EmployeeList": [ { "Id": 1, "Name": "Lokesh Gupta" }, { "Id": 2, "Name": "Alex Kolenchiskey" }, { "Id": 3, "Name": "David Kameron" } ] }
Happy Learning !!