当前位置:   article > 正文

FastJson 框架详解

fastjson

1. Fastjson的官方地址

Fastjson: 地址

Springboot 自带的json解析框架是jackson,如果要想使用fastjson的话,可以采用以下的两种方式:

方式一:用bean替代默认解析器(推荐)

注意的是:这里的bean并不是将原来的jackson给直接替换掉,而是springboot会采用我们设置的更高优先级的fastjson来解析。

  1. @Configuration
  2. public class WebConfig {
  3. @Bean
  4. public HttpMessageConverters fastJsonMessageConverters() {
  5. List<HttpMessageConverter<?>> converters = new ArrayList<>();
  6. //需要定义一个convert转换消息的对象;
  7. FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
  8. //添加fastJson的配置信息;
  9. FastJsonConfig fastJsonConfig = new FastJsonConfig();
  10. fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
  11. //全局时间配置
  12. fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
  13. //在convert中添加配置信息.
  14. fastConverter.setFastJsonConfig(fastJsonConfig);
  15. converters.add(0, fastConverter);
  16. return new HttpMessageConverters(converters);
  17. }
  18. }

方式二:实现WebMvcConfigurer

  1. @Configuration
  2. public class FastjsonCon implements WebMvcConfigurer {
  3. @Override
  4. public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
  5. FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
  6. //自定义FastJson配置
  7. FastJsonConfig config = new FastJsonConfig();
  8. config.setSerializerFeatures(SerializerFeature.QuoteFieldNames,
  9. SerializerFeature.WriteEnumUsingToString,
  10. /*SerializerFeature.WriteMapNullValue,*/
  11. SerializerFeature.WriteDateUseDateFormat,
  12. SerializerFeature.DisableCircularReferenceDetect);
  13. fastJsonHttpMessageConverter.setFastJsonConfig(config);
  14. converters.add(fastJsonHttpMessageConverter);
  15. }
  16. }

2. FastJson 的三个主要类和基本 Api

FastJson 主要的三个类:JSON、JSONArray、JSONObjectJSONObject和JSONArray继承自JSON

可以发现,JSONObject代表json对象,JSONArray代表json对象数组,JSON代表JSONObject和JSONArray的转化。

FastJson API 入口类是com.alibaba.fastjson.JSON,常用的序列化操作都可以在JSON类上的静态方法直接完成。

  1. // 把JSON文本parse为JSONObject或者JSONArray
  2. public static final Object parse(String text);
  3. // 把JSON文本parse成JSONObject
  4. public static final JSONObject parseObject(String text)
  5. // 把JSON文本parse为JavaBean
  6. public static final <T> T parseObject(String text, Class<T> clazz);
  7. // 把JSON文本parse成JSONArray
  8. public static final JSONArray parseArray(String text);
  9. //把JSON文本parse成JavaBean集合
  10. public static final <T> List<T> parseArray(String text, Class<T> clazz);
  11. // 将JavaBean序列化为JSON文本
  12. public static final String toJSONString(Object object);
  13. // 将JavaBean序列化为带格式的JSON文本
  14. public static final String toJSONString(Object object, boolean prettyFormat);
  15. //将JavaBean转换为JSONObject或者JSONArray
  16. public static final Object toJSON(Object javaObject);

序列化:

String jsonString = JSON.toJSONString(obj);

反序列化:

VO vo = JSON.parseObject("...", VO.class);

泛型反序列化:

  1. import com.alibaba.fastjson.TypeReference;
  2. List<VO> list = JSON.parseObject("...", new TypeReference<List<VO>>() {});

2.1 JSON

JSON类中的方法主要是实现json对象,json对象数组,javabean对象,json字符串之间的相互转化。

1. toJSONString ()

toJSONString ()方法经过多次重载,但最终都是实现json对象转化为json字符串javabean对象转化为json字符串。其中,有关键字transient修饰的toJSONString()用于json对象序列化过程中,希望某个"键:值"对数据不变的应用中。

2. parseObject()

JSON类之parseObject()方法,实现json字符串转换为json对象或javabean对象

2.2 JSONObject

