Json 是目前互联网应用使用最为广泛的信息交换格式之一。Spring Boot 内置了 Jackson 。Json 在应用中主要体现在以下功能:

  1. 序列化
  2. 反序列化
  3. 字段格式化
  4. 验证自动化

目前长用的 Json 组件包括

  1. Jackson
  2. Gson
  3. FastJson
  4. JSON-B

本章主要讨论以上 4 中 Json 组件的 4 中功能。

本项目源码 github 下载

1 新建 Spring Boot Maven 示例工程项目

注意:是用来 IDEA 开发工具

  1. File > New > Project,如下图选择 Spring Initializr 然后点击 【Next】下一步
  2. 填写 GroupId(包名)、Artifact(项目名) 即可。点击 下一步

    groupId=com.fishpro

    artifactId=json
  3. 选择依赖 Spring Web Starter 前面打钩。
  4. 项目名设置为 spring-boot-study-json.

2 编写代码用于测试示例

2.1 用户实体类

新建两个实体类,用户类、用户地址类,他们的关系是父子关系

User(路径 src/main/java/com/fishpro/json/dto/User.java)

public class User {
private Integer userId; private String username; private List<Address> addresses; private Calendar created = new GregorianCalendar(); public User(Integer userId,String username){
this.userId=userId;
this.username=username;
}
public User(Integer userId,String username,List<Address> addresses){
this.userId=userId;
this.username=username;
this.addresses=addresses;
}
public Integer getUserId() {
return userId;
} public void setUserId(Integer userId) {
this.userId = userId;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public List<Address> getAddresses() {
return addresses;
} public void setAddresses(List<Address> addresses) {
this.addresses = addresses;
} public Calendar getCreated() {
return created;
} public void setCreated(Calendar created) {
this.created = created;
}
}

Address (路径 src/main/java/com/fishpro/json/dto/Address.java)

public class Address {
private String street;
private String zipcode;
private String mobile; public Address(String street,String zipcode,String mobile){
this.street=street;
this.zipcode=zipcode;
this.mobile=mobile;
}
public String getStreet() {
return street;
} public void setStreet(String street) {
this.street = street;
} public String getZipcode() {
return zipcode;
} public void setZipcode(String zipcode) {
this.zipcode = zipcode;
} public String getMobile() {
return mobile;
} public void setMobile(String mobile) {
this.mobile = mobile;
}
}

2.2 控制层代码

UserController (路径 src/main/java/com/fishpro/json/controller/UserController.java)

@RequestMapping("/user")
@RestController
public class UserController { @GetMapping("/get")
public User get(){
List<Address> addressList=new ArrayList<>();
addressList.add(new Address("江苏省南京市玄武大道1000号","201001","1801989098"));
addressList.add(new Address("江苏省南京市玄武大道1001号","201001","1811989098"));
User user = new User(1, "fishpro",addressList);
return user;
}
}

运行 右键点击 JsonApplication > Run JsonApplication 在浏览器中输入 http://localhost:8086/user/get 系统直接返回了json格式,那么 Spring Boot 中默认就是哟合那个了 Jackson 来处理。

{
"userId": 1,
"username": "fishpro",
"addresses": [{
"street": "江苏省南京市玄武大道1000号",
"zipcode": "201001",
"mobile": "1801989098"
}, {
"street": "江苏省南京市玄武大道1001号",
"zipcode": "201001",
"mobile": "1811989098"
}],
"created": "2019-08-13T14:40:50.901+0000"
}

3 Jackson

3.1 依赖引入 Jackson

无须引入,Spring Boot 默认采用了 Jackson来处理诸如 @RequestBody @ResponseBody

3.2 配置 Jackson

如 2。2 代码示例,默认采用了 Jackson ,但返回的日期格式没有展示人们常用的格式,就要我们从 applicaiton中配置他的展示格式。

server.port = 8086
#jackson
#日期格式化
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
#spring.jackson.date-format=yyyy-MM-dd
#格式化输出
spring.jackson.serialization.indent_output=true
#忽略无法转换的对象
spring.jackson.serialization.fail_on_empty_beans=false
#设置空如何序列化
spring.jackson.defaultPropertyInclusion=NON_EMPTY
#允许对象忽略json中不存在的属性
spring.jackson.deserialization.fail_on_unknown_properties=false
#允许出现特殊字符和转义符
spring.jackson.parser.allow_unquoted_control_chars=true
#允许出现单引号
spring.jackson.parser.allow_single_quotes=true

运行 右键点击 JsonApplication > Run JsonApplication 在浏览器中输入 http://localhost:8086/user/get 系统直接返回了json格式, 现在 created 以 yyy-MM-dd HH:mm:ss 展示给我们了。

{
"userId" : 1,
"username" : "fishpro",
"addresses" : [ {
"street" : "江苏省南京市玄武大道1000号",
"zipcode" : "201001",
"mobile" : "1801989098"
}, {
"street" : "江苏省南京市玄武大道1001号",
"zipcode" : "201001",
"mobile" : "1811989098"
} ],
"created" : "2019-08-13 14:51:48"
}

3.3 Jackson 序列化

如何单独的使用序列化和反序列化功能呢

