1. Fastjson的官方地址
Fastjson: 地址
Springboot 自带的json解析框架是jackson,如果要想使用fastjson的话,可以采用以下的两种方式:
方式一:用bean替代默认解析器(推荐)
注意的是:这里的bean并不是将原来的jackson给直接替换掉,而是springboot会采用我们设置的更高优先级的fastjson来解析。
@Configuration public class WebConfig { @Bean public HttpMessageConverters fastJsonMessageConverters() { List<HttpMessageConverter<?>> converters = new ArrayList<>(); //需要定义一个convert转换消息的对象; FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); //添加fastJson的配置信息; FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat); //全局时间配置 fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); //在convert中添加配置信息. fastConverter.setFastJsonConfig(fastJsonConfig); converters.add(0, fastConverter); return new HttpMessageConverters(converters); } }
方式二:实现WebMvcConfigurer
@Configuration public class FastjsonCon implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); //自定义FastJson配置 FastJsonConfig config = new FastJsonConfig(); config.setSerializerFeatures(SerializerFeature.QuoteFieldNames, SerializerFeature.WriteEnumUsingToString, /*SerializerFeature.WriteMapNullValue,*/ SerializerFeature.WriteDateUseDateFormat, SerializerFeature.DisableCircularReferenceDetect); fastJsonHttpMessageConverter.setFastJsonConfig(config); converters.add(fastJsonHttpMessageConverter); } }
2. FastJson 的三个主要类和基本 Api
FastJson 主要的三个类:JSON、JSONArray、JSONObject。JSONObject和JSONArray继承自JSON。
可以发现,JSONObject代表json对象,JSONArray代表json对象数组,JSON代表JSONObject和JSONArray的转化。
FastJson API 入口类是com.alibaba.fastjson.JSON,常用的序列化操作都可以在JSON类上的静态方法直接完成。
// 把JSON文本parse为JSONObject或者JSONArray public static final Object parse(String text); // 把JSON文本parse成JSONObject public static final JSONObject parseObject(String text); // 把JSON文本parse为JavaBean public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文本parse成JSONArray public static final JSONArray parseArray(String text); //把JSON文本parse成JavaBean集合 public static final <T> List<T> parseArray(String text, Class<T> clazz); // 将JavaBean序列化为JSON文本 public static final String toJSONString(Object object); // 将JavaBean序列化为带格式的JSON文本 public static final String toJSONString(Object object, boolean prettyFormat); //将JavaBean转换为JSONObject或者JSONArray public static final Object toJSON(Object javaObject);
序列化:
String jsonString = JSON.toJSONString(obj);
反序列化:
VO vo = JSON.parseObject("...", VO.class);
泛型反序列化:
import com.alibaba.fastjson.TypeReference; 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)
public String getString(String key) { Object value = this.get(key); return value == null ? null : value.toString(); }
getString(String key)方法,该方法输入参数为String key(键),输出为String ,用于获取json对象中的字符串型数据。例如通过该方法获取 “name”:"bob"键值对中name这个键所对应的值bob。通过查看源码发现内部主要由Map接口中的get()方法实现。
public Object get(Object key) { Object val = this.map.get(key); if (val == null && (key instanceof Number || key instanceof Boolean || key instanceof Character)) { val = this.map.get(key.toString()); } return val; }
2. getInteger(String key)
public Integer getInteger(String key) { Object value = this.map.get(key); if (value == null) { return null; } else if (value instanceof Integer) { return (Integer)value; } else if (value instanceof Number) { return ((Number)value).intValue(); } else if (value instanceof String) { String str = (String)value; if (!str.isEmpty() && !"null".equalsIgnoreCase(str)) { return str.indexOf(46) != -1 ? (int)Double.parseDouble(str) : Integer.parseInt(str); } else { return null; } } else { throw new JSONException("Can not cast '" + value.getClass() + "' to Integer"); } }
JSONObject中的getInteger(String key)该方法获取json对象中的整型数据,例如获取"age:20"键值对中age对应的整型数值20。
JSONObject中其它的get方法与上述两个方法极为相似,比较常用的有如下几个:
public <T> T getObject(String key, Type type, Feature... features) public Long getLong(String key) public Float getFloat(String key) public Date getDate(String key) 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():
public boolean add(Object item) { return this.list.add(item); }
remove():
public boolean remove(Object o) { return this.list.remove(o); }
containsAll():
public boolean containsAll(Collection c) { return this.list.containsAll(c); }
listIterator():
public ListIterator listIterator() { return this.list.listIterator(); }
JSONArray里面也有一些get()方法,不过都不常用,最有用的应该是getJSONObject(int index)方法,该方法用于获取json对象数组中指定位置的JSONObject对象
简单测试:
public class TestFastJson { @Test public void testFastJson(){ JSONObject jsonObject = new JSONObject(); jsonObject.put("name","yao"); jsonObject.put("age",12); System.out.println(jsonObject); } @Test public void testFastJsonStringToJsonObj(){ User user1 = new User("张三","中国",26); String jsonString = JSON.toJSONString(user1); System.out.println("jsonString:" + jsonString); JSONObject jsonObject = JSON.parseObject(jsonString); System.out.println("jsonObject:" + jsonObject); User user = JSON.parseObject(jsonString, User.class); System.out.println("user:" + user); User user2 = new User("李四","中国",27); User user3 = new User("王五","中国",25); List<User> list = new ArrayList<>(); list.add(user2); list.add(user3); String jsonString1 = JSON.toJSONString(list); System.out.println("jsonString1:" + jsonString1); List<Object> objects = JSON.parseArray(jsonString1, new Type[]{String.class, User.class}); System.out.println("jsonArray:" + objects); List<User> list1 = JSON.parseArray(jsonString1, User.class); System.out.println("list1:" + list1); } } @Data @AllArgsConstructor @NoArgsConstructor @ToString class User { private String name; private String region; private Integer age; }
运行结果:
jsonString:{"age":26,"name":"张三","region":"中国"} jsonObject:{"name":"张三","region":"中国","age":26} user:User(name=张三, region=中国, age=26) jsonString1:[{"age":27,"name":"李四","region":"中国"},{"age":25,"name":"王五","region":"中国"}] jsonArray:[{"age":27,"name":"李四","region":"中国"}, User(name=王五, region=中国, age=25)] list1:[User(name=李四, region=中国, age=27), User(name=王五, region=中国, age=25)]
3. Fastjson 定制序列化
3.1 使用@JSONField配置
public @interface JSONField { // 配置序列化和反序列化的顺序,1.1.42版本之后才支持 int ordinal() default 0; // 指定字段的名称 String name() default ""; // 指定字段的格式,对日期格式有用 String format() default ""; // 是否序列化 boolean serialize() default true; // 是否反序列化 boolean deserialize() default true; //使用serializeUsing制定属性的序列化类 Class<?> serializeUsing() default Void.class; //使用deserializeUsing制定属性的反序列化类 Class<?> deserializeUsing() default Void.class; //参与反序列化时候的别名 String[] alternateNames() default {}; //对象映射到父对象上。不进行子对象映射 boolean unwrapped() default false; //当你有⼀个字段是json字符串的数据,你希望直接输出,而不是经过转义之后再输出 boolean jsonDirect() default false; }
可以把@JSONField配置在字段或者getter/setter方法上,例如:
配置在字段上
public class VO { @JSONField(name="ID") private int id; @JSONField(name="birthday",format="yyyy-MM-dd") public Date date; }
配置在 Getter/Setter 上
public class VO { private int id; @JSONField(name="ID") public int getId() { return id;} @JSONField(name="ID") public void setId(int id) {this.id = id;} }
注意:若属性是私有的,必须有set*方法。否则无法反序列化。
使用format配置日期格式化
public class A { // 配置date序列化和反序列使用yyyyMMdd日期格式 @JSONField(format="yyyyMMdd") public Date date; }
使用serialize/deserialize指定字段不序列化
public class A { @JSONField(deserialize=false) public Date date; }
使用ordinal指定字段的顺序
public static class VO { @JSONField(ordinal = 3) private int f0; @JSONField(ordinal = 2) private int f1; @JSONField(ordinal = 1) private int f2; }
使用unwrapped
public class JSONController { public static void main(String[] args) { QSM qsm = new QSM(); qsm.setName("传闻中的陈芊芊"); qsm.setCity("花垣城"); QSM qsm2 = new QSM(); qsm2.setName("传闻中的韩烁"); qsm2.setCity("玄虎城"); Nation nation1 = Nation.builder().name("中国").qsm(qsm).qsm2(qsm2).build(); System.out.println(JSON.toJSONString(nation1)); } } @Data @Builder @AllArgsConstructor @NoArgsConstructor class Nation { private String name; @JSONField(unwrapped = true) private QSM qsm; @JSONField(unwrapped = false) private QSM qsm2; } @Data class QSM { String name; String city; }
{"name":"中国","city":"花垣城","name":"传闻中的陈芊芊","qsm2":{"city":"玄虎城","name":"传闻中的韩烁"}}
使用serializeUsing制定属性的序列化类
public static class Student{ @JSONField(serializeUsing = ModelValueSerializer.class) public int value; } public static class ModelValueSerializer implements ObjectSerializer { @Override public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { Integer value = (Integer) object; String text = id+ "号"; serializer.write(text); } }
Student student= new Student(); student.id= 100; String json = JSON.toJSONString(student); Assert.assertEquals("{\"value\":\"100号\"}", json);
3.2 使用@JSONType配置
@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 {}; }
和JSONField类似,但JSONType配置在类上,而不是field或者getter/setter方法上。
String[] ignores() default {};: 指定需要忽略的字段列表。该属性是一个字符串数组,可以列出不需要被序列化和反序列化的字段名。
String[] includes() default {};: 指定需要包含的字段列表。与 ignores 属性相反,该属性是一个字符串数组,可以列出需要被序列化和反序列化的字段名。
String typeKey() default "": 指定用于标识类型的字段名。如果 Fastjson 需要在序列化时包含类信息,则会使用该字段来指定类型。默认值为@type。
String[] orders() default {}: 指定字段的顺序。该属性是一个字符串数组,可以按照指定的顺序对字段进行序列化。
PropertyNamingStrategy: 指定字段命名策略。该属性接受一个类类型作为参数,用于指定字段命名的策略。
SerializerFeature[] serialzeFeatures() default {}: 序列化配置数组。
4. SpringMVC 整合 Fastjson
这里简单介绍一下在SpringMVC 中如何整合Fastjson的,这里采用配置类的方式(xml配置的方式可以参考官方文档)
1、引入 Maven 的依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.31</version> </dependency>
2、Fastjson 自定义配置
如果使用 Spring MVC 来构建 Web 应用并对性能有较高的要求的话,可以使用 Fastjson 提供的FastJsonHttpMessageConverter
来替换 Spring MVC 默认的 HttpMessageConverter
以提高 @RestController @ResponseBody @RequestBody
注解的 JSON序列化速度。下面是配置方式,非常简单。
@Configuration public class WebMvcConfigurer extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); //自定义配置... //FastJsonConfig config = new FastJsonConfig(); //config.set ... //converter.setFastJsonConfig(config); converters.add(0, converter); } }
注:如果你使用的 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,输出为0 | false |
WriteNullBooleanAsFalse | Boolean字段如果为null,输出为false | false |
SkipTransientField | transient修饰的方法或字段在序列化时将会被忽略 | 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 | 忽略非字段的 getter | false |
WriteEnumUsingName | Enum 输出使用枚举的名称 | false |
BrowserSecure | 启用浏览器兼容模式 | false |
可以使用以下代码进行配置:
FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures( SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat );
3.2 日期格式(DateFormat)
FastJson默认使用ISO-8601格式输出日期,例如"2019-12-01T12:00:00.000Z"。我们可以通过设置DateFormat来指定输出格式,例如"yyyy-MM-dd HH:mm:ss"。
FastJsonConfig fastJsonConfig = new FastJsonConfig(); 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
package com.alibaba.fastjson.serializer; public interface ValueFilter extends SerializeFilter, com.alibaba.fastjson2.filter.ValueFilter { Object process(Object var1, String var2, Object var3); default Object apply(Object object, String name, Object value) { return this.process(object, name, value); } }
测试代码:
@Test public void testValueFilter(){ User user = new User("赵六","中国",12); // FastJson 1 ValueFilter valueFilter = new ValueFilter() { @Override public Object process(Object o, String s, Object o1) { System.out.println("o:" + o); System.out.println("s:" + s); System.out.println("o1:" + o1); if(s.equals("name")){ o1 = o1 + "用户"; return o1; } return o1; } }; String jsonString = JSON.toJSONString(user, valueFilter); System.out.println(jsonString); User user1 = JSON.parseObject(jsonString, User.class); System.out.println(user1); }
o:User(name=赵六, region=中国, age=12) s:age o1:12 o:User(name=赵六, region=中国, age=12) s:name o1:赵六 o:User(name=赵六, region=中国, age=12) s:region o1:中国 {"age":12,"name":"赵六用户","region":"中国"} User(name=赵六用户, region=中国, age=12)
3.3.2 NameFilter:修改属性的名称
NameFilter其中的 process 方法,如果需要自定义序列化过程,可以自己实现 NameFilter,重写里面的 process 方法,其中的三个参数同 ValueFilter 。
package com.alibaba.fastjson.serializer; public interface NameFilter extends SerializeFilter, com.alibaba.fastjson2.filter.NameFilter { String process(Object var1, String var2, Object var3); }
测试代码:
@Test public void testNameFilter() { User user = new User("赵六","中国",12); NameFilter nameFilter = new NameFilter() { @Override public String process(Object o, String s, Object o1) { System.out.println("o:" + o); System.out.println("s:" + s); System.out.println("o1:" + o1); if(s.equals("name")){ return "xingming"; } return s; } }; String jsonString = JSON.toJSONString(user, nameFilter); System.out.println(jsonString); }
o:User(name=赵六, region=中国, age=12) s:age o1:12 o:User(name=赵六, region=中国, age=12) s:name o1:赵六 o:User(name=赵六, region=中国, age=12) s:region o1:中国 {"age":12,"xingming":"赵六","region":"中国"} Process finished with exit code 0
3.3.3 BeforeFilter:序列化时在最前添加内容
BeforeFilter 抽象类中,当我们实例化一个BeforeFilter 对象的时候,需要重写里面的抽象方法 writeBefore,在此方法中可以配置自己在序列化前端进行的操作。
public abstract class BeforeFilter extends com.alibaba.fastjson2.filter.BeforeFilter implements SerializeFilter { public BeforeFilter() { } }
public abstract class BeforeFilter implements Filter { private static final ThreadLocal<JSONWriter> serializerLocal = new ThreadLocal(); public BeforeFilter() { } public void writeBefore(JSONWriter serializer, Object object) { JSONWriter last = (JSONWriter)serializerLocal.get(); serializerLocal.set(serializer); this.writeBefore(object); serializerLocal.set(last); } protected final void writeKeyValue(String key, Object value) { JSONWriter serializer = (JSONWriter)serializerLocal.get(); boolean ref = serializer.containsReference(value); serializer.writeName(key); serializer.writeColon(); serializer.writeAny(value); if (!ref) { serializer.removeReference(value); } } public abstract void writeBefore(Object var1); }
观察 BeforeFilter 的源码可以发现:writeBefore方法调用了重载的抽象方法writeBefore,也就是重写的那个方法,此外,在 BeforeFilter 还有一个 writeKeyValue 方法,可以在重写的writeBefore方法中调用此方法对 json 进行添加。
@Test public void testBeforeFilter() { User user = new User("赵六","中国",12); BeforeFilter beforeFilter = new BeforeFilter() { @Override public void writeBefore(Object o) { System.out.println("序列化前是我,哈哈哈哈哈"); } }; String jsonString = JSON.toJSONString(user, beforeFilter); System.out.println(jsonString); }
序列化前是我,哈哈哈哈哈 {"age":12,"name":"赵六","region":"中国"}
3.3.4 AfterFilter:序列化时在最后添加内容
AfterFilter抽象类中,当我们实例化一个AfterFilter对象的时候,需要重写里面的抽象方法 writeAfter,在此方法中可以配置自己在序列化末端进行的操作。
@Test public void testAfterFilter() { User user = new User("赵六","中国",12); AfterFilter afterFilter = new AfterFilter() { @Override public void writeAfter(Object o) { System.out.println("我是序列化之后的输出!"); } }; String jsonString = JSON.toJSONString(user, afterFilter); System.out.println(jsonString); }
我是序列化之后的输出! {"age":12,"name":"赵六","region":"中国"}
3.3.5 PropertyFilter:根据PropertyName和PropertyValue来判断是否序列化
PropertyFilter可以通过扩展实现根据object或者属性名称或者属性值进行判断是否需要序列化。
@Test public void testPropertyFilter() { User user = new User("赵六","中国",12); PropertyFilter propertyFilter = new PropertyFilter() { @Override public boolean apply(Object o, String s, Object o1) { if("age".equals(s)){ return (int)o1 == 10; } return false; } }; String jsonString = JSON.toJSONString(user, propertyFilter); System.out.println(jsonString); }
{}
3.3.6 PropertyPreFilter:根据PropertyName判断是否序列化
PropertyPreFilter(属性前置过滤器)是 Fastjson 提供的一种过滤器接口,用于在序列化时控制哪些属性需要被序列化。与 PropertyFilter相比,PropertyPreFilter允许在序列化开始之前预先过滤掉不需要序列化的属性,而不是在序列化过程中动态地进行过滤。
PropertyPreFilter接口定义了一个 apply 方法,该方法接收一个对象和对象的属性名,返回一个布尔值来指示是否需要序列化这个属性。如果返回 true,则表示需要序列化该属性,如果返回 false,则表示不需要序列化该属性。
使用 PropertyPreFilter可以实现更细粒度的属性过滤控制,尤其适用于一些复杂的序列化场景。
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.PropertyPreFilter; import java.util.HashMap; import java.util.Map; public class Example { public static void main(String[] args) { Map<String, Object> data = new HashMap<>(); data.put("name", "John"); data.put("age", 30); data.put("gender", "male"); PropertyPreFilter filter = (object, name, value) -> !"gender".equals(name); String jsonString = JSON.toJSONString(data, filter); System.out.println(jsonString); } }
3.4 自定义序列化器和反序列化器
在 FastJson 中,你可以通过实现 SerializeFilter 和 ObjectSerializer 接口来自定义序列化过程,通过实现 ParserConfig 和 ObjectDeserializer 接口来自定义反序列化过程。
自定义序列化:
import com.alibaba.fastjson.serializer.JSONSerializer; import com.alibaba.fastjson.serializer.ObjectSerializer; import java.io.IOException; import java.lang.reflect.Type; public class CustomObjectSerializer implements ObjectSerializer { @Override public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { // 在这里实现自定义的序列化逻辑 // 这里只是一个简单示例,可以根据需求实现具体的逻辑 serializer.out.writeString("CustomSerializedValue"); } } import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializeConfig; public class Main { public static void main(String[] args) { SerializeConfig config = new SerializeConfig(); config.put(MyClass.class, new CustomObjectSerializer()); MyClass obj = new MyClass(); System.out.println(JSON.toJSONString(obj, config)); } }
自定义反序列化:
import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; import java.lang.reflect.Type; public class CustomObjectDeserializer implements ObjectDeserializer { @Override public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { // 在这里实现自定义的反序列化逻辑 // 这里只是一个简单示例,可以根据需求实现具体的逻辑 return (T) new MyClass(); } @Override public int getFastMatchToken() { return 0; } }``` import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; public class Main { public static void main(String[] args) { ParserConfig.getGlobalInstance().putDeserializer(MyClass.class, new CustomObjectDeserializer()); String jsonString = "{\"field\":\"value\"}"; MyClass obj = JSON.parseObject(jsonString, MyClass.class); System.out.println(obj); } }
5. FastJson 2 较 FastJson1.0 的变更
5.1 Maven 依赖引入
<dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.27</version> </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