public class JSONObject extends JSON implements Map<String, Object>, Cloneable, Serializable, InvocationHandler {

JSONObject 实现了Map接口,而json对象中的数据都是以键值对形式出现,因此JSONObject底层操作是由Map实现的

JSONObject 类中主要都是get()方法,通过"键:值"对中的键来获取其对应的值,且方法的输入参数几乎皆为String类型,这是因为json对象中,"键:值"对的键都是String类型的

1. getString(String key)

  1. public String getString(String key) {
  2. Object value = this.get(key);
  3. return value == null ? null : value.toString();
  4. }

getString(String key)方法,该方法输入参数为String key(键),输出为String ,用于获取json对象中的字符串型数据。例如通过该方法获取 “name”:"bob"键值对中name这个键所对应的值bob。通过查看源码发现内部主要由Map接口中的get()方法实现。

  1. public Object get(Object key) {
  2. Object val = this.map.get(key);
  3. if (val == null && (key instanceof Number || key instanceof Boolean || key instanceof Character)) {
  4. val = this.map.get(key.toString());
  5. }
  6. return val;
  7. }

2. getInteger(String key)

  1. public Integer getInteger(String key) {
  2. Object value = this.map.get(key);
  3. if (value == null) {
  4. return null;
  5. } else if (value instanceof Integer) {
  6. return (Integer)value;
  7. } else if (value instanceof Number) {
  8. return ((Number)value).intValue();
  9. } else if (value instanceof String) {
  10. String str = (String)value;
  11. if (!str.isEmpty() && !"null".equalsIgnoreCase(str)) {
  12. return str.indexOf(46) != -1 ? (int)Double.parseDouble(str) : Integer.parseInt(str);
  13. } else {
  14. return null;
  15. }
  16. } else {
  17. throw new JSONException("Can not cast '" + value.getClass() + "' to Integer");
  18. }
  19. }

JSONObject中的getInteger(String key)该方法获取json对象中的整型数据,例如获取"age:20"键值对中age对应的整型数值20。

JSONObject中其它的get方法与上述两个方法极为相似,比较常用的有如下几个:

  1. public <T> T getObject(String key, Type type, Feature... features)
  2. public Long getLong(String key)
  3. public Float getFloat(String key)
  4. public Date getDate(String key)
  5. public java.sql.Date getSqlDate(String key)

总结:JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利用诸如size(),isEmpty()等方法获取"键:值"对的个数和判断是否为空。其本质是通过实现Map接口并调用接口中的方法完成的。

2.3 JSONArray

JSONArray 其内部是由List接口中的方法来完成操作的。

JSONArray代表json对象数组,json数组对象中存储的是一个个json对象,所以类中的方法主要用于直接操作json对象。比如这其中的add(),remove(),containsAll()方法,对应于json对象的添加,删除与判断。其内部主要有List接口中的对应方法来实现。

add():

  1. public boolean add(Object item) {
  2. return this.list.add(item);
  3. }

remove():

  1. public boolean remove(Object o) {
  2. return this.list.remove(o);
  3. }

containsAll():

  1. public boolean containsAll(Collection c) {
  2. return this.list.containsAll(c);
  3. }

listIterator():

  1. public ListIterator listIterator() {
  2. return this.list.listIterator();
  3. }

JSONArray里面也有一些get()方法,不过都不常用,最有用的应该是getJSONObject(int index)方法,该方法用于获取json对象数组中指定位置的JSONObject对象

简单测试:

