FastJSON指南
fastjson用于将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
简单使用
- 通过maven引入相应的json包
com.alibaba fastjson 1.2.49
- 定义一个需要转换所实体类User,代码如下:
package com.ivan.json.entity;import java.util.Date;import com.alibaba.fastjson.annotation.JSONField;public class User {private Long id;private String name;@JSONField(format = "yyyy-MM-dd HH:mm:ss")private Date createTime;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}}
- 写个简单的测试类用于测试fastjson的序列化与反序列化,代码如下:
package com.ivan.json;import java.util.Date;import com.alibaba.fastjson.JSON;
import com.ivan.json.entity.User;public class SimpleTest {public static void main(String[] args) {serialize();deserialize();}public static void serialize() {User user = new User();user.setId(11L);user.setName("西安");user.setCreateTime(new Date());String jsonString = JSON.toJSONString(user);System.out.println(jsonString);}public static void deserialize() {String jsonString = "{\"createTime\":\"2018-08-17 14:38:38\",\"id\":11,\"name\":\"西安\"}";User user = JSON.parseObject(jsonString, User.class);System.out.println(user.getName());System.out.println(user.getCreateTime());}
}
SerializerFeature特性的使用
fastjson通过SerializerFeature对生成的json格式的数据进行一些定制,比如可以输入的格式更好看,使用单引号而非双引号等。例子程序如下:
package com.ivan.json;import java.util.Date;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.ivan.json.entity.User;public class SerializerFeatureTest {public static void main(String[] args) {User user = new User();user.setId(11L);user.setCreateTime(new Date());String jsonString = JSON.toJSONString(user, SerializerFeature.PrettyFormat, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.UseSingleQuotes);System.out.println(jsonString);}}
输出的结果如下:

