fastjson 指南

简介

fastjson 是阿里巴巴出品的高性能json序列化框架。

在maven中引用:

1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency>

常用API

JSON API

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
// 将对象转换为 json 格式的字符串
JSON.toJSONString(person);
// 指定日期格式化方式
JSON.toJSONStringWithDateFormat(person, "yyyy-MM-dd");

String jsonStr = "{id:1}";

// 将字符串解析为 JSONObject 对象
JSONObject jsonObject = JSON.parseObject(jsonStr);

// JSONObject 使用
Person personFromJson1 = jsonObject.toJavaObject(Person.class);
System.out.println(jsonObject.getInteger("id"));

// 将字符串直接解析为 java 对象
Person personFromJson2 = JSON.parseObject(jsonStr, Person.class);

String jsonArrStr = "[{id:1},{id:2}]";

// 将字符串解析为 JSONArray 对象
JSONArray jsonArray = JSON.parseArray(jsonStr);
List<Person> personListFromJson1 = jsonArray.toJavaList(Person.class);

// 将字符直接串解析为 java List 对象
List<Person> personListFromJson2 = JSON.parseArray(jsonStr, Person.class);

JSONField 注解

JSONField 加在字段上,对字段单独指定序列化方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

// 禁止序列化密码字段
@JSONField(serialize = false)
private String password;

// 指定别名
@JSONField(name = "性别")
private Sex sex;

// 指定序列化类
@JSONField(serializeUsing = HelloBigDecimalSerializer.class)
private BigDecimal money;

// 单独指定日期格式
@JSONField(format = "yyyy-MM-dd")
private Date birthday;

SerializerFeature

SerializerFeature 是fastjson的序列化特性枚举类。

枚举 描述
QuoteFieldNames 使用双引号包围字段名称
UseSingleQuotes 使用双引号
WriteMapNullValue 序列化map中的null
WriteEnumUsingToString 用枚举toString()值输出
WriteEnumUsingName 用枚举name()输出
UseISO8601DateFormat 使用 ISO8601 标准输出日期
WriteNullListAsEmpty 将 null 值的 List 序列化为 "[]"
WriteNullStringAsEmpty 将 null 值的 String 序列化为 ""
WriteNullNumberAsZero 将 null 值的 Number 序列化为 "0"
WriteNullBooleanAsFalse 将 null 值的 Boolean 序列化为 "false"
SkipTransientField 跳过 transient 字段
SortField 将字段按照字典序排列,例如:"{a:1,b:2,c:3}"
WriteTabAsSpecial <todo>
PrettyFormat <todo>
WriteClassName <todo>
DisableCircularReferenceDetect 禁用循环引用检测(强烈建议禁用)
WriteSlashAsSpecial <todo>
BrowserCompatible <todo>
WriteDateUseDateFormat <todo>
NotWriteRootClassName <todo>
DisableCheckSpecialChar <todo>
BeanToArray <todo>
WriteNonStringKeyAsString <todo>
NotWriteDefaultValue 不输出默认值
BrowserSecure <todo>
IgnoreNonFieldGetter <todo>
WriteNonStringValueAsString <todo>
IgnoreErrorGetter 忽略 getter 方法报错
WriteBigDecimalAsPlain 使用 BigDecimal.toPlainString() 序列化
MapSortField 对Map的key按照字典序排列后序列化

spring MVC 配置

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<bean id="fastJsonConfig" class="com.alibaba.fastjson.support.config.FastJsonConfig">
<property name="charset" value="UTF-8"/>
<property name="dateFormat" value="yyyy-MM-dd HH:mm:ss" />
<property name="features">
<array>
<value>IgnoreNotMatch</value>
<value>AllowUnQuotedFieldNames</value>
</array>
</property>
<property name="serializerFeatures">
<array>
<value>WriteDateUseDateFormat</value>
<value>WriteMapNullValue</value>
<value>DisableCircularReferenceDetect</value>
</array>
</property>
<property name="serializeConfig">
<bean class="com.alibaba.fastjson.serializer.SerializeConfig">
<!-- 强烈建议禁用 ASM ,fastjson 在 ASM模式下,自定义序列化类不起作用 -->
<property name="asmEnable" value="false"/>
</bean>
</property>
</bean>

<mvc:annotation-driven>
<mvc:message-converters>
<!-- 这个一定要在 FastJsonHttpMessageConverter 前 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8"/>
<property name="supportedMediaTypes">
<array>
<value>text/html</value>
<value>application/json</value>
</array>
</property>
</bean>
<!-- 配置fastjson解析 -->
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<array>
<value>text/html</value>
<value>application/json</value>
</array>
</property>
<property name="defaultCharset" value="UTF-8"/>
<property name="fastJsonConfig" ref="fastJsonConfig" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

自定义序列化和反序列化

自定义序列化时,需要实现 com.alibaba.fastjson.serializer.ObjectSerializer 接口。并且需要注册:

1
SerializeConfig.getGlobalInstance().put(BigDecimal.class, new HelloBigDecimalSerializer());

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
package com.cloudin.example.support.fastjson;

import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.io.IOException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
* @author YFHan
* @version 1.0.0
* @date 2018/2/3 0003 18:26
*/
public class HelloBigDecimalSerializer implements ObjectSerializer {

@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
if (object == null) {
if (serializer.isEnabled(SerializerFeature.WriteNullNumberAsZero)) {
serializer.out.write("0.00");
} else {
serializer.out.writeNull();
}
} else {

BigDecimal value = (BigDecimal) object;
serializer.out.write(value.setScale(2, RoundingMode.DOWN).toPlainString());
}
}
}

spring json fastjson