  1. public class TestFastJson {
  2. @Test
  3. public void testFastJson(){
  4. JSONObject jsonObject = new JSONObject();
  5. jsonObject.put("name","yao");
  6. jsonObject.put("age",12);
  7. System.out.println(jsonObject);
  8. }
  9. @Test
  10. public void testFastJsonStringToJsonObj(){
  11. User user1 = new User("张三","中国",26);
  12. String jsonString = JSON.toJSONString(user1);
  13. System.out.println("jsonString:" + jsonString);
  14. JSONObject jsonObject = JSON.parseObject(jsonString);
  15. System.out.println("jsonObject:" + jsonObject);
  16. User user = JSON.parseObject(jsonString, User.class);
  17. System.out.println("user:" + user);
  18. User user2 = new User("李四","中国",27);
  19. User user3 = new User("王五","中国",25);
  20. List<User> list = new ArrayList<>();
  21. list.add(user2);
  22. list.add(user3);
  23. String jsonString1 = JSON.toJSONString(list);
  24. System.out.println("jsonString1:" + jsonString1);
  25. List<Object> objects = JSON.parseArray(jsonString1, new Type[]{String.class, User.class});
  26. System.out.println("jsonArray:" + objects);
  27. List<User> list1 = JSON.parseArray(jsonString1, User.class);
  28. System.out.println("list1:" + list1);
  29. }
  30. }
  31. @Data
  32. @AllArgsConstructor
  33. @NoArgsConstructor
  34. @ToString
  35. class User {
  36. private String name;
  37. private String region;
  38. private Integer age;
  39. }

运行结果:

  1. jsonString:{"age":26,"name":"张三","region":"中国"}
  2. jsonObject:{"name":"张三","region":"中国","age":26}
  3. user:User(name=张三, region=中国, age=26)
  4. jsonString1:[{"age":27,"name":"李四","region":"中国"},{"age":25,"name":"王五","region":"中国"}]
  5. jsonArray:[{"age":27,"name":"李四","region":"中国"}, User(name=王五, region=中国, age=25)]
  6. list1:[User(name=李四, region=中国, age=27), User(name=王五, region=中国, age=25)]

3. Fastjson 定制序列化

3.1 使用@JSONField配置 

  1. public @interface JSONField {
  2. // 配置序列化和反序列化的顺序,1.1.42版本之后才支持
  3. int ordinal() default 0;
  4. // 指定字段的名称
  5. String name() default "";
  6. // 指定字段的格式,对日期格式有用
  7. String format() default "";
  8. // 是否序列化
  9. boolean serialize() default true;
  10. // 是否反序列化
  11. boolean deserialize() default true;
  12. //使用serializeUsing制定属性的序列化类
  13. Class<?> serializeUsing() default Void.class;
  14. //使用deserializeUsing制定属性的反序列化类
  15. Class<?> deserializeUsing() default Void.class;
  16. //参与反序列化时候的别名
  17. String[] alternateNames() default {};
  18. //对象映射到父对象上。不进行子对象映射
  19. boolean unwrapped() default false;
  20. //当你有⼀个字段是json字符串的数据,你希望直接输出,而不是经过转义之后再输出
  21. boolean jsonDirect() default false;
  22. }

可以把@JSONField配置在字段或者getter/setter方法上,例如:

配置在字段上

  1. public class VO {
  2. @JSONField(name="ID")
  3. private int id;
  4. @JSONField(name="birthday",format="yyyy-MM-dd")
  5. public Date date;
  6. }

配置在 Getter/Setter 上

  1. public class VO {
  2. private int id;
  3. @JSONField(name="ID")
  4. public int getId() { return id;}
  5. @JSONField(name="ID")
  6. public void setId(int id) {this.id = id;}
  7. }

注意:若属性是私有的,必须有set*方法。否则无法反序列化。

使用format配置日期格式化

  1. public class A {
  2. // 配置date序列化和反序列使用yyyyMMdd日期格式
  3. @JSONField(format="yyyyMMdd")
  4. public Date date;
  5. }

使用serialize/deserialize指定字段不序列化

  1. public class A {
  2. @JSONField(deserialize=false)
  3. public Date date;
  4. }

使用ordinal指定字段的顺序

  1. public static class VO {
  2. @JSONField(ordinal = 3)
  3. private int f0;
  4. @JSONField(ordinal = 2)
  5. private int f1;
  6. @JSONField(ordinal = 1)
  7. private int f2;
  8. }

使用unwrapped