使用SerializerFeature的输出结果
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不推荐设为true |
| PrettyFormat | 结果是否格式化,默认为false |
| WriteClassName | 序列化时写入类型信息,默认为false。反序列化是需用到 |
| DisableCircularReferenceDetect | 消除对同一对象循环引用的问题,默认为false |
| WriteSlashAsSpecial | 对斜杠’/’进行转义 |
| BrowserCompatible | 将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false |
| WriteDateUseDateFormat | 全局修改日期格式,默认为false。 |
| DisableCheckSpecialChar | 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false |
| BeanToArray | 将对象转为array输出 |
JSONField与JSONType注解的使用
fastjson提供了JSONField对序列化与反序列化进行定制,比如可以指定字段的名称,序列化的顺序。JSONField用于属性,方法方法参数上。JSONField的源码如下:
package com.alibaba.fastjson.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface JSONField {
// 配置序列化和反序列化的顺序int ordinal() default 0;
// 指定字段的名称String name() default "";
// 指定字段的格式,对日期格式有用String format() default "";// 是否序列化boolean serialize() default true;
// 是否反序列化boolean deserialize() default true;
//字段级别的SerializerFeatureSerializerFeature[] serialzeFeatures() default {};
//Feature[] parseFeatures() default {};//给属性打上标签, 相当于给属性进行了分组String label() default "";boolean jsonDirect() default false;//制定属性的序列化类Class> serializeUsing() default Void.class;//制定属性的反序列化类Class> deserializeUsing() default Void.class;String[] alternateNames() default {};boolean unwrapped() default false;
}
其中serializeUsing与deserializeUsing可以用于对字段的序列化与反序列化进行定制化。比如我们在User实体上加上个sex属性,类型为boolean。下面分别定义了序列化类与反序列化类,序列化类代码如下:
package com.ivan.json.converter;import java.io.IOException;
import java.lang.reflect.Type;import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;public class SexSerializer implements ObjectSerializer {public void write(JSONSerializer serializer,Object object,Object fieldName,Type fieldType,int features)throws IOException {Boolean value = (Boolean) object;String text = "女";if (value != null && value == true) {text = "男";}serializer.write(text);}}
反序列化类代码如下:
package com.ivan.json.converter;import java.lang.reflect.Type;import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;public class SexDeserialize implements ObjectDeserializer {public T deserialze(DefaultJSONParser parser,Type type,Object fieldName) {String sex = parser.parseObject(String.class);if ("男".equals(sex)) {return (T) Boolean.TRUE;} else {return (T) Boolean.FALSE;}}public int getFastMatchToken() {return JSONToken.UNDEFINED;}}
fastjosn提供了JSONType用于类级别的定制化, JSONType的源码如下:
package com.alibaba.fastjson.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;@Retention(RetentionPolicy.RUNTIME)
//需要标注在类上
@Target({ ElementType.TYPE })
public @interface JSONType {boolean asm() default true;
//这里可以定义输出json的字段顺序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 {};
}
SerializeFilter
fastjson通过SerializeFilter编程扩展的方式定制序列化fastjson支持以下SerializeFilter用于不同常景的定制序列化:
- PropertyFilter 根据PropertyName和PropertyValue来判断是否序列化,接口定义如下:
package com.alibaba.fastjson.serializer;/*** @author wenshao[szujobs@hotmail.com]*/
public interface PropertyFilter extends SerializeFilter {/*** @param object the owner of the property* @param name the name of the property* @param value the value of the property* @return true if the property will be included, false if to be filtered out* 根据 属性的name与value判断是否进行序列化*/boolean apply(Object object, String name, Object value);
}
- PropertyPreFilter根据PropertyName判断是否序列化
package com.alibaba.fastjson.serializer;public interface PropertyPreFilter extends SerializeFilter {//根据 object与name判断是否进行序列化boolean apply(JSONSerializer serializer, Object object, String name);
}
- NameFilter 序列化时修改Key
package com.alibaba.fastjson.serializer;public interface NameFilter extends SerializeFilter {
//根据 name与value的值,返回json字段key的值String process(Object object, String name, Object value);
}
- ValueFilter 序列化时修改Value
package com.alibaba.fastjson.serializer;public interface ValueFilter extends SerializeFilter {//根据name与value定制输出json的valueObject process(Object object, String name, Object value);
}
- BeforeFilter 在序列化对象的所有属性之前执行某些操作
package com.alibaba.fastjson.serializer;public abstract class BeforeFilter implements SerializeFilter {private static final ThreadLocal serializerLocal = new ThreadLocal();private static final ThreadLocal seperatorLocal = new ThreadLocal();private final static Character COMMA = Character.valueOf(',');final char writeBefore(JSONSerializer serializer, Object object, char seperator) {serializerLocal.set(serializer);seperatorLocal.set(seperator);writeBefore(object);serializerLocal.set(null);return seperatorLocal.get();}protected final void writeKeyValue(String key, Object value) {JSONSerializer serializer = serializerLocal.get();char seperator = seperatorLocal.get();serializer.writeKeyValue(seperator, key, value);if (seperator != ',') {seperatorLocal.set(COMMA);}}
//需要实现的方法,在实际实现中可以调用writeKeyValue增加json的内容public abstract void writeBefore(Object object);
}
- AfterFilter 在序列化对象的所有属性之后执行某些操作
package com.alibaba.fastjson.serializer;/*** @since 1.1.35*/
public abstract class AfterFilter implements SerializeFilter {private static final ThreadLocal serializerLocal = new ThreadLocal();private static final ThreadLocal seperatorLocal = new ThreadLocal();private final static Character COMMA = Character.valueOf(',');final char writeAfter(JSONSerializer serializer, Object object, char seperator) {serializerLocal.set(serializer);seperatorLocal.set(seperator);writeAfter(object);serializerLocal.set(null);return seperatorLocal.get();}protected final void writeKeyValue(String key, Object value) {JSONSerializer serializer = serializerLocal.get();char seperator = seperatorLocal.get();serializer.writeKeyValue(seperator, key, value);if (seperator != ',') {seperatorLocal.set(COMMA);}}
//子类需要实现的方法,实际使用的时候可以调用writeKeyValue增加内容public abstract void writeAfter(Object object);
}
- LabelFilter根据 JsonField配置的label来判断是否进行输出
package com.alibaba.fastjson.serializer;//根据 JsonField配置的label来判断是否进行输出
public interface LabelFilter extends SerializeFilter {boolean apply(String label);
}
泛型反序列化
fastjson通过TypeReference来实现泛型的反序列化,以下是一个简单的例子程序。首先定义了BaseDTO用于所有DTO的父类,代码如下:
package com.ivan.frame.dto.common;import java.io.Serializable;import com.alibaba.fastjson.JSONObject;public class BaseDTO implements Serializable{private static final long serialVersionUID = 2230553030766621644L;@Overridepublic String toString() {return JSONObject.toJSONString(this);}}
RequestDTO用于抽像所有的请求DTO,里面有个泛型参数,代码如下:
package com.ivan.frame.dto.common;public final class RequestDTO extends BaseDTO {private static final long serialVersionUID = -2780042604928728379L;/*** 调用方的名称*/private String caller;/*** 请求参数*/private T param;public String getCaller() {return caller;}public void setCaller(String caller) {this.caller = caller;}/*** 获取请求参数*/public T getParam() {return param;}/*** 设置请求参数* * @param param 请求参数*/public void setParam(T param) {this.param = param;}}
定义一个具体的业务对象, PersonDTO代码如下:
package com.ivan.frame.dto;import com.ivan.frame.dto.common.BaseDTO;public class PersonDTO extends BaseDTO {private static final long serialVersionUID = 4637634512292751986L;private int id;private int age;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
通过JSON.parseObject传入TypeReference对象进行泛型转换,代码如下:
package com.ivan.json;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ivan.frame.dto.PersonDTO;
import com.ivan.frame.dto.common.RequestDTO;public class GenericTest {public static void main(String[] args) {RequestDTO requestDTO = new RequestDTO();requestDTO.setCaller("callerId");PersonDTO personDTO = new PersonDTO();personDTO.setAge(11);personDTO.setName("张三");requestDTO.setParam(personDTO);String jsonString = JSON.toJSONString(requestDTO);System.out.println(jsonString);//这行是关键代码requestDTO = JSON.parseObject(jsonString, new TypeReference>(){});System.out.println(requestDTO.getParam().getName());}
}
fastjson各种概念
- JSON:本身是Abstract,提供了一系统的工具方法方便用户使用的API。
序列化相关的概念
- SerializeConfig:内部是个map容器主要功能是配置并记录每种Java类型对应的序列化类。
- SerializeWriter 继承自Java的Writer,其实就是个转为FastJSON而生的StringBuilder,完成高性能的字符串拼接。
- SerializeFilter: 用于对对象的序列化实现各种定制化的需求。
- SerializerFeature:对于对输出的json做各种格式化的需求。
- JSONSerializer:相当于一个序列化组合器,集成了SerializeConfig, SerializeWriter , SerializeFilter与SerializerFeature。
序列化的入口代码如下,上面提到的各种概念都包含了
public static String toJSONString(Object object, // SerializeConfig config, // SerializeFilter[] filters, // String dateFormat, //int defaultFeatures, // SerializerFeature... features) {SerializeWriter out = new SerializeWriter(null, defaultFeatures, features);try {JSONSerializer serializer = new JSONSerializer(out, config);if (dateFormat != null && dateFormat.length() != 0) {serializer.setDateFormat(dateFormat);serializer.config(SerializerFeature.WriteDateUseDateFormat, true);}if (filters != null) {for (SerializeFilter filter : filters) {serializer.addFilter(filter);}}serializer.write(object);return out.toString();} finally {out.close();}}
反序列化相关的概念
- ParserConfig:内部通过一个map保存各种ObjectDeserializer。
- JSONLexer : 与SerializeWriter相对应,用于解析json字符串。
- JSONToken:定义了一系统的特殊字符,这些称为token。
- ParseProcess :定制反序列化,类似于SerializeFilter。
- Feature:用于定制各种反序列化的特性。
- DefaultJSONParser:相当于反序列化组合器,集成了ParserConfig,Feature, JSONLexer 与ParseProcess。
反序列化的入口代码如下,上面的概念基本都包含了:
@SuppressWarnings("unchecked")public static T parseObject(String input, Type clazz, ParserConfig config, ParseProcess processor,int featureValues, Feature... features) {if (input == null) {return null;}if (features != null) {for (Feature feature : features) {featureValues |= feature.mask;}}DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues);if (processor != null) {if (processor instanceof ExtraTypeProvider) {parser.getExtraTypeProviders().add((ExtraTypeProvider) processor);}if (processor instanceof ExtraProcessor) {parser.getExtraProcessors().add((ExtraProcessor) processor);}if (processor instanceof FieldTypeResolver) {parser.setFieldTypeResolver((FieldTypeResolver) processor);}}T value = (T) parser.parseObject(clazz, null);parser.handleResovleTask(value);parser.close();return (T) value;}
与Spring MVC整合
fastjson提供了FastJsonHttpMessageConverter用于将Spring mvc里的body数据(必须是json格式)转成Controller里的请求参数或者将输出的对象转成json格式的数据。spring mvc里的核心配置如下:
text/html;charset=UTF-8 application/json;charset=UTF-8
WriteMapNullValue WriteNullStringAsEmpty
这里有一个注意点,当你用Spring 3或者fastjson使用的是1.1.x的版本,在转换带有泛型参数类型的时候无法进行转换,而在Spring4配合fastjson1.2.X的版本可以解决这个问题。FastJsonHttpMessageConverter read的核心代码如下:
public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
