fastJSON 学习笔记
添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version> 1.2.70</version>
</dependency>
<!--方便调试-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
简单使用
JSONArray
和 JSONObject
都是 JSON
子类
String text = JSON.toJSONString(obj); //序列化
VO vo = JSON.parseObject("{...}", VO.class); //反序列化
JSONObject json = (JSONObject)JSONObject.toJSON(vo); // javaBean 转 JSONObject
JSONObject.toJSONString(vo, SerializerFeature.PrettyFormat); // 对象格式化输出。类似js中的 JSON.stringify(vo,null,4);
JSONObject.toJSONString(JSONObject.parse(vo), SerializerFeature.PrettyFormat); // 字符串格式化就有点傻了,要先转对象
faseJSON 结果为空时
空数组列表,结果是 []
空对象,结果是:{}
前端都可以直接给 js 用。 (感觉有点废话。o( ̄▽ ̄)o )
Java 泛型列表转 JSON
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.NameFilter;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
// 按 XXid 查询 hehe 列表
List<Hehe> heheList = heheService.getHeheByXXid(XXid);
//映射属性名
NameFilter nameFilter = new NameFilter() {
public String process(Object source, String name, Object value) {
if (name.equals("heheId")) {
return "id";
}else if (name.equals("heheName")) {
return "name";
}
return name;
}
};
//【转JSON,字段过滤 方法一 】 (以下用的是包含,也可以用排除。包含优先级较高,只要设置,排除就无效了。)
SimplePropertyPreFilter sppfilter = new SimplePropertyPreFilter();
sppfilter.getIncludes().add("heheId");
sppfilter.getIncludes().add("heheName");
sppfilter.getIncludes().add("heheValue");
sppfilter.getIncludes().add("heheRemark");
sppfilter.getIncludes().add("sheheImage");
//【转JSON,字段过滤 方法二 】,直接写出要序列化的属性
//public SimplePropertyPreFilter(Class<?> clazz, String... properties){...}
sppfilter = new SimplePropertyPreFilter(Hehe.class, "heheId","heheName","heheValue");
//直接传属性名,它是一个 Class<?> clazz 为 null 的重载。不知其所以然 ( >﹏<)
//sppfilter = new SimplePropertyPreFilter("heheId","heheName","heheValue");
JSON.toJSONString(heheList, sppfilter);
//只使用字段过滤(没有映射属性名)
JSON.toJSONString(heheList, sppfilter, SerializerFeature.UseSingleQuotes);
//【字段过滤】+【映射属性名】两个过滤器放进数据,即可同时使用
//转JSON,支持数组传多个【过滤器】,多个【SerializerFeature】直拉往加后参数就行了,当然也支持传数组(如果多次使用,创建个数组方便些)
//SerializeFilter[] filterArr = {nameFilter, sppfilter};
//JSON.toJSONString(heheList, filterArr, SerializerFeature.UseSingleQuotes);
/**
* 如果 hehe 的子对象 haha 中有外键 heheId 想避免 haha 里的 heheId 被序列化(把父子两个对象都设置过滤就行了):
* SimplePropertyPreFilter sppfilter = new SimplePropertyPreFilter(SmartSite.class,"heheId","heheName","heheValue","heheRemark","sheheImage");
* SimplePropertyPreFilter sppfilter2 = new SimplePropertyPreFilter(haha.class,"hahaId","hahaName" );
* 转JSON,多个过滤器用数组传参【字段过滤】+【映射属性名】+【排除子对象中的 父表id】
* SerializeFilter[] filterArr = {nameFilter, sppfilter, sppfilter2};
* 【2B注意】子对象的属性,只有在子对象被序列化的前提下,才会出来
*/
序列化时定义属性顺序(class级别注解)
//fastJSON序列化时定义属性顺序(所有字段都要列出来,否则无效)
@JSONType(orders={"heheId","heheName","heheValue","heheRemark","sheheImage"})
public class heheBean{
private String sheheImage;
private Integer heheId;
private Integer heheValue;
private String heheRemark;
private String heheName;
//----------- getter setter begin ----------
...
//----------- getter setter end ----------
}
@JSONType(orders={"hahaId","hahaName","heheId"})
public class hahaBean{
private Integer hahaId;
private Integer heheId;
private String hahaName;
//----------- getter setter begin ----------
...
//----------- getter setter end ----------
}
@JSONField
属性 | 说明 |
---|---|
name | 指定字段名 |
serialize | 是否序列化。默认 true |
deserialize | 是否反序列化。默认 true |
ordinal | 序列化和反序列化的顺序,1.1.42版本之后才支持 |
format | 日期格式化 |
serializeUsing | 在fastjson 1.2.16版本之后,JSONField支持新的定制化配置serializeUsing,可以单独对某一个类的某个属性定制序列化 |
@Data
public class Hero{
@JSONField(name = "name", serialize = true, ordinal = 1, serializeUsing = MySerializer.class)
private String heroName;
// 反序列化时忽略年龄
@JSONField(name = "age", deserialize = false, ordinal = 2, serializeUsing = MySerializer.class)
private Integer heroAge;
@JSONField(name = "birthday", format="yyyy-MM-dd", ordinal = 3)
private Date heroBirthday;
}
serializeUsing 应用
MySerializer 保持 18 岁
public class MySerializer implements ObjectSerializer {
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
Integer age = (Integer) object;
age = age > 18 ? 18 : age;
serializer.write(age);
}
}
序列化与反序列化时字段名不一样
@JSONField
加在 getter、settter
上
public class User {
private String name;
private String title;
public String getName() { return name; }
@JSONField(name = "userName")
public void setName(String name) { this.name = name; }
public String getTitle() { return title; }
@JSONField(name = "userTitle")
public void setTitle(String title) { this.title = title; }
}
@Test
public void test(){
String str1 = "{\"name\":\"aaaa\",\"title\":\"bbb\"}";
User test1 = JSONObject.parseObject(str1, User.class);
System.out.println(JSONObject.toJSONString(test1)); // {}
String str2 = "{\"userName\":\"aaaa\",\"userTitle\":\"bbb\"}";
User test2 = JSONObject.parseObject(str2, User.class);
System.out.println(JSONObject.toJSONString(test2)); // {"name":"aaaa","title":"bbb"}
}
例:驼峰与下划线问题 @JSONField(name=“JSON中的key”)
@JSONField(name="JSON中的key")
可以用于自定义序列化后的key
。
这是微信小程序 code2Session 接口返回的数据
这里返回的JSON中 session_key
与 sessionKey
无法对应(虽然听说fastjson能自动匹配,但实验失败版本 1.2.4)
所以使用 @JSONField(name="session_key")
注解来解决。
code2Session:{
openid:'string',// 用户唯一标识
session_key:'string',// 会话密钥
unionid:'string',// 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见 UnionID 机制说明。
errcode:'number',// 错误码
errmsg:'string',// 错误信息
}
建立对应POJO
package com.jerry.wechat.pojo;
import java.util.Date;
import com.alibaba.fastjson.annotation.JSONField;
public class WeChatSession {
private String openid; // 用户唯一标识
@JSONField(name="session_key")
private String sessionKey; // 会话密钥
private String unionid; // 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见 UnionID 机制说明。
private Integer errcode; // 错误码
private String errmsg; // 错误信息
private Date createDate;
}
反序列化
Hero hero = JSON.parseArray(str, Hero.class);
List<Hero> list = JSON.parseArray(str, Hero.class);
泛型反序列化
Result<Hero> result = null;
result = JSON.parseObject(str, new TypeReference<Result<Hero>>(){});
List<Map<String, Hero>> map = null;
map = JSON.parseObject(str, new TypeReference<List<Map<String, String>>>(){});
参考资料
Fastjson 常见问题
Fastjson 常见问题 - JSONField 介绍
FastJSON2 学习笔记
Fastjson SerializerFeature详解 【传送门】
w3cschool Fastjson API SerializeFilte r简介
runoob Fastjson 简明教程