  1. public class JSONController {
  2. public static void main(String[] args) {
  3. QSM qsm = new QSM();
  4. qsm.setName("传闻中的陈芊芊");
  5. qsm.setCity("花垣城");
  6. QSM qsm2 = new QSM();
  7. qsm2.setName("传闻中的韩烁");
  8. qsm2.setCity("玄虎城");
  9. Nation nation1 = Nation.builder().name("中国").qsm(qsm).qsm2(qsm2).build();
  10. System.out.println(JSON.toJSONString(nation1));
  11. }
  12. }
  13. @Data
  14. @Builder
  15. @AllArgsConstructor
  16. @NoArgsConstructor
  17. class Nation {
  18. private String name;
  19. @JSONField(unwrapped = true)
  20. private QSM qsm;
  21. @JSONField(unwrapped = false)
  22. private QSM qsm2;
  23. }
  24. @Data
  25. class QSM {
  26. String name;
  27. String city;
  28. }
{"name":"中国","city":"花垣城","name":"传闻中的陈芊芊","qsm2":{"city":"玄虎城","name":"传闻中的韩烁"}}

使用serializeUsing制定属性的序列化类

  1. public static class Student{
  2. @JSONField(serializeUsing = ModelValueSerializer.class)
  3. public int value;
  4. }
  5. public static class ModelValueSerializer implements ObjectSerializer {
  6. @Override
  7. public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
  8. int features) throws IOException {
  9. Integer value = (Integer) object;
  10. String text = id+ "号";
  11. serializer.write(text);
  12. }
  13. }
  1. Student student= new Student();
  2. student.id= 100;
  3. String json = JSON.toJSONString(student);
  4. Assert.assertEquals("{\"value\":\"100号\"}", json);

3.2 使用@JSONType配置

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target({ElementType.TYPE})
  3. public @interface JSONType {
  4. boolean asm() default true;
  5. String[] orders() default {};
  6. String[] includes() default {};
  7. String[] ignores() default {};
  8. SerializerFeature[] serialzeFeatures() default {};
  9. Feature[] parseFeatures() default {};
  10. boolean alphabetic() default true;
  11. Class<?> mappingTo() default Void.class;
  12. Class<?> builder() default Void.class;
  13. String typeName() default "";
  14. String typeKey() default "";
  15. Class<?>[] seeAlso() default {};
  16. Class<?> serializer() default Void.class;
  17. Class<?> deserializer() default Void.class;
  18. boolean serializeEnumAsJavaBean() default false;
  19. PropertyNamingStrategy naming() default PropertyNamingStrategy.CamelCase;
  20. Class<? extends SerializeFilter>[] serialzeFilters() default {};
  21. }

和JSONField类似,但JSONType配置在上,而不是field或者getter/setter方法上。

  1. String[] ignores() default {};: 指定需要忽略的字段列表。该属性是一个字符串数组,可以列出不需要被序列化和反序列化的字段名。

  2.  String[] includes() default {};: 指定需要包含的字段列表。与 ignores 属性相反,该属性是一个字符串数组,可以列出需要被序列化和反序列化的字段名。

  3. String typeKey() default "": 指定用于标识类型的字段名。如果 Fastjson 需要在序列化时包含类信息,则会使用该字段来指定类型。默认值为@type

  4. String[] orders() default {}: 指定字段的顺序。该属性是一个字符串数组,可以按照指定的顺序对字段进行序列化。

  5. PropertyNamingStrategy: 指定字段命名策略。该属性接受一个类类型作为参数,用于指定字段命名的策略。

  6. SerializerFeature[] serialzeFeatures() default {}: 序列化配置数组。

4. SpringMVC 整合 Fastjson

这里简单介绍一下在SpringMVC 中如何整合Fastjson的,这里采用配置类的方式(xml配置的方式可以参考官方文档)

在 Spring 中集成 Fastjson · alibaba/fastjson Wiki · GitHub

1、引入 Maven 的依赖

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>fastjson</artifactId>
  4. <version>2.0.31</version>
  5. </dependency>

2、Fastjson 自定义配置