 //测试 Jackson 序列化
ObjectMapper mapper=new ObjectMapper();//定义一个转化对象
List<Address> addressList=new ArrayList<>();
addressList.add(new Address("江苏省南京市玄武大道1000号","201001","1801989098"));
addressList.add(new Address("江苏省南京市玄武大道1001号","201001","1811989098"));
User user = new User(1, "fishpro",addressList);
try {
String json = mapper.writeValueAsString(user);
System.out.println(json); }catch (Exception e){
e.printStackTrace();
}

3.4 Jackson 反序列化

 //测试 Jackson 序列化
ObjectMapper mapper=new ObjectMapper();//定义一个转化对象
//测试 Jackjson 反序列化
String json="{\"userId\":2,\"username\":\"程序员\",\"addresses\":[{\"street\":\"江苏省南京市玄武大道1000号\",\"zipcode\":\"201001\",\"mobile\":\"1801989098\"},{\"street\":\"江苏省南京市玄武大道1001号\",\"zipcode\":\"201001\",\"mobile\":\"1811989098\"}],\"created\":1565709784274}"; try {
User user2 = mapper.readValue(json, User.class);
System.out.println(user2); }catch (Exception e){
e.printStackTrace();
}

3.5 常用注解

Jackson提供了一系列注解,方便对JSON序列化和反序列化进行控制,下面介绍一些常用的注解。

@JsonIgnore

@JsonIgnore 此注解用于属性上,作用是进行JSON操作时忽略该属性。

@JsonFormat

@JsonFormat 此注解用于属性上,作用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")。

例如为字段单独指定时间格式

