JSON官网:https://www.json.org/json-en.html
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。轻量级指的是跟xml作比较,数据交换指的是客户端和服务器之间业务数据的传输格式。
JSON 是一种完全独立于语言的文本格式,使用 C 系列语言(包括 C)所熟悉的约定,使之让开发者很容易阅读和编写,也让机器很容易解析和生成,并有效地提升网络传输效率。这些优点也使 JSON 成为一种理想的独立语言文本格式。很多语言都提供了对json的支持(包括C,C++,C#,Java,JavaScript、Perl、Python等)。

Json的数据本身是数组,中括号包裹,数组的元素之间逗号分开,数组元素的数据类型没有限制。
JsonArray_Json数组格式
输出:鼠标放到页面上 右键 -> 选择检查> 或 直接按 F12>

json的数据本身是对象,大括号包裹,对象采用键值对形式存储,键固定为字符串类型,值是任意类型的数据,键和值使用冒号分开。
JsonObject_Json对象格式

JsonArrayObject_Json数据的嵌套

JsonObjectArray

Json数据的嵌套

描述同样的消息,json相比xml占用更少的空间,如:
xml格式
1 张三 30
json表示
{"id": 1,"name": "张三","age": 30
}
所有的操作把java里面的bean、map、collection等转化为json字符串(序列化),或反向操作(反序列化)占用更少的空间,如:java里面作json的技术一览
json官网:https://www.json.org/json-en.html

FastJson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将JavaBean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。FastJson会出现漏洞和bug,注意一下!

com.alibaba fastjson 1.2.68 compile
package com.test.json.pojo;import lombok.Data;
import java.util.Date;@Data
public class Student {private Integer id;private String name;private Integer age;private String email;private Date birthday;private Boolean flag;
}
序列化:是指将java对象转成json格式字符串的过程,JavaBean对象,List集合对象,Map集合,为应用最广泛的。
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.test.json.pojo.Student;
import org.junit.Test;import java.util.*;public class TestFastJson {//用于获取日期public Date getDate(){Date date = new Date();return date;}
}
@Test//Java中的对象,Student对象,序列化为Json格式字符串public void testObjectToJson(){Student student = new Student();student.setId(1);student.setName("张三");student.setAge(20);student.setEmail("zs@sina.com");student.setBirthday(getDate()); //转化毫秒值//student 对象,转到Json格式字符串//调用静态方法,传递要转换的对象String jsonString = JSON.toJSONString(student);System.out.println(jsonString);//student对象,转到Json格式字符串//{"age":20,"birthday":1662539443005,"email":"zs@sina.com","id":1,"name":"张三"}}
@Test//Java中的集合List,序列化为Json格式字符串public void testListToJson(){//集合List,存储Student对象List list = new ArrayList<>();Student student1 = new Student();student1.setId(1);student1.setName("张三");student1.setAge(20);student1.setEmail("zs@sina.com");student1.setBirthday(getDate()); //转化毫秒值Student student2 = new Student();student2.setId(2);student2.setName("李四");student2.setAge(22);student2.setEmail("ls@126.com");student2.setBirthday(getDate()); //转化毫秒值//Student对象存储到List集合中list.add(student1);list.add(student2);//List集合,序列化为Json格式字符串String jsonString = JSON.toJSONString(list);System.out.println(jsonString);// 转后的结果是数组,数组的元素是对象// [{"age":20,"birthday":1662539828574,"email":"zs@sina.com","id":1,"name":"张三"}, //数组是1对象:张三 2对象:李四// {"age":22,"birthday":1662539828574,"email":"ls@126.com","id":2,"name":"李四"}]}
@Test//Java中的集合Maps,序列化为Json格式字符串public void testMapToJson(){//创建Map集合,键为字符串类型,值是Student对象Map map = new HashMap();//集合List,存储Student对象List list = new ArrayList<>();Student student1 = new Student();student1.setId(1);student1.setName("张三");student1.setAge(20);student1.setEmail("zs@sina.com");student1.setBirthday(getDate()); //转化毫秒值Student student2 = new Student();student2.setId(2);student2.setName("李四");student2.setAge(22);student2.setEmail("ls@126.com");student2.setBirthday(getDate()); //转化毫秒值map.put("Student1",student1);map.put("Student2",student2);String jsonString = JSON.toJSONString(map);System.out.println(jsonString);// json格式字符串是对象,对象中有两个键 student1 student2 每个键对应的值是Student对象 List转换是数组 map转换是对象// {"Student1":{"age":20,"birthday":1662540245268,"email":"zs@sina.com","id":1,"name":"张三"},// "Student2":{"age":22,"birthday":1662540245268,"email":"ls@126.com","id":2,"name":"李四"}}}
@Test//Json格式字符串,反序列化回到Java对象public void testJsonToObject(){String jsonString = "{\"age\":20,\"birthday\":1662539443005,\"email\":\"zs@sina.com\",\"id\":1,\"name\":\"张三\"}";//JSON类的静态方法//传递要反序列化的Json字符串,传递Java对象的class对象Student student = JSON.parseObject(jsonString,Student.class);System.out.println(student);//Student(id=1, name=张三, age=20, email=zs@sina.com, birthday=Wed Sep 07 16:30:43 CST 2022)}
@Test//Json格式字符串,反序列化回到List集合public void testJsonToList(){String jsonString = "[{\"age\":20,\"birthday\":1662539828574,\"email\":\"zs@sina.com\",\"id\":1,\"name\":\"张三\"},{\"age\":22,\"birthday\":1662539828574,\"email\":\"ls@126.com\",\"id\":2,\"name\":\"李四\"}]";//JSON类的静态方法,parseArray//传递json格式字符串,传递转换后的集合的泛型的class对象List list = JSON.parseArray(jsonString,Student.class);for (Student student:list){System.out.println(student);}// Student(id=1, name=张三, age=20, email=zs@sina.com, birthday=Wed Sep 07 16:37:08 CST 2022)// Student(id=2, name=李四, age=22, email=ls@126.com, birthday=Wed Sep 07 16:37:08 CST 2022)}
@Test//Json格式字符串,反字符串回到Map集合public void testJsonToMap(){String jsonString = " {\"Student1\":{\"age\":20,\"birthday\":1662540245268,\"email\":\"zs@sina.com\",\"id\":1,\"name\":\"张三\"},\"Student2\":{\"age\":22,\"birthday\":1662540245268,\"email\":\"ls@126.com\",\"id\":2,\"name\":\"李四\"}}";//JSON类的静态方法 .parseObject()//直接进行反序列化,Map集合没有泛型的,泛型没有是不安全的集合//转换后的集合,必须有泛型//调用parseObject,传递参数,类型引用 typeReferences类的泛型中,传递转后的map集合 protected 授权限保护的匿名方法 需要匿名内部类 是子类的匿名对象Map map = JSON.parseObject(jsonString,new TypeReference
创建测试类:
import java.util.Date;/*** SerializerFeature 枚举:进行序列化时,可以自己定义特殊需求* JSON静态方法 tJSONString()* 方法的参数:第一个是要序列化的对象* 方法的参数:第二个参数SerializerFeature枚举类型的可变参数* SerializerFeature枚举常量,做序列化的个性需求*/
public class TestFastJson2 {public Date getDate(){Date date = new Date();return date;}
}
SerializerFeature枚举常量,该枚举类型支持序列化的一些特性数据类型定义:
public static String toJSONString(Object object, SerializerFeature... features) {return toJSONString(object, DEFAULT_GENERATE_FEATURE, features);
}
@Test//WriteMapNullValue 枚举中的常量,序列化null值的字段public void testWriteMapNullValue(){Student student = new Student();student.setId(1);student.setName("张三");student.setAge(20);student.setBirthday(getDate()); //转化毫秒值//不赋值//student.setEmail("zs@sina.com");String jsonString1 = JSON.toJSONString(student);System.out.println(jsonString1);// {"age":20,"birthday":1662542783030,"id":1,"name":"张三"}//方法参数上,添加枚举类型String jsonString2 = JSON.toJSONString(student,SerializerFeature.WriteMapNullValue);System.out.println(jsonString2);// {"age":20,"birthday":1662542783030,"email":null,"id":1,"name":"张三"}}
"" @Test//WriteNullAsEmpty 枚举的常量,序列化为null的字段,值序列化为“”public void testWriteStringAsEmpty(){Student student = new Student();student.setId(1);student.setName("张三");student.setAge(20);student.setBirthday(getDate()); //转化毫秒值//不赋值//student.setEmail("zs@sina.com");//方法的参数上,添加枚举类型String jsonString = JSON.toJSONString(student,SerializerFeature.WriteNullStringAsEmpty);System.out.println(jsonString);// {"age":20,"birthday":1662543749112,"email":"","id":1,"name":"张三"}}
0 @Test//WriteNullNumberAsZero 枚举的常量 序列化字段值为null 序列化为0public void testWriteNullAsZero() {Student student = new Student();student.setId(1);student.setName("张三");//不赋值// student.setAge(20);student.setBirthday(getDate()); //转化毫秒值//不赋值//student.setEmail("zs@sina.com");//方法的参数上,添加枚举类型String jsonString = JSON.toJSONString(student,SerializerFeature.WriteNullNumberAsZero);System.out.println(jsonString);// {"age":0,"birthday":1662544065292,"id":1,"name":"张三"}}
@Test//WriteNullBooleanAsFalse 枚举的常量 序列化布尔值为null 序列华为falsepublic void testWriteNullBooleanAsFalse() {Student student = new Student();student.setId(1);student.setName("张三");student.setAge(20);student.setBirthday(getDate()); //转化毫秒值//不赋值//student.setEmail("zs@sina.com");//不赋值//student.setFlag(true);String jsonString1 = JSON.toJSONString(student);System.out.println(jsonString1);// {"age":20,"birthday":1662544479657,"id":1,"name":"张三"}//方法的参数上,添加枚举类型String jsonString2 = JSON.toJSONString(student,SerializerFeature.WriteNullBooleanAsFalse);System.out.println(jsonString2);// {"age":20,"birthday":1662544479657,"flag":false,"id":1,"name":"张三"}}
@Test// WriteDateUseDateFormat 枚举的常量,序列化 日期格式化// PrettyFormat 枚举常量,序列化,格式化输出public void testWriteDateUseDate_FormatPrettyFormat(){Student student = new Student();student.setId(1);student.setName("张三");student.setAge(20);student.setBirthday(getDate()); //转化毫秒值//不赋值//student.setEmail("zs@sina.com");//不赋值//student.setFlag(true);String jsonString1 = JSON.toJSONString(student);System.out.println(jsonString1);//{"age":20,"birthday":1662544849121,"id":1,"name":"张三"}//方法的参数上,添加枚举类型String jsonString2 = JSON.toJSONString(student,SerializerFeature.WriteDateUseDateFormat);System.out.println(jsonString2);//{"age":20,"birthday":"2022-09-07 18:00:49","id":1,"name":"张三"}//方法的参数上,添加枚举类型 可以加俩String jsonString3 = JSON.toJSONString(student,SerializerFeature.WriteDateUseDateFormat,SerializerFeature.PrettyFormat);System.out.println(jsonString3);/*** {* "age":20,* "birthday":"2022-09-07 18:00:49",* "id":1,* "name":"张三"* }*/}
@JSONField注解,该注解作用于方法上字段上和参数上可在序列化和反序列化时进行特性功能定制,注解可以放在方法上、成员变量上、方法的参数上。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.alibaba.fastjson.annotation;import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
public @interface JSONField {int ordinal() default 0;String name() default "";String format() default "";boolean serialize() default true;boolean deserialize() default true;SerializerFeature[] serialzeFeatures() default {};Feature[] parseFeatures() default {};String label() default "";boolean jsonDirect() default false;Class> serializeUsing() default Void.class;Class> deserializeUsing() default Void.class;String[] alternateNames() default {};boolean unwrapped() default false;String defaultValue() default "";
}
package com.test.json.pojo;import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;import java.util.Date;@Data
public class Student_JsonField {//@JSONField 注解属性: name 指定序列化后的名字
//@JSONField 注解属性:ordinal 序列化后的顺序,属性值越小,顺序靠前
//@JSONField 注解属性:format 序列化后的格式
//@JSONField 注解属性:serialize 是否序列化该字段
//@JSONField 注解属性:deserialize 是否反序列化该字段
//@JSONField 注解属性:serialzeFeatures 序列化时的特性定义,和常量一致private Integer id;@JSONField(name = "studentName",ordinal = 1)private String name;@JSONField(ordinal = 2)private Integer age;//@JSONField 注解属性:serialize 是否序列化该字段@JSONField(serialize = false)private String email;//@JSONField 注解属性:format 指定序列化后的格式@JSONField(format = "YYYY-MM-dd HH:mm:ss")private Date birthday;private Boolean flag;
}
import com.alibaba.fastjson.JSON;
import com.test.json.pojo.Student_JsonField;
import org.junit.Test;import java.util.Date;/*** @JSonField 注解* 该注解作用于方法上,字段上和方法的参数上。可在序列化和反序列化时进行特性功能定制*/public class TestFastJson3_JsonField {public Date getDate(){Date date = new Date();return date;}@Testpublic void testObjectToJson(){/*** @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})* public @interface JSONField {* int ordinal() default 0;* 注意看一下源代码*/Student_JsonField student = new Student_JsonField();student.setId(1);student.setName("张三");student.setAge(20);student.setBirthday(getDate()); //转化毫秒值student.setEmail("zs@sina.com");String jsonString = JSON.toJSONString(student);System.out.println(jsonString);// {"age":20,"birthday":1662565074308,"email":"zs@sina.com","id":1,"name":"张三"}//加完注解后 name// {"age":20,"birthday":1662565946059,"email":"zs@sina.com","id":1,"studentName":"张三"}//加完注解 ordinal//{"birthday":1662565915298,"email":"zs@sina.com","id":1,"studentName":"张三","age":20}//加完注解 format// {"birthday":"2022-09-07 23:54:03","email":"zs@sina.com","id":1,"studentName":"张三","age":20}//加完注解 serialize = false//{"birthday":"2022-09-07 23:55:21","id":1,"studentName":"张三","age":20}}
}
@JSONType该注解作用于类上对该类的字段进行序列化和反序列化的特性功能定制,该注解作用在类上。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.alibaba.fastjson.annotation;import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface JSONType {boolean asm() default true;String[] orders() default {};String[] includes() default {};String[] ignores() default {};SerializerFeature[] serialzeFeatures() default {};Feature[] parseFeatures() default {};boolean alphabetic() default true;Class> mappingTo() default Void.class;Class> builder() default Void.class;String typeName() default "";String typeKey() default "";Class>[] seeAlso() default {};Class> serializer() default Void.class;Class> deserializer() default Void.class;boolean serializeEnumAsJavaBean() default false;PropertyNamingStrategy naming() default PropertyNamingStrategy.CamelCase;Class extends SerializeFilter>[] serialzeFilters() default {};
}
package com.test.json.pojo;import com.alibaba.fastjson.annotation.JSONType;
import lombok.Data;@Data
// 注解属性 includes 要被序列化的字段
// 注解属性 orders 序列化后的顺序
// 注解属性:serialzeFeatures 序列化时的特性定义和常数一致
@JSONType(includes = {"id","name","age","address"},orders = {"name","age","id","address"})
public class Student_JsonType {private int id;private String name;private int age;private String address;
}
import com.alibaba.fastjson.JSON;
import com.test.json.pojo.Student_JsonType;
import org.junit.Test;/*** @JSONType 注解* 该注解作用于类上,对该类的字段进行序列化和反序列化时的特性功能定制*/
public class TestFastJson4_JsonType {@Testpublic void test(){Student_JsonType student = new Student_JsonType();student.setId(1);student.setAddress("北京市");student.setName("张三");student.setAge(22);String jsonString = JSON.toJSONString(student);System.out.println(jsonString);//{"address":"北京市","age":22,"id":1,"name":"张三"}//如果去掉一个 @JSONType(includes = {"id","name","address"})// {"address":"北京市","id":1,"name":"张三"}/*** package com.test.json.fastjson.pojo;** import com.alibaba.fastjson.annotation.JSONField;* import com.alibaba.fastjson.annotation.JSONType;* import lombok.Data;** @Data* // 注解的属性 includes 要被序列化的字段* @JSONType(includes = {"id","name","address"})* public class Person {** private int id;** private String name;** @JSONField(serialize = true) 不管用* private int age;** private String address;* }*///{"address":"北京市","id":1,"name":"张三"}//添加orders// @JSONType(includes = {"id","name","age","address"},orders = {"name","age","id","address"})//{"name":"张三","age":22,"id":1,"address":"北京市"}}
}
Jackson是用来序列化和反序列化 json 的 Java 的开源框架。Spring MVC 的默认 json 解析器便是 Jackson。与其他 Java 的 json 框架 Gson 等相比, Jackson 解析大的 json 文件速度比较快;Jackson 运行时占用内存比较低,性能比较好;Jackson 有灵活的 API,可以很容易进行扩展和定制。

com.fasterxml.jackson.core jackson-databind 2.10.1
com.fasterxml.jackson.datatype jackson-datatype-jsr310 2.10.1
package com.test.json.fastjson;import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;import java.time.LocalDateTime;
import java.util.Date;@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserS{/*** 用户id*/private Long id;/*** 用户姓名*/private String name;/*** 密码*/private String pwd;/*** 网站名1*/private String websiteUrl;/*** 注册日期*/private Date registerDate;/*** 生日*/private LocalDateTime birthday;/*** 地址*/private String addr;}
package com.test.json.jackson;import lombok.Data;@Data
public class ResultDTO {private Boolean success = Boolean.TRUE;private T data;private ResultDTO(){}public static ResultDTO buildSuccess(T t){ResultDTO resultDTO = new ResultDTO<>();resultDTO.setData(t);return resultDTO;}}
//序列化private static ObjectMapper objectMapper = new ObjectMapper();static {/*** 序列化配置*///全局配置: 配置序列化时只包含非空属性objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);}/*** 序列化* 把bean转化成json字符串*/@Testpublic void test1() throws JsonProcessingException {UserS user = new UserS();user.setId(1L);user.setName("张三");//user.setPwd("123");user.setAddr("河南");user.setWebsiteUrl("http://www.baidu.com");user.setRegisterDate(new Date());user.setBirthday(LocalDateTime.now());String string = objectMapper.writeValueAsString(user);System.out.println(string);}
@Data
@JsonInclude(JsonInclude.Include.NON_NULL) //类加上标签
public class UserS{...
}
{"id":1,"name":"张三","websiteUrl":"http://www.baidu.com","registerDate":1661844024802,"birthday":{"month":"AUGUST","year":2022,"dayOfMonth":30,"hour":15,"minute":20,"monthValue":8,"nano":857000000,"second":24,"dayOfWeek":"TUESDAY","dayOfYear":242,"chronology":{"id":"ISO","calendarType":"iso8601"}},"addr":"河南"}
static {/*** 全局的配置*///自动通过spi发现jackson的module并注册objectMapper.findAndRegisterModules();}
/*** 注册日期*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")private Date registerDate;
{"id":1,"name":"张三","websiteUrl":"http://www.baidu.com","registerDate":"2022-08-30 15:42:10","birthday":"2022-08-30 15:42:10","addr":"河南"}
static {//美化输出objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
}
{"id" : 1,"name" : "张三","websiteUrl" : "http://www.baidu.com","registerDate" : "2022-08-30 16:13:48","birthday" : "2022-08-30 16:13:48","addr" : "河南"
}
FastJson对于json中多的key默认的处理就是忽略!!!
添加这行代码,当遇到与类多余的属性时会选择不输出
static {/*** 反序列化的配置*///objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);//两种写法等价objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
/*** 反序列化*/@Testpublic void test2() throws Exception{String str = "{\"id\":1,\"name\":\"张三\",\"websiteUrl\":\"http://www.baidu.com\",\"registerDate\":\"2022-08-30 15:42:10\",\"birthday\":\"2022-08-30 15:42:10\",\"addr\":\"河南\"}\n";UserS user = objectMapper.readValue(str, UserS.class); //属性必须与类相同 多了少了 都会报错System.out.println(user); //Ctrl + Alt +V}
结果:
{"success" : true,"data" : {"name" : "张三","websiteUrl" : "http://www.baidu.com"}
}
/*** 泛型的处理*/@Testpublic void test3() throws Exception{UserS user = new UserS();user.setName("张三");user.setWebsiteUrl("http://www.baidu.com");ResultDTO userResultDTO = ResultDTO.buildSuccess(user);String dtoSerializationResult = objectMapper.writeValueAsString(userResultDTO);System.out.println(dtoSerializationResult);//反序列化为ResultDTOResultDTO dataResult = objectMapper.readValue(dtoSerializationResult, new TypeReference>() {});System.out.println("dataResult:"+dataResult);System.out.println("data:"+dataResult.getData());}
结果:
{"success" : true,"data" : {"name" : "张三","websiteUrl" : "http://www.baidu.com"}
}
dataResult:ResultDTO(success=true, data=User(id=null, name=张三, pwd=null, websiteUrl=http://www.baidu.com, registerDate=null, birthday=null, addr=null))
data:User(id=null, name=张三, pwd=null, websiteUrl=http://www.baidu.com, registerDate=null, birthday=null, addr=null)
static { //驼峰命名法 转下划线objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
}
/*** 地址*/@JsonProperty("address")private String addr;
{"id" : 1,"name" : "张三","pwd" : "123","website_url" : "http://www.baidu.com","register_date" : "2022-08-30 16:53:56","birthday" : "2022-08-30 16:53:56","address" : "河南"
}
/*** 密码*/@JsonIgnoreprivate String pwd;
{"id" : 1,"name" : "张三","website_url" : "http://www.baidu.com","register_date" : "2022-08-30 16:52:08","birthday" : "2022-08-30 16:52:08","address" : "河南"
}
/*** 对象更新,对象合并,如果后者属性有值,则用后者,否则前者的值不变*/@Testpublic void test4() throws Exception {UserS orginalUser = new UserS();orginalUser.setId(2L);orginalUser.setName("张三");orginalUser.setWebsiteUrl("www.baidu.com");UserS newUser = new UserS();newUser.setId(3L);newUser.setWebsiteUrl("www.google.com");//让我们省去了很多判断UserS updateUser = objectMapper.updateValue(orginalUser, newUser);//id:2 name:张三 java websiteUrl:http:google.comSystem.out.println(updateUser);}
结果:
UserS(id=3, name=张三, pwd=null, websiteUrl=www.google.com, registerDate=null, birthday=null, addr=null)
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.test.json.jackson.ResultDTO;
import com.test.json.jackson.UserS;
import org.junit.Test;import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;public class JacksonTest {//序列化private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";private static ObjectMapper objectMapper = new ObjectMapper();static {/*** 序列化配置*///全局配置: 配置序列化时只包含非空属性objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);//美化输出objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);/*** 反序列化的配置*///objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);//两种写法等价objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);/*** 通用的配置*///对Date进行配置,SimpleDateFormat是线程不安全的objectMapper.setDateFormat(new SimpleDateFormat(DATE_TIME_FORMAT));//自动通过spi发现jackson的module并注册//objectMapper.findAndRegisterModules(); //注释了 就可以用下面手动配置JavaModule//手动配置JavaTimeModule并注册JavaTimeModule javaTimeModule = new JavaTimeModule();//序列化javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));//反序列化javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));//注册:objectMapper.registerModule(javaTimeModule);//驼峰命名法 转下划线objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);}/*** 序列化* 把bean转化成json字符串*/@Testpublic void test1() throws JsonProcessingException {UserS user = new UserS();user.setId(1L);user.setName("张三");user.setPwd("123");user.setAddr("河南");user.setWebsiteUrl("http://www.baidu.com");user.setRegisterDate(new Date());user.setBirthday(LocalDateTime.now());String string = objectMapper.writeValueAsString(user);System.out.println(string);}/*** 反序列化*/@Testpublic void test2() throws Exception {String str = "{\"id\":1,\"name\":\"张三\",\"websiteUrl\":\"http://www.baidu.com\",\"registerDate\":\"2022-08-30 15:42:10\",\"birthday\":\"2022-08-30 15:42:10\",\"addr\":\"河南\"}\n";UserS user = objectMapper.readValue(str, UserS.class); //属性必须与类相同 多了少了 都会报错System.out.println(user); //Ctrl + Alt +V}/*** 泛型的处理*/@Testpublic void test3() throws Exception {UserS user = new UserS();user.setName("张三");user.setWebsiteUrl("http://www.baidu.com");ResultDTO userResultDTO = ResultDTO.buildSuccess(user);String dtoSerializationResult = objectMapper.writeValueAsString(userResultDTO);System.out.println(dtoSerializationResult);//反序列化为ResultDTOResultDTO dataResult = objectMapper.readValue(dtoSerializationResult, new TypeReference>() {});System.out.println("dataResult:" + dataResult);System.out.println("data:" + dataResult.getData());}/*** 对象更新,对象合并,如果后者属性有值,则用后者,否则前者的值不变*/@Testpublic void test4() throws Exception {UserS orginalUser = new UserS();orginalUser.setId(2L);orginalUser.setName("张三");orginalUser.setWebsiteUrl("www.baidu.com");UserS newUser = new UserS();newUser.setId(3L);newUser.setWebsiteUrl("www.google.com");//让我们省去了很多判断UserS updateUser = objectMapper.updateValue(orginalUser, newUser);//id:2 name:张三 java websiteUrl:http:google.comSystem.out.println(updateUser);}
}