如果使用 Spring MVC 来构建 Web 应用并对性能有较高的要求的话,可以使用 Fastjson 提供的FastJsonHttpMessageConverter来替换 Spring MVC 默认的 HttpMessageConverter 以提高 @RestController @ResponseBody @RequestBody 注解的 JSON序列化速度。下面是配置方式,非常简单。

  1. @Configuration
  2. public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
  3. @Override
  4. public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
  5. FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
  6. //自定义配置...
  7. //FastJsonConfig config = new FastJsonConfig();
  8. //config.set ...
  9. //converter.setFastJsonConfig(config);
  10. converters.add(0, converter);
  11. }
  12. }

注:如果你使用的 Fastjson 版本小于1.2.36的话(强烈建议使用最新版本),在与Spring MVC 4.X 版本集成时需使用 FastJsonHttpMessageConverter4

注2:SpringBoot 2.0.1版本中加载WebMvcConfigurer的顺序发生了变动,故需使用converters.add(0, converter);指定FastJsonHttpMessageConverter在converters内的顺序,否则在SpringBoot 2.0.1及之后的版本中将优先使用Jackson处理。

3、Fastjson 常用配置说明

FastJsonConfig是用于配置FastJson序列化和反序列化的配置类。它可以设置各种序列化和反序列化的参数,包括日期格式、序列化特性、过滤器、自定义序列化器和反序列化器等。
 

3.1 序列化特性(SerializerFeature)

序列化特性用于控制JSON输出格式,例如禁用循环引用、输出空置字段、美化输出格式等。SerializerFeature是一个枚举类型

枚举值含义默认值
QuoteFieldNames输出key时是否使用双引号true
UseSingleQuotes使用单引号而不是双引号false
WriteMapNullValue  是否输出值为null的字段false
WriteEnumUsingToString  Enum 输出使用 toString() 方法false
UseISO8601DateFormat    Date使用ISO8601格式输出false
WriteNullListAsEmpty    List字段如果为null,输出为[]false
WriteNullStringAsEmpty  字符类型字段如果为null,输出为”“false
WriteNullNumberAsZero数值字段如果为null,输出为0false
WriteNullBooleanAsFalseBoolean字段如果为null,输出为falsefalse
SkipTransientFieldtransient修饰的方法或字段在序列化时将会被忽略true  
SortField按字段名称排序后输出false
以下不推荐:
WriteTabAsSpecial把\t做转义输出false
PrettyFormat    美化输出格式,使其更易读false
WriteClassName  序列化时写入类型信息false
DisableCircularReferenceDetect 禁用循环引用检测false
WriteSlashAsSpecial对斜杠'/'进行转义false
BrowserCompatible  启用浏览器兼容模式false
WriteDateUseDateFormat  Date 类型字段的格式化输出false
DisableCheckSpecialChar禁用特殊字符检查false
NotWriteRootClassName  不写入根类名称

false

BeanToArray序列化时将 Bean 对象转换成数组false
NotWriteDefaultValue    不写默认值false
WriteNonStringKeyAsString  将非字符串类型的 key 转换为字符串false
IgnoreNonFieldGetter    忽略非字段的 getterfalse
WriteEnumUsingName  Enum 输出使用枚举的名称false
BrowserSecure  启用浏览器兼容模式false

可以使用以下代码进行配置:

  1. FastJsonConfig fastJsonConfig = new FastJsonConfig();
  2. fastJsonConfig.setSerializerFeatures(
  3. SerializerFeature.PrettyFormat,
  4. SerializerFeature.WriteMapNullValue,
  5. SerializerFeature.DisableCircularReferenceDetect,
  6. SerializerFeature.WriteDateUseDateFormat
  7. );

3.2 日期格式(DateFormat)

FastJson默认使用ISO-8601格式输出日期,例如"2019-12-01T12:00:00.000Z"。我们可以通过设置DateFormat来指定输出格式,例如"yyyy-MM-dd HH:mm:ss"

  1. FastJsonConfig fastJsonConfig = new FastJsonConfig();
  2. fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");

3.3 过滤器(SerializeFilter)

过滤器可以用于在序列化时进行字段过滤、属性重命名等操作。FastJson提供了多种过滤器,例如PropertyPreFilter、NameFilter、ValueFilter、BeforeFilter、AfterFilter等。

