Gson在Spring MVC中的使用

  1. 1. 基本
  2. 2. 进阶
    1. 2.1. 使用@Expose注解忽略不想序列化的(敏感)字段
    2. 2.2. 利用字段null来简化API的输出
    3. 2.3. 与Spring MVC整合
    4. 2.4. 更多Gson配置

最近在用Spring MVC搭建一套Restful API,整个过程的最后一步就是数据序列化。Spring MVC默认使用Jackson,但在使用过程中并不如想象中的顺手。因而尝试转向Gson

Gson是Google出品的用来进行Java Object和JSON转换的类库。有人曾对Gson和Jackson的性能做过比较,Gson在读取和写入方面的速度都要逊于Jackson。不过现前并不需要在性能上作过多要求,容易上手和提高开发效率才是这个项目的重中之重。

基本

使用Gson来反序列化JSON十分简单,如下:

User
1
2
3
4
5
6
7
public class User{
private String name;
private String password;

public User(String name, String password){...}
...
}
Gson反序列化User
1
2
3
4
5
Gson gson = new Gson();
gson.toJson(new User("hello", "world"), User.class);

// Result:
// {"name": "hello", "password": "world"}

但Gson的优点不仅仅在于这点,而是在自定义序列化方面。

进阶

使用@Expose注解忽略不想序列化的(敏感)字段

很明显,在返回给用户的时候是不应该包含password这种字段的,在反序列化的过程中应该把它忽略掉。这里就可以使用Gson自带的注解@Expose来指定哪些字段需要被反序列化。注意:字段加了@Expose表明该字段会被反序列化,而不是被忽略。

User带@Expose注解
1
2
3
4
5
6
7
8
public class User{
@Expose
private String name;
private String password;

public User(String name, String password){...}
...
}
Gson反序列化User
1
2
3
4
5
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
gson.toJson(new User("hello", "world"), User.class);

// Result:
// {"name": "hello"}

利用字段null来简化API的输出

CommonResponse
1
2
3
4
5
6
7
8
9
10
11
12
public class CommonResponse<T>{
@Expose
private Int status; //API状态码,与HttpStatus状态码类似,200为Success,10000以上则对应服务的各种错误
@Expose
private T response; // status == 200 时的具体返回值,status != 200 时不显示
@Expose
private String message; //status != 200 时的详细消息输出,status == 200 时不显示

public CommonResponse(T response){...}
public CommonResponse(T response, String message){...}
...
}

Json默认对于null的字段不输出,利用这种方式可以简化API的输出,压缩空间;同时利用上面CommonResponse的设计,
在输出正确时

CommonResponse.status = 200
1
2
3
4
5
6
{
"status": 200,
"response": {
"name": "hello"
}
}

输出错误时

CommonResponse.status = 10001
1
2
3
4
{
"status": 10001,
"message": "no use found"
}

与Spring MVC整合

web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<mvc:annotation-driven>
<mvc:message-converters>
<!--use utf-8-->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
<property name="writeAcceptCharset" value="false"/>
</bean>
<bean class="info.xudshen.basic.util.gson.GsonHttpMessageConverter">
<constructor-arg>
<!--ignore the class in this list->
<list>
<value>com.wordnik.swagger.model.ResourceListing</value>
<value>com.wordnik.swagger.model.ApiListing</value>
</list>
</constructor-arg>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

GsonHttpMessageConverter的代码在Gist

更多Gson配置

更多Gson配置
1
2
3
4
5
public Gson gson = new GsonBuilder().enableComplexMapKeySerialization()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.excludeFieldsWithoutExposeAnnotation()
.setDateFormat("yyyy-MM-dd HH:mm:ss.S Z")
.create();