Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。目前Java中常见的JSON处理框架分别是Gson、Jackson、Fastjson,Fastjson作为一个国产框架,被国人广泛认可,“快”是其主要的卖点,大约比Jackson快20%左右,转换效率排名为 fastjson -> jackson -> gson, 今天我们就来对fastjson进行一个快速入门和深入了解。
Maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.66</version>
</dependency>
Fastjson主要是用来对json格式数据的解析使用,是一种高效遍历切功能强大的类库,日常使用主要是Java对象的序列化和反序列化,还有各种灵活的API支持我们获取JSONObject对象中的数据;
1、序列化 (将Java对象转成JSON格式的字符串)
JSONObject jsonObj = new JSONObject();
JSONArray jsonArr = new JSONArray();
jsonObj.put("test","test");
jsonObj.put("123", null);
jsonArr.add(jsonObj);
System.out.println(JSONObject.toJSONString(jsonObj));
System.out.println(JSONArray.toJSONString(jsonArr));
打印结果:
{"test":"test"}
[{"test":"test"}]
总结: fastjson常用的格式有2个,分别是JSONObject和JSONArray,大家可以理解为JSONObject对应java的Map格式,JSONArray对应java的ArrayList格式,实际工作中我们也是依据这两个对象来对数据进行操作。
PS:在以上示例里面的JSONObject.toJSONString()方法,通常我们的看到这个API我们都会认为里面只能放JSONObjec对象,而JSONArray.toJSONString()只能放JSONArray对象,但是实际上查看源码,我们就能够发现JSONObject和JSONArray使用的toJSONString方法其实都是继承的同一个父类,JSON类的toJSONString方法,所以在我们 实际使用上JSONObjec.toJSONString()和JSONArray.toJSONString()对同一对象的打印都是相同的,且并不限制其入参类型(对象和数组)
2、反序列化(将JSON格式字符串转成java对象)
// JSON字符串转JSONObject对象
JSONObject.parseObject(JSON.toJSONString(jsonObj));
// JSON字符串转JSONArray对象
JSONArray.parseArray(JSON.toJSONString(jsonArr));
// JSON字符串根据传入Class类型转成对应对象
JSONObject.parseObject(JSON.toJSONString(jsonObj), JSONObject.class);
// JSON字符串根据传入Class类型转成对应对象的集合
JSONArray.parseArray(JSON.toJSONString(jsonArr), JSONObject.class);
// JSONObject和JSONArray父类的转换方法
JSON.parseObject(JSON.toJSONString(jsonObj));
JSON.parseArray(JSON.toJSONString(jsonArr));
JSON.parseObject(JSON.toJSONString(jsonObj), JSONObject.class);
JSON.parseArray(JSON.toJSONString(jsonArr), JSONObject.class);
// 实际上我们也可以直接通过JSON.parse() API直接转换Object、Array、String,出参类型是Object,后续使用时需要转换
JSON.parse(JSON.toJSONString(jsonObj))
PS: JSON.toJSONString(jsonObj)和JSON.toJSONString(jsonArr) 只是演示,你可以理解为第一个入参是JSON格式的字符串,可别每个都加… JSONObject.class也可以换成对应转换的VO类,如User.class
总结: 序列化和反序列化时,实际上走的API都是父类JSON的API,所以实际使用时,我们可以直接使用JSON.toJSONString()、JSON.parseArray()等,效果是一样的
3、获取数据
// 获取JSONObject对象中Val属的类型值(值类型为String)
String stringVal = jsonObj.getString("Val");
// 获取JSONObject对象中Val属的类型值(值类型为JSONObject)
JSONObject jsonObject = jsonObj.getJSONObject("Val");
// 获取JSONObject对象中Val属的类型值(值类型为JSONArray)
JSONArray jsonArray = jsonObj.getJSONArray("Val");
// 获取JSONObject对象中Val属的类型值(值类型为Byte、byte)
Byte byteVal = jsonObj.getByte("Val");
byte byteValue = jsonObj.getByteValue("Val");
// 获取JSONObject对象中Val属的类型值(值类型为Short、short)
Short shortVal = jsonObj.getShort("Val");
short shortValue = jsonObj.getShortValue("Val");
// 获取JSONObject对象中Val属的类型值(值类型为Integer、int )
Integer integer = jsonObj.getInteger("Val");
int intValue = jsonObj.getIntValue("Val");
// 获取JSONObject对象中Val属的类型值(值类型为Long、long)-
Long longVal = jsonObj.getLong("Val");
long longValue = jsonObj.getLongValue("Val");
// 获取JSONObject对象中Val属的类型值(值类型为Float、float)
Float floatVal = jsonObj.getFloat("Val");
float floatValue = jsonObj.getFloatValue("Val");
// 获取JSONObject对象中Val属的类型值(值类型为Double、double)
Double doubleVal = jsonObj.getDouble("Val");
double doubleValue = jsonObj.getDoubleValue("Val");
PS:这些API可以方便快捷直接获取对应格式的数据,不需要对齐进行转换,避免重复写无意义的代码
4、删除数据
jsonObj.remove("test"); // 单独删除某个key的值
jsonObj.clear(); // 全部删除
jsonObj.remove("test", "test"); // 单独删除某个key的值,如果删除成功则返回true,如果删除失败则返回false(不存在对应key的值)
5、过滤字段
SimplePropertyPreFilter filter = new SimplePropertyPreFilter(JSONObject.class, "bookName", "price");
filter.getIncludes().add("type"); // 展示白名单(展示字段)
filter.getExcludes().add("price"); // 展示黑名单(排除字段) // PS:排除优先级最高
System.out.println(JSON.toJSONString(jsonObj, filter));
例:
JSONObject user = new JSONObject();
user.put("name", "xiaoming");
user.put("age", "18");
SimplePropertyPreFilter filter = new SimplePropertyPreFilter(JSONObject.class, "name", "name");
filter.getIncludes().add("name"); // 展示白名单(展示字段)
filter.getExcludes().add("age"); // 展示黑名单(排除字段) // PS:排除优先级最高
System.out.println(JSON.toJSONString(user, filter));
打印结果
{"name":"xiaoming"}
6、注解
@JSONField
// 配置在字段和方法上即可生效 // 若属性是私有的,必须有set*方法。否则无法反序列化。
// 功能: 标注序列表字段,并可更改该字段序列化后的名称、顺序、格式等
public @interface JSONField {
int ordinal() default 0; // 配置序列化和反序列化的顺序,1.1.42版本之后才⽀持
String name() default ""; // 指定字段的名称 PS: 不能为中文
String format() default ""; // 指定字段的格式,主要用于日期格式化
boolean serialize() default true; // 是否序列化
boolean deserialize() default true; // 是否反序列化
}
@JSONType(ignores = {“name”})
// 功能:类级别注解 ,标注字段,主要用于决定确定哪些字段要序列化,哪些字段不许序列化
public @interface JSONType {
boolean asm() default true;
String[] orders() default {};
String[] ignores() default {}; // 序列化字段对象
String[] includes() default {}; // 非序列化字段对象 (优先级高于ignores)
}
@JSONCreator
// 方法级别注解,用来指定构造方法来创建Java对象
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface JSONCreator {
// 仅用于标注,没有逻辑属性、字段
}
7、不常用的特性
String objJson = JSON.toJSONString(Object object, SerializerFeature... features)
例1: JSON.toJSONString(new Date(), SerializerFeature.WriteDateUseDateFormat);
// 获得: "2021-02-23 17:00:04"
例2: JSON.toJSONString(jsonArr, SerializerFeature.UseSingleQuotes);
// 获得: [{'price':'233','type':'notepad','bookName':'myNotepad'}]
例3: JSON.toJSONStringWithDateFormat(new Date(), "yyyy-MM-dd HH:mm:ss")
// 获得: "2021-02-23 17:00:04"
例4: JSON.toJSONString(bean,new PascalNameFilter());
// jsonBean的key首字母大写
例5: JSON.toJSONString(list, SerializerFeature.PrettyFormat);
/* 获得: [ { "price":"233", "type":"notepad", "bookName":"myNotepad" } ]*/
例6: JSON.toJSONString(map, SerializerFeature.WriteMapNullValue);
// {"123":null,"price":"233","type":"notepad","bookName":"myNotepad"} fastjson默认过滤value为null的key,此写法则不过滤
例7: static{ TypeUtils.compatibleWithJavaBean = true; }
// fastjson默认将javaBean对象的属性都以驼峰形式命名(首字母小写),设置则不走默认逻辑
SerializerFeature属性介绍
名称 | 含义 |
---|---|
QuoteFieldNames | 输出key时是否使用双引号,默认为true |
UseSingleQuotes | 使用单引号而不是双引号,默认为false |
WriteMapNullValue | 是否输出值为null的字段,默认为false |
WriteEnumUsingToString | Enum输出name()或者original,默认为false |
UseISO8601DateFormat | Date使用ISO8601格式输出,默认为false |
WriteNullListAsEmpty | List字段如果为null,输出为[],而非null |
WriteNullStringAsEmpty | 字符类型字段如果为null,输出为”“,而非null |
WriteNullNumberAsZero | 数值字段如果为null,输出为0,而非null |
WriteNullBooleanAsFalse | Boolean字段如果为null,输出为false,而非null |
SkipTransientField | 如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true |
SortField | 按字段名称排序后输出。默认为false |
WriteTabAsSpecial | 把\t做转义输出,默认为false |
PrettyFormat | 结果是否格式化,默认为false |
WriteClassName | 序列化时写入类型信息,默认为false。反序列化是需用到 |
DisableCircularReferenceDetect | 消除对同一对象循环引用的问题,默认为false |
WriteSlashAsSpecial | 对斜杠’/’进行转义 |
BrowserCompatible | 将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false |
WriteDateUseDateFormat | 全局修改日期格式,默认为false。JSON.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat); |
DisableCheckSpecialChar | 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false |
NotWriteRootClassName | 含义 |
BeanToArray | 将对象转为array输出 |
WriteNonStringKeyAsString | 含义 |
NotWriteDefaultValue | 含义 |
BrowserSecure | 含义 |
IgnoreNonFieldGetter | 含义 |
WriteEnumUsingName | 含义 |
8、总结 fastjson真的是一个简单易用的类库!以上知识我们只需要掌握常用的就行了,其他的我们只要了解一下即可,因为很难保证后续不会有各种各样的“需求”能够让这些API派上用上~