    /**更新时间 用户可以点击更新,保存最新更新的时间。**/
@JsonFormat(pattern="yyyy-MM-dd")
private Calendar updated = new GregorianCalendar();

@JsonProperty

@JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,@JsonProperty("name")。

3.6 问题:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of com.fishpro.json.dto.User (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

因为实体类没有显示的 无参数构造函数,所有报错了,解决方案就是在实体类中增加无参数构造函数,例如本示例中

public User(){}
public Address(){}

4 fastjson

fastjson 是 阿里巴巴的开源项目。在国内使用非常广泛。

4.1 依赖引入

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>

4.2 fastjson 序列化

List<Address> addressList=new ArrayList<>();
addressList.add(new Address("江苏省南京市玄武大道1000号","201001","1801989098"));
addressList.add(new Address("江苏省南京市玄武大道1001号","201001","1811989098"));
User user = new User(1, "fishpro",addressList);
//测试 Fastjson 序列化
System.out.println("测试 Fastjson 序列化");
System.out.println(JSON.toJSONString(user));

输出结果

{"addresses":[{"mobile":"1801989098","street":"江苏省南京市玄武大道1000号","zipcode":"201001"},{"mobile":"1811989098","street":"江苏省南京市玄武大道1001号","zipcode":"201001"}],"created":1565787589602,"userId":1,"username":"fishpro"}

4.3 fastjson 反序列化

        String json="{\"userId\":2,\"username\":\"程序员\",\"addresses\":[{\"street\":\"江苏省南京市玄武大道1000号\",\"zipcode\":\"201001\",\"mobile\":\"1801989098\"},{\"street\":\"江苏省南京市玄武大道1001号\",\"zipcode\":\"201001\",\"mobile\":\"1811989098\"}],\"created\":1565709784274}";

        //测试 Fastjson 反序列化
System.out.println("测试 Fastjson 反序列化");
User user3 = JSON.parseObject(json,User.class);
System.out.println(user3);

4.4 fastjson 的注解

上面序列化、反序列化使用的实体类的注解还是 jackjson 中使用的。为了说明注解问题,我们新疆一个类 Person

@JSONField

@JSONField 作用在类的属性上,是类的属性与输出的 Json 的映射。JSONField 的几个属性

名称 用途
name 指定那么的时候表示 json 输出使用此 name @JSONField(name="ID")
format 格式化日期 @JSONField(format="yyyyMMdd")
serialize false 表示不序列化 @JSONField(serialize=false)
deserialize false 表示不反序列化 @JSONField(deserialize=false)
ordinal f使用 ordinal 指定字段的顺序 @JSONField(ordinal = 3)

public class Person { @JSONField(name = "age")
private int age; @JSONField(name = "full_name",ordinal = 1)
private String fullName; @JSONField(name = "date_of_birth",format = "yyyy-MM-dd")
private Date dateOfBirth; @JSONField(serialize = false)
private String alias; public Person(int age, String fullName, Date dateOfBirth) {
super();
this.age = age;
this.fullName= fullName;
this.dateOfBirth = dateOfBirth;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getFullName() {
return fullName;
} public void setFullName(String fullName) {
this.fullName = fullName;
} public Date getDateOfBirth() {
return dateOfBirth;
} public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
} public String getAlias() {
return alias;
} public void setAlias(String alias) {
this.alias = alias;
}
}

4.5 BeanToArray 功能

System.out.println("测试 Fastjson person 注解");
Person person=new Person(100,"dashen",new Date());
Person person2=new Person(98,"dashen2",new Date());
Person person3=new Person(88,"dashen3",new Date());
List<Person> personList=new ArrayList<>();
personList.add(person);
personList.add(person2);
personList.add(person3);
System.out.println(JSON.toJSONString(personList, SerializerFeature.BeanToArray));

输出

{"age":100,"date_of_birth":"2019-08-14","full_name":"dashen"}

4.6 直接创建 JSON 对象

 System.out.println("测试 Fastjson 生成 json");
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < 2; i++) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("AGE", 10);
jsonObject.put("FULL NAME", "Doe " + i);
jsonObject.put("DATE OF BIRTH", "2019/08/12 12:12:12");
jsonArray.add(jsonObject);
}
System.out.println(jsonArray.toJSONString());

生成

[{"DATE OF BIRTH":"2019/08/12 12:12:12","FULL NAME":"Doe 0","AGE":10},{"DATE OF BIRTH":"2019/08/12 12:12:12","FULL NAME":"Doe 1","AGE":10}]

4.7 过滤器 ValueFilter

名称 说明
PropertyPreFilter 根据PropertyName判断是否序列化
PropertyFilter 根据PropertyName和PropertyValue来判断是否序列化
NameFilter 修改Key,如果需要修改Key,process返回值则可
ValueFilter 修改Value
BeforeFilter 序列化时在最前添加内容
AfterFilter 序列化时在最后添加内容

过滤器一般用于特定场景用途。


参考:

https://www.cnblogs.com/jian-xiao/p/6009435.html?utm_source=itdadao&utm_medium=referral

https://www.cnblogs.com/yuanmo396022993/p/9118308.html

https://www.runoob.com/w3cnote/fastjson-intro.html

http://kimmking.github.io/2017/06/06/json-best-practice/