3.3.1 ValueFilter :修改Value值——修改属性的值

ValueFilter 其中的 apply 方法,如果需要自定义序列化过程,可以自己实现 ValueFilter,重写里面的 process 方法,其中的三个参数:

  1、Object object : 表示当前的对象,例如 User(name=赵六, region=中国, age=12)

  2、String name : 表示当前属性名称,例如 s:age

  3、Object value:表示当前属性的值,例如 o1:12

  1. package com.alibaba.fastjson.serializer;
  2. public interface ValueFilter extends SerializeFilter, com.alibaba.fastjson2.filter.ValueFilter {
  3. Object process(Object var1, String var2, Object var3);
  4. default Object apply(Object object, String name, Object value) {
  5. return this.process(object, name, value);
  6. }
  7. }

测试代码:

  1. @Test
  2. public void testValueFilter(){
  3. User user = new User("赵六","中国",12);
  4. // FastJson 1
  5. ValueFilter valueFilter = new ValueFilter() {
  6. @Override
  7. public Object process(Object o, String s, Object o1) {
  8. System.out.println("o:" + o);
  9. System.out.println("s:" + s);
  10. System.out.println("o1:" + o1);
  11. if(s.equals("name")){
  12. o1 = o1 + "用户";
  13. return o1;
  14. }
  15. return o1;
  16. }
  17. };
  18. String jsonString = JSON.toJSONString(user, valueFilter);
  19. System.out.println(jsonString);
  20. User user1 = JSON.parseObject(jsonString, User.class);
  21. System.out.println(user1);
  22. }
  1. o:User(name=赵六, region=中国, age=12)
  2. s:age
  3. o1:12
  4. o:User(name=赵六, region=中国, age=12)
  5. s:name
  6. o1:赵六
  7. o:User(name=赵六, region=中国, age=12)
  8. s:region
  9. o1:中国
  10. {"age":12,"name":"赵六用户","region":"中国"}
  11. User(name=赵六用户, region=中国, age=12)
3.3.2 NameFilter:修改属性的名称

NameFilter其中的 process 方法,如果需要自定义序列化过程,可以自己实现 NameFilter,重写里面的 process 方法,其中的三个参数同 ValueFilter

  1. package com.alibaba.fastjson.serializer;
  2. public interface NameFilter extends SerializeFilter, com.alibaba.fastjson2.filter.NameFilter {
  3. String process(Object var1, String var2, Object var3);
  4. }

 测试代码:

  1. @Test
  2. public void testNameFilter() {
  3. User user = new User("赵六","中国",12);
  4. NameFilter nameFilter = new NameFilter() {
  5. @Override
  6. public String process(Object o, String s, Object o1) {
  7. System.out.println("o:" + o);
  8. System.out.println("s:" + s);
  9. System.out.println("o1:" + o1);
  10. if(s.equals("name")){
  11. return "xingming";
  12. }
  13. return s;
  14. }
  15. };
  16. String jsonString = JSON.toJSONString(user, nameFilter);
  17. System.out.println(jsonString);
  18. }
  1. o:User(name=赵六, region=中国, age=12)
  2. s:age
  3. o1:12
  4. o:User(name=赵六, region=中国, age=12)
  5. s:name
  6. o1:赵六
  7. o:User(name=赵六, region=中国, age=12)
  8. s:region
  9. o1:中国
  10. {"age":12,"xingming":"赵六","region":"中国"}
  11. Process finished with exit code 0
3.3.3 BeforeFilter:序列化时在最前添加内容

