My original motivation for this series of posts was the “new” 1.10 release of jQuery DataTables. This release added client-side processing with data delivery as json objects via ajax – a great match for a jersey back end. The Ajax data source (objects) requires that the data be provided with a key of “data” and a value of an array of objects. I’ll update our project to provide the UserMap in that format.
Here’s the UserMapMarshall class implementing JsonSerializer1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32package com.ideoplex.tutorial;
import java.lang.reflect.Type;
import java.util.Collection;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonElement;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonSerializationContext;
public class UserMapMarshall implements JsonSerializer<UserMap> {
private static Gson gson = new Gson();
@Override
public JsonElement serialize(UserMap map , Type typeOfSrc, JsonSerializationContext context) {
JsonArray array = new JsonArray();
for ( User user : map.values() ) {
array.add( gson.toJsonTree(user) );
}
JsonObject object = new JsonObject();
object.add("data",array);
return object;
}
}
The GsonWriter class was also updated to save the Gson object as a static member. In this case, the Gson object was generated from a GsonBuilder object and an UserMapMarshall object explicitly registered as the Type Adapter for the UserMap class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33$ git diff --staged GsonWriter.java Amber 6:15
diff --git a/src/main/java/com/ideoplex/tutorial/GsonWriter.java b/src/main/java/com/ideoplex/tutorial/GsonWriter.java
index 990b5dd..9ef181d 100644
--- a/src/main/java/com/ideoplex/tutorial/GsonWriter.java
+++ b/src/main/java/com/ideoplex/tutorial/GsonWriter.java
@@ -25,12 +25,16 @@ import javax.ws.rs.ext.MessageBodyWriter;
import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
@Provider
@Produces(MediaType.APPLICATION_JSON)
@Singleton
public class GsonWriter<T> implements MessageBodyWriter<T> {
+ protected static Gson gson = new GsonBuilder()
+ .registerTypeAdapter(UserMap.class,new UserMapMarshall())
+ .create();
@Override
public void writeTo(T t, Class<?> type, Type genericType,
@@ -38,9 +42,8 @@ public class GsonWriter<T> implements MessageBodyWriter<T> {
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream)
throws IOException, WebApplicationException {
- Gson g = new Gson();
httpHeaders.get("Content-Type").add("charset=UTF-8");
- entityStream.write(g.toJson(t).getBytes("UTF-8"));
+ entityStream.write(gson.toJson(t).getBytes("UTF-8"));
}
@Override
After deploying the new webapp, the first request returns “data” as the key and an empty array as the value.
1
2$ curl http://xxxxxx-nnnnnn.use1-2.nitrousbox.com:8080/jersey-gson/webapi/myresource/user/map
{"data":[]}
I insert two new User objects.
1
2
3
4
5
6
7
8$ curl http://xxxxxx-nnnnnn.use1-2.nitrousbox.com:8080/jersey-gson/webapi/myresource/user/post \
--header 'Content-type: application/json' \
--data '{"email":"noone@example.com","surName":"Doe","givenName":"John"}'
{"email":"noone@example.com","surName":"Doe","givenName":"John"}
$ curl http://xxxxxx-nnnnnn.use1-2.nitrousbox.com:8080/jersey-gson/webapi/myresource/user/post \
--header 'Content-type: application/json' \
--data '{"email":"john@example.com","surName":"Public","givenName":"John"}'
{"email":"john@example.com","surName":"Public","givenName":"John"}
And now the response object with “data” as the key and an array of User objects as the value – formatted for clarity.
1
2
3
4$ curl http://xxxxxx-nnnnnn.use1-2.nitrousbox.com:8080/jersey-gson/webapi/myresource/user/map
{"data":[{"email":"john@example.com","surName":"Public","givenName":"John"},
{"email":"noone@example.com","surName":"Doe","givenName":"John"}
]}
Next, I’ll connect this to an html page with a DataTable. You can browse the source for jersey-gson on GitHub.
29 Sep: Custom Marshalling with Gson - part 1
04 Oct: Jersey, Gson and DataTables