如果不了解JSON格式,建议先看下:JSON数据格式【学习记录】
JSON序列化、反序列化JavaBean的框架有很多,最常见的Jackson、阿里巴巴开源的FastJson、谷歌的GSON、apache提供的json-lib等,下面我们主要来熟悉一下:Java语言中FastJson的使用。
FastJson
FastJson是由阿里巴巴工程师基于Java开发的一款Json解析器和生成器,可用于将Java对象转换为其JSON表示形式,它还可以用于将JSON字符串转换为等效的Java对象。FastJson可以处理任意Java对象,包括没有源代码的预先存在的对象。
FastJson使用十分简便,我们只需要在Maven工程的pom文件中引入以下依赖即可:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
FastJson API的入口是com.alibaba.fastjson.JSON
,常用的序列化操作都可以在JSON类上的静态方法直接完成。
API测试
我们已经在项目中引入了FastJson的依赖,我们再创建一个用户类用于测试:
package com.test.json;
@Data
public class User {
private Integer id;
private String name;
private String sex;
private Integer age;
}
一、序列化
序列化就是将JavaBean序列化为JSON字符串,下面我们来看下FastJson常见的序列化方法。
下面序列化相关方法都有统一的返回值类型String。
1)toJsonString(Object o);
public static void main(String[] args) {
User user = User.builder().id(1).name("张三").sex("男").age(23).build();
System.out.println(JSON.toJSONString(user));
}
{"age":23,"id":1,"name":"张三","sex":"男"}
我们通过传入一个对象,便可以将对象转成JSON字符串,这里我们传入的不仅仅是JavaBean还可以是一个Map对象,传入Map对象我们同样也可以取到一个JSON字符串。
public static void main(String[] args) {
Map<String, Object> userMap = new HashMap<>();
userMap.put("id", 1);
userMap.put("name", "张三");
userMap.put("sex", "男");
userMap.put("age", 23);
System.out.println(JSON.toJSONString(userMap));
}
{"age":23,"id":1,"name":"张三","sex":"男"}
List对象也很适用,结果是一个标准的JSONArray的字符串。
public static void main(String[] args) {
User zhangsan = User.build().id(1).name("张三").sex("男").age(23).build();
User lisi = User.build().id(2).name("李四").sex("女").age(18).build();
List<User> userList = new ArrayList<>();
userList.add(zhangsan);
userList.add(lisi);
System.out.println(JSON.toJSONString(userList));
}
[{"id":1,"name":"张三","sex":"男","age":23},{"id":2,"name":"李四","sex":"女","age":18},]
2)toJSONString(Object o, boolean prettyFormat);
如果说 toJSONString(Object o);
的输出结果只有单调的一行让你看起来有点吃力,那么我们可以使用 toJSONString(Object o, boolean prettyFormat);
来让输出结果看起来舒服点。
public static void main(String[] args) {
User user = User.builder().id(1).name("张三").sex("男").age(23).build();
System.out.println(JSON.toJSONString(user, true));
}
{
"age":23,
"id":1,
"name":"张三",
"sex":"男"
}
通过JSON自带的格式化,让输出结果看起来更加清晰,真是贴心~
3)JSON.toJSONString(Object object, SerializerFeature… features);
我们可以看到这个方法里面有个参数SerializerFeature...
,可能感到有点陌生,我们先来看下什么是 SerializerFeature
,通过源码可以发现 SerializerFeature
原来是个枚举类:
源码中都被 @deprecated
注释的实例说明已经废弃了,那有哪些是我们平时经常用到的呢:
对象 | 描述 |
---|---|
SerializerFeature.UseSingleQuotes | 使用单引号而不是双引号,默认为false |
SerializerFeature.PrettyFormat | 结果是否格式化,默认为false |
SerializerFeature.WriteDateUseDateFormat | 如果时间是date、时间戳类型,按照这种格式"yyyy-MM-dd HH:mm"初始化时间 |
SerializerFeature.WriteMapNullValue | 是否输出值为null的字段,默认为false |
SerializerFeature.WriteClassName | 序列化时写入类型信息,默认为false |
使用案例:
SerializerFeature.UseSingleQuotes
使用单引号而不是使用双引号,默认为false。
public static void main(String[] args) {
User user = User.builder().id(1).name("张三").sex("男").age(23).build();
System.out.println(JSON.toJSONString(user, SerializerFeature.UseSingleQuotes));
}
{'age':23,'id':1,'name':'张三','sex':'男'}
SerializerFeature.PrettyFormat
结果是否格式化,默认为false。
public static void main(String[] args) {
User user = User.builder().id(1).name("张三").sex("男").age(23).build();
System.out.println(JSON.toJSONString(user));
System.out.println("===============");
System.out.println(JSON.toJSONString(user, SerializerFeature.PrettyFormat));
}
{"age":23,"id":1,"name":"张三","sex":"男"}
===============
{
"age":23,
"id":1,
"name":"张三",
"sex":"男"
}
SerializerFeature.WriteDateUseDateFormat
如果时间是Date、时间戳类型,按照这种格式初始化时间"yyyy-MM-dd HH:mm"。
public static void main(String[] args) {
System.out.println(JSON.toJSONString(new Date()));
System.out.println("===============");
System.out.println(JSON.toJSONString(new Date(), SerializerFeature.WriteDateUseDateFormat));
}
1676427576691
===============
"2023-02-15 10:19:37"
通过这种方式我们将日期输出成了固定的格式:yyyy-MM-dd HH:mm,有时候我们不想得到这种格式那该怎么办?通过下面方法支持自定义时间格式:(注意方法不要用错)
4)toJSONStringWithDateFormat(Object object, String dateFormat, SerializerFeature… features);
public static void main(String[] args) {
System.out.println(JSON.toJSONString(new Date()));
System.out.println("===============");
System.out.println(JSON.toJSONStringWithDateFormat(new Date(), "HH:mm:ss"));
}
1676428350771
===============
"10:32:30"
下面我们接着看SerializerFeature枚举类的其他用法。
SerializerFeature.WriteMapNullValue
是否输出值为null的字段,默认为false。
这个有什么用处呢?我们应该很清楚开发规范中鼓励用JavaBean传递参数,尽量减少Map传递参数,因为Map相当于一个黑盒,对于使用者来说根本不知道里面存在哪些字段,而对于创建者来说估计也时常会忘记里面存在哪些字段,为了解决这个痛,JSON也推出了解决方法:
public static void main(String[] args) {
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("name", null);
dataMap.put("age", 23);
System.out.println(JSON.toJSONString(dataMap));
System.out.println("===============");
System.out.println(JSON.toJSONString(dataMap, SerializerFeature.WriteMapNullValue));
}
{"age":23}
===============
{"name":null,"age":23}
通过普通方式的 toJSONString()
方法,空值仿佛被吃掉了,这很可能会成为一个开发灾难!
SerializerFeature.WriteClassName
序列化时写入类信息,默认为false。这个方法可以在反序列化的时候用到,用法如下:
public static void main(String[] args) {
User user = User.builder().id(1).name("张三").sex("男").age(23).build();
System.out.println(JSON.toJSONString(user, SerializerFeature.WriteClssName));
}
{"@type":"com.test.json.User","age":23,"id":1,"name":"张三","sex":"男"}
通过这样我们可以看到我们序列化的对象是什么类型的。
上面这些便是toJSONString的扩展用法,上面说到的是序列化,那么对应的便是反序列化。
二、反序列化
反序列化就是把JSON格式的字符串转换为JavaBean对象。
1)JSONObject parseObject(String text);
public static void main(String[] args){
String jsonStr = "{'age':23,'id':1,'name':'张三','sex':'男'}";
JSONObject jsonObject = JSON.parseObject(jsonStr);
System.out.println(jsonObject.get("name"));
}
张三
用法十分简单,可以将一个标准的JSON字符串转为一个JSONObject对象,由于JSONObject类实现了Map接口,因此我们可以通过get()来获取到值。
我们上述已经说过Map的致命不足,所以我们更希望能得到一个JavaBean对象。
2)<T> T parseObject(String text, Class<T> clazz);
我们通过传入我们想要转换的对象类型,就可以得到我们想要的JavaBean。
public static void main(String[] args){
String jsonStr = "{'age':23,'id':1,'name':'张三','sex':'男'}";
User user = JSON.parseObject(jsonStr, User.class);
System.out.println(user.getName());
}
张三
//后续待更新…