BeforeFilter 抽象类中,当我们实例化一个BeforeFilter 对象的时候,需要重写里面的抽象方法 writeBefore,在此方法中可以配置自己在序列化前端进行的操作。

  1. public abstract class BeforeFilter extends com.alibaba.fastjson2.filter.BeforeFilter implements SerializeFilter {
  2. public BeforeFilter() {
  3. }
  4. }
  1. public abstract class BeforeFilter implements Filter {
  2. private static final ThreadLocal<JSONWriter> serializerLocal = new ThreadLocal();
  3. public BeforeFilter() {
  4. }
  5. public void writeBefore(JSONWriter serializer, Object object) {
  6. JSONWriter last = (JSONWriter)serializerLocal.get();
  7. serializerLocal.set(serializer);
  8. this.writeBefore(object);
  9. serializerLocal.set(last);
  10. }
  11. protected final void writeKeyValue(String key, Object value) {
  12. JSONWriter serializer = (JSONWriter)serializerLocal.get();
  13. boolean ref = serializer.containsReference(value);
  14. serializer.writeName(key);
  15. serializer.writeColon();
  16. serializer.writeAny(value);
  17. if (!ref) {
  18. serializer.removeReference(value);
  19. }
  20. }
  21. public abstract void writeBefore(Object var1);
  22. }

观察 BeforeFilter 的源码可以发现:writeBefore方法调用了重载的抽象方法writeBefore也就是重写的那个方法,此外,在 BeforeFilter 还有一个 writeKeyValue 方法,可以在重写的writeBefore方法中调用此方法对 json 进行添加。

  1. @Test
  2. public void testBeforeFilter() {
  3. User user = new User("赵六","中国",12);
  4. BeforeFilter beforeFilter = new BeforeFilter() {
  5. @Override
  6. public void writeBefore(Object o) {
  7. System.out.println("序列化前是我,哈哈哈哈哈");
  8. }
  9. };
  10. String jsonString = JSON.toJSONString(user, beforeFilter);
  11. System.out.println(jsonString);
  12. }
  1. 序列化前是我,哈哈哈哈哈
  2. {"age":12,"name":"赵六","region":"中国"}
3.3.4 AfterFilter:序列化时在最后添加内容

AfterFilter抽象类中,当我们实例化一个AfterFilter对象的时候,需要重写里面的抽象方法 writeAfter,在此方法中可以配置自己在序列化末端进行的操作。

  1. @Test
  2. public void testAfterFilter() {
  3. User user = new User("赵六","中国",12);
  4. AfterFilter afterFilter = new AfterFilter() {
  5. @Override
  6. public void writeAfter(Object o) {
  7. System.out.println("我是序列化之后的输出!");
  8. }
  9. };
  10. String jsonString = JSON.toJSONString(user, afterFilter);
  11. System.out.println(jsonString);
  12. }
  1. 我是序列化之后的输出!
  2. {"age":12,"name":"赵六","region":"中国"}
3.3.5 PropertyFilter:根据PropertyName和PropertyValue来判断是否序列化

PropertyFilter可以通过扩展实现根据object或者属性名称或者属性值进行判断是否需要序列化

  1. @Test
  2. public void testPropertyFilter() {
  3. User user = new User("赵六","中国",12);
  4. PropertyFilter propertyFilter = new PropertyFilter() {
  5. @Override
  6. public boolean apply(Object o, String s, Object o1) {
  7. if("age".equals(s)){
  8. return (int)o1 == 10;
  9. }
  10. return false;
  11. }
  12. };
  13. String jsonString = JSON.toJSONString(user, propertyFilter);
  14. System.out.println(jsonString);
  15. }
{}
3.3.6 PropertyPreFilter:根据PropertyName判断是否序列化

PropertyPreFilter属性前置过滤器)是 Fastjson 提供的一种过滤器接口,用于在序列化时控制哪些属性需要被序列化。与 PropertyFilter相比,PropertyPreFilter允许在序列化开始之前预先过滤掉不需要序列化的属性,而不是在序列化过程中动态地进行过滤

PropertyPreFilter接口定义了一个 apply 方法,该方法接收一个对象和对象的属性名,返回一个布尔值来指示是否需要序列化这个属性。如果返回 true,则表示需要序列化该属性,如果返回 false,则表示不需要序列化该属性。

使用 PropertyPreFilter可以实现更细粒度的属性过滤控制,尤其适用于一些复杂的序列化场景。

  1. import com.alibaba.fastjson.JSON;
  2. import com.alibaba.fastjson.serializer.PropertyPreFilter;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. public class Example {
  6. public static void main(String[] args) {
  7. Map<String, Object> data = new HashMap<>();
  8. data.put("name", "John");
  9. data.put("age", 30);
  10. data.put("gender", "male");
  11. PropertyPreFilter filter = (object, name, value) -> !"gender".equals(name);
  12. String jsonString = JSON.toJSONString(data, filter);
  13. System.out.println(jsonString);
  14. }
  15. }

