🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 一、 FastJSON、Gson和Jackson对比 **开源的Jackson**:SpringBoot默认是使用Jackson作为JSON数据格式处理的类库,Jackson在各方面都比较优秀,所以不建议将Jackson替换为Gson或fastjson。 **Google的Gson**:Gson是Google为满足内部需求开发的JSON数据处理类库,其核心结构非常简单,toJson与fromJson两个转换函数实现对象与JSON数据的转换, **阿里巴巴的FastJson**:Fastjson是阿里巴巴开源的JSON数据处理类库,其主要特点是序列化速度快。当并发数据量越大的时候,越能体现出fastjson的优势。但是笔者觉得选择JSON处理类库,快并不是唯一需要考虑的因素,与数据库或磁盘IO相比,JSON数据序列化与反序列化的这点时间还不足以对软件性能产生比较大的影响。 **性能比较**:笔者看多很多的关于这三个类库的性能测试(截止2019年11月20日),总结如下: * 序列化过程性能:fastjson >= jackson > Gson,Gson在数据并发量较大时会与其他二者有较明显差距。 * 反序列化性能:三者几乎不相上下,Gson略好一点。 **fastjson为人诟病的问题:**:虽然fastjson速度上有一定的优势,但是其为了追求速度,很大程度放弃了JSON的规范性。因此还时不时的在有些版本中暴露安全问题。大家如果有机会去看一下fastjson的github代码,其代码质量不是很高。所以用不用fastjson在国内软件界还是有争议的,在国外基本没人用。 ## 二、在Spring中注解方法使用Jackson 在上文中,笔者已经给出自己的结论:不建议将Jackson替换为Gson或fastjson。jackson主要的作用是: > 什么叫序列化与反序列化?说白了就是把对象转成可传输、可存储的格式(json、xml、二进制、甚至自定义格式)叫做序列化。反序列化顾名思义。 * 反序列化:在客户端将请求数据上传到服务端的时候,自动的处理JSON数据对象中的字符串、数字,将其转换为包含Date类型、Integer等类型的对象。 * 序列化:按照指定的格式、顺序等将实体类对象转换为JSON字符串 所以我们下面就给大家介绍一下jackson的常用注解的使用方法,帮助我们进行序列化和反序列化工作。 ### 常用注解 这些注解通常用于标注java实体类或实体类的属性。 * @JsonPropertyOrder(value={"pname1","pname2"}) 改变子属性在JSON序列化中的默认定义的顺序。如:param1在先,param2在后。 * @JsonIgnore 排除某个属性不做序列化与反序列化 * @JsonProperty(anotherName) 为某个属性换一个名称,体现在JSON数据里面 * @JsonInclude(JsonInclude.Include.NON\_NULL) 排除为空的元素不做序列化反序列化 * @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 指定日期类型的属性格式 ~~~ @JsonPropertyOrder(value={"content","title"}) public class Article { @JsonIgnore private Long id; @JsonProperty("auther") private String author; private String title; private String content; @JsonInclude(JsonInclude.Include.NON_NULL) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date createTime; private List<Reader> reader; } ~~~ 上文代码中对应的JSON数据格式可以为: ~~~ { auther :"", content:"", title:"", createTime:"2019-10-20 12:12:12", reader:[{"name":"zimug","age":18},{"name":"kobe","age":37}] } ~~~ * 因为定义了JsonPropertyOrder,content在先,title在后 * 因为定义了JsonIgnore,id属性被忽略 * 因为定义了JsonProperty,author属性变为auther * 因为定义了JsonInclude和JsonFormat,createTime不要为空,并且格式为 "yyyy-MM-dd HH:mm:ss" 通常会对日期类型转换,进行全局配置,而不是在每一个java bean里面配置 ~~~ spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 ~~~ ## 三、手动数据转换 除了在spring框架内实现自动的前后端JSON数据与java对象的转换,我们还可以使用jackson自己写代码进行转换。 ~~~ //jackson的ObjectMapper 转换对象 ObjectMapper mapper = new ObjectMapper(); //将某个java对象转换为JSON字符串 String jsonStr = mapper.writeValueAsString(javaObj); //将jsonStr转换为Ademo类的对象 Ademo ademo = mapper.readValue(jsonStr, Ademo.class); ~~~ 当JSON字符串代表的对象的字段多于类定义的字段时,使用readValue会抛出UnrecognizedPropertyException异常,在类的定义处加上@JsonIgnoreProperties(ignoreUnknown = true)可以解决这个问题。 ## 四、Postman测试 下面让我们结合postman对REST接口和Jackson做一下测试吧。Postman是接口测试过程中经常使用到的工具。 测试使用数据: ~~~ { "id": 1, "author": "zimug", "title": "手摸手教你开发spring boot", "content": "c", "createTime": "", "reader":[{"name":"zimug","age":18},{"name":"kobe","age":37}] } ~~~ 下面以测试新增文章的接口为例: * 测试的接口服务端点为“/rest/article” * 服务端点支持的HTTP方法为POST * 使用Http协议的body传输JSON数据,对应Controller应该使用RequestBody进行数据参数接收 * 点击Send进行接口数据的发送 测试的接口代码请参考本专栏之前实现的RESTful接口,更多接口测试请看课堂视频实操。 ![](https://img.kancloud.cn/f2/41/f241191f583aa6487220bab353f2dfc2_816x445.png) ## 五、神奇的Bug 在有些版本JsonFormat注解(比如:Spring Boot 2.3.0.RELEASE),不能生效。我经过反复的实验,为实体类增加一个无参的构造函数和一个全参的构造函数,JsonFormat注解就生效了! ![](https://img.kancloud.cn/57/3e/573ec4232cb3f97de314f9c956d170ba_1166x376.png)