java操作json
一、简介
json : JavaScript Object Notation,JS 对象简谱。
官网: https://www.json.org/json-zh.html
二、使用场景
-
网络传输
描述同样的信息,json相比xml占用更少的空间,如:
<?xml version="1.0" encoding="UTF-8"?> <person> <id>1</id> <name>张三</name> <age>30</age> </person>
json表示:
{ "id":1, "name":"张三", "age":30 }
-
序列化存储
三、java里面操作json有哪些技术?
-
所谓的操作
把java里面的bean、map、collection等转为json字符串(序列化)或反向操作(反序列化)。
-
java里操作json的技术一览
四、fastjson
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
4.1 序列化(Bean->Json字符串)
JSON.toJSONString()
:转为JSON字符串
包含null
SerializerFeature.WriteMapNullValue
:指定序列化时包含null
String string = JSON.toJSONString(person, SerializerFeature.WriteMapNullValue);
日期时间格式化
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
指定日期格式
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date registerDate;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime birthDay;
奇怪的"$ref "引用探测
$ref:对象中多次引用了同一个其他对象的时候,序列化就会出现$ref
可以通过SerializerFeature.DisableCircularReferenceDetect
禁用引用探测功能
/**
* 测试fastjson的引用探测
* $ref:对象中多次引用了同一个其他对象的时候,序列化就会出现$ref
*/
@Test
public void test$Ref(){
List<Person> list = new ArrayList<>();
Person person = new Person();
person.setId(33L);
person.setName("乐之者java");
list.add(person);
list.add(person);
list.add(person);
// DisableCircularReferenceDetect 禁用引用探测功能
String string = JSON.toJSONString(list,SerializerFeature.DisableCircularReferenceDetect);
System.out.println(string);
}
SerializeFilter定制处理
对属性或属性值在序列化前做定制化处理
/**
* SerializeFilter定制处理.要求:
* 输出的json字符串的key是大写的、驼峰转下划线
*/
@Test
public void testSerializeFilter(){
Person person = new Person();
person.setId(1L);
// person.setName("乐之者java");
person.setPwd("123");
person.setAddr("河南");
person.setWebsiteUrl("http://www.roadjava.com");
person.setRegisterDate(new Date());
person.setBirthDay(LocalDateTime.now());
/*
object: person对象
name:属性
value: name属性对应的值
*/
NameFilter nameFilter = (object,name, value) -> name.toUpperCase();
String string = JSON.toJSONString(person,nameFilter);
System.out.println(string);
}
美化输出
将第二个参数设为true
建议:在网络传输中最好不要进行美化输出
4.2 反序列化(Json字符串->Bean)
-
泛型处理
fastjson对于json中多的key默认的处理就是忽略
后端向前端返回json数据,设置统一返回结果
@Data
public class ResultVO<T> {
private Boolean success = Boolean.TRUE;
private T data;
private ResultVO(){}
public static <T> ResultVO<T> buildSuccess(T t) {
ResultVO<T> resultVO = new ResultVO<>();
resultVO.setData(t);
return resultVO;
}
}
测试反序列化
反序列化后不能够获取到泛型类型
/**
* 测试反序列化
* json字符串-->bean
*/
@Test
public void testDeSerialize(){
String jsonStr = "{\"address\":\"河南\",\"birthDay\":\"2021-08-17 03:38:09\",\"id\":1,\"name\":null,\"pwd\":\"123\",\"registerDate\":\"2021-08-17 03:38:09\",\"websiteUrl\":\"http://www.roadjava.com\"}";
// 反序列化为person对象
Person person = JSON.parseObject(jsonStr, Person.class);
System.out.println(person);
// 返回给调用端ResultVO
ResultVO<Person> personResultVO = ResultVO.buildSuccess(person);
String voJsonStr = JSON.toJSONString(personResultVO);
// 调用端需要把voJsonStr反序列化为对象
// 反序列化后不能够获取到泛型类型
// ResultVO resultVO = JSON.parseObject(voJsonStr, ResultVO.class);
// System.out.println("resultVO"+resultVO);
// Object data = resultVO.getData();
// 需要反序列化为什么类型,就给TypeReference传入什么类型即可
ResultVO<Person> deSerializedVo = JSON.parseObject(voJsonStr, new TypeReference<ResultVO<Person>>() {});
System.out.println("deSerializedVo:"+deSerializedVo);
Person data = deSerializedVo.getData();
System.out.println("data:"+data);
}
4.3 通用配置
指定属性名和json字符串key的对应关系
/**
* 地址
* name = "address":指定属性名和json字符串key的对应关系 addr---address
*/
@JSONField(name = "address")
private String addr;
反序列化时传入的是addr,在已经通过配置了@JSONField(name = "address")
的情况下,是不能对该属性进行反序列化的,只能将其改为address才能对该属性进行反序列化
忽略指定属性
例如不想将密码返回给前端
@JSONField(serialize = false,deserialize = false)
private String pwd;
五、jackson
Springmvc默认使用jackson
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.1</version>
</dependency>
<!--对LocalDateTime等jdk8时间日期api的转化支持-->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.10.1</version>
</dependency>
5.1 序列化
- 只包含非null属性
- 全局配置
- 单个的bean配置
- 日期时间格式化
- 全局配置
- 单个bean的配置
- 美化输出
5.2 反序列化
- 忽略不存在的key
- 泛型处理
5.3 通用配置
- 序列化: 驼峰转下划线/反序列化:下划线转驼峰
- 指定属性名和json字符串key的对应关系
- 忽略指定属性
5.4 其他应用
- 对象更新