3.4 自定义序列化器和反序列化器

FastJson 中,你可以通过实现 SerializeFilter ObjectSerializer 接口来自定义序列化过程,通过实现 ParserConfig ObjectDeserializer 接口来自定义反序列化过程。

自定义序列化:

  1. import com.alibaba.fastjson.serializer.JSONSerializer;
  2. import com.alibaba.fastjson.serializer.ObjectSerializer;
  3. import java.io.IOException;
  4. import java.lang.reflect.Type;
  5. public class CustomObjectSerializer implements ObjectSerializer {
  6. @Override
  7. public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
  8. // 在这里实现自定义的序列化逻辑
  9. // 这里只是一个简单示例,可以根据需求实现具体的逻辑
  10. serializer.out.writeString("CustomSerializedValue");
  11. }
  12. }
  13. import com.alibaba.fastjson.JSON;
  14. import com.alibaba.fastjson.serializer.SerializeConfig;
  15. public class Main {
  16. public static void main(String[] args) {
  17. SerializeConfig config = new SerializeConfig();
  18. config.put(MyClass.class, new CustomObjectSerializer());
  19. MyClass obj = new MyClass();
  20. System.out.println(JSON.toJSONString(obj, config));
  21. }
  22. }

自定义反序列化:

  1. import com.alibaba.fastjson.parser.DefaultJSONParser;
  2. import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
  3. import java.lang.reflect.Type;
  4. public class CustomObjectDeserializer implements ObjectDeserializer {
  5. @Override
  6. public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
  7. // 在这里实现自定义的反序列化逻辑
  8. // 这里只是一个简单示例,可以根据需求实现具体的逻辑
  9. return (T) new MyClass();
  10. }
  11. @Override
  12. public int getFastMatchToken() {
  13. return 0;
  14. }
  15. }```
  16. import com.alibaba.fastjson.JSON;
  17. import com.alibaba.fastjson.parser.ParserConfig;
  18. public class Main {
  19. public static void main(String[] args) {
  20. ParserConfig.getGlobalInstance().putDeserializer(MyClass.class, new CustomObjectDeserializer());
  21. String jsonString = "{\"field\":\"value\"}";
  22. MyClass obj = JSON.parseObject(jsonString, MyClass.class);
  23. System.out.println(obj);
  24. }
  25. }

5. FastJson 2 较 FastJson1.0 的变更

5.1 Maven 依赖引入

  1. <dependency>
  2. <groupId>com.alibaba.fastjson2</groupId>
  3. <artifactId>fastjson2</artifactId>
  4. <version>2.0.27</version>
  5. </dependency>

优化1:整体继承类的修改:

  • Fastjson1 的JSONObject 只是简单实现Map接口,是无序的map容器
  • Fastjson2 的JSONObject 实现了链结构的Map,是有序的Map容器
  • 无论是JSONObject或者JSONArray都摆脱了JSON的类,而且JSON由抽象类——>接口

版本V1

//1.Fastjson 1 JSONObject类定义

public class JSONObject extends JSON implements Map<String,Object> ...{

}

//2.Fastjson 1 JSONArray类定义

public class JSONArray extends JSON implements List<Object>... {

}

版本V2

//1.Fastjson2 JSONObject类定义

public class JSONObject extends LinkedHashMap<String, Object> implements InvocationHandler{

}

//2.Fastjson2 JSONArray类定义

public class JSONArray extends ArrayList<Object> {

}

优化2:常见类型的优化

时间转化类由原来使用SimpleDateFormat转化为 JDK8 提供的java.time API,吸收了 joda-time的部分精华,功能更强大,性能也更好。同时,DateTimeFormatter 是线程安全的

未完待续。。。。后续会更新fastjson2

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/882722
推荐阅读
相关标签
  

闽ICP备14008679号