Spring Boot Json 之 Jackjson Fastjson的更多相关文章

  1. FastJson/spring boot: json输出方法二

    1.引入FastJson依赖包 <!-- FastJson --> <dependency> <groupId>com.alibaba</groupId> ...

  2. FastJson/spring boot: json输出

    1.引入FastJson依赖包 <!-- FastJson --> <dependency> <groupId>com.alibaba</groupId> ...

  3. 在spring boot环境中使用fastjson + redis的高速缓存技术

    因为项目需求,需要在spring boot环境中使用redis作数据缓存.之前的解决方案是参考的http://wiselyman.iteye.com/blog/2184884,具体使用的是Jackso ...

  4. Spring Boot与Mybatis 借助Fastjson快速完成数据解析入库

    通过Spring Boot可以快速搭建一个项目结构,在此基础上本文就通过一个简单的例子,说明如何结合Mybatis 和 Fastjson,快速的完成一个数据的入库基本操作. 添加相关的依赖 <d ...

  5. spring boot json 首字母大小写问题解决方案

     spring boot默认使用的json解析框架是jackson,对于.net转java的项目来说太坑了,首字母大写的属性会自动转为小写,然后前端就悲剧了,十几个属性的ViewModel增加几个Js ...

  6. spring boot配置使用fastjson

    一.前言 spring boot默认使用jackson来操作json数据,相比于jackson,fastjson更好用,功能也强大,所以这里记录一下在spring boot中配置使用fastjson的 ...

  7. spring boot 入门操作(二)

    spring boot入门操作 使用FastJson解析json数据 pom dependencies里添加fastjson依赖 <dependency> <groupId>c ...

  8. Spring Boot 知识图谱

    最近有意重新学习下SpringBoot知识,特地总结了SpringBoot的知识点,对于想要学习的人来说,够用. SpringBoot学习路径 第一部分:了解 Spring Boot Spring B ...

  9. Spring Boot (2) Restful风格接口

    Rest接口 动态页面jsp早已过时,现在流行的是vuejs.angularjs.react等前端框架 调用 rest接口(json格式),如果是单台服务器,用动态还是静态页面可能没什么大区别,如果服 ...

随机推荐

  1. C++-POJ2960-S-Nim-[限制型Nim]

    每次只能从取集合S中个数的物品,其他和普通Nim游戏相同 预处理出每种物品堆的sg值,然后直接xor一下,xor-sum>0即必胜 #include <set> #include & ...

  2. webscarab

    1.功能 WebScarab是一个用来分析使用HTTP和HTTPS协议的应用程序框架.其原理很简单,WebScarab可以记录它检测到的会话内容(请求和应答),并允许使用者可以通过多种形式来查看记录. ...

  3. os和sys模块_python

    一.os模块 1.os模块的功能 提供对系统调用的借口,常用于系统文件目录打交道. 2.常用的方法 二.sys模块 1.模块功能 与python解释器交互 2.常用方法 print(sys.path) ...

  4. 虚拟路径引起的bug

    之前,遇到一个问题,就是,项目访问不了最新产生的pdf文件. 百思不得其解,为什么,返回 idea 页面就可以访问了(真的只是返回 idea 页面,不进行其他什么的操作).一直以为是热部署的问题 后来 ...

  5. MySql 中关键字 case when then else end 的用法

    解释: SELECT case -------------如果 ' then '男' -------------sex='1',则返回值'男' ' then '女' -------------sex= ...

  6. js 简单粗暴深拷贝

    var obj = {} var newObj = JSON.parse(JSON.stringify(obj))

  7. Android 开发 ThreadPool(线程池) 总结

    本文是介绍线程池的基础篇. 一.线程池的作用 创建异步线程的弊端: 1.每次new Thread创建对象,导致性能变差. 2.缺乏统一的管理,可能导致无限制的线程运行,严重的后果就是OOM 或者死机. ...

  8. C# 获取变量的指针(IntPtr)

     1. 获取数组的指针(IntPtr) 通过Marshal.UnsafeAddrOfPinnedArrayElement(Array,Int32)方法获得一个数组的第某个元素的内存地址. Array是 ...

  9. windows_环境变量

    今天在windows下安装了openSSH,就想在windows下也添加一个服务器地址的环境变量,添加是会了,引用却不会,网上也没找到相应的文章,就自己看了看别人的bat程序,然后找到了引用变量的方法 ...

  10. 虚拟机NAT模式联网

    阿里开源镜像软件:https://opsx.alibaba.com/mirror 如何使VMware ip与本机ip处于同一网段 https://blog.csdn.net/kakuma_chen/a ...