赞
踩
fastjson用于将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
简单使用
- <dependencies>
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.49</version>
- </dependency>
- </dependencies>
- 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;
- }
-
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- 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());
- }
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
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);
-
- }
-
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
输出的结果如下:
使用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;
- //字段级别的SerializerFeature
- SerializerFeature[] 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;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
其中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);
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
反序列化类代码如下:
- 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> 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;
- }
-
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
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 {};
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
SerializeFilter
fastjson通过SerializeFilter编程扩展的方式定制序列化fastjson支持以下SerializeFilter用于不同常景的定制序列化:
- 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);
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- package com.alibaba.fastjson.serializer;
-
- public interface PropertyPreFilter extends SerializeFilter {
-
- //根据 object与name判断是否进行序列化
- boolean apply(JSONSerializer serializer, Object object, String name);
- }
- package com.alibaba.fastjson.serializer;
-
- public interface NameFilter extends SerializeFilter {
- //根据 name与value的值,返回json字段key的值
- String process(Object object, String name, Object value);
- }
-
- package com.alibaba.fastjson.serializer;
-
- public interface ValueFilter extends SerializeFilter {
- //根据name与value定制输出json的value
- Object process(Object object, String name, Object value);
- }
-
- package com.alibaba.fastjson.serializer;
-
- public abstract class BeforeFilter implements SerializeFilter {
-
- private static final ThreadLocal<JSONSerializer> serializerLocal = new ThreadLocal<JSONSerializer>();
- private static final ThreadLocal<Character> seperatorLocal = new ThreadLocal<Character>();
-
- 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);
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- package com.alibaba.fastjson.serializer;
-
- /**
- * @since 1.1.35
- */
- public abstract class AfterFilter implements SerializeFilter {
-
- private static final ThreadLocal<JSONSerializer> serializerLocal = new ThreadLocal<JSONSerializer>();
- private static final ThreadLocal<Character> seperatorLocal = new ThreadLocal<Character>();
-
- 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);
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- 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;
-
- @Override
- public String toString() {
- return JSONObject.toJSONString(this);
- }
-
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
RequestDTO用于抽像所有的请求DTO,里面有个泛型参数,代码如下:
- package com.ivan.frame.dto.common;
-
-
- public final class RequestDTO<T extends BaseDTO> 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;
- }
-
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
定义一个具体的业务对象, 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;
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
通过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<PersonDTO> requestDTO = new RequestDTO<PersonDTO>();
- 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<RequestDTO<PersonDTO>>(){});
-
-
- System.out.println(requestDTO.getParam().getName());
- }
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
fastjson各种概念
序列化相关的概念
- 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();
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
反序列化相关的概念
- @SuppressWarnings("unchecked")
- public static <T> 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;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
与Spring MVC整合
fastjson提供了FastJsonHttpMessageConverter用于将Spring mvc里的body数据(必须是json格式)转成Controller里的请求参数或者将输出的对象转成json格式的数据。spring mvc里的核心配置如下:
- <mvc:annotation-driven conversion-service="conversionService">
- <mvc:message-converters register-defaults="true">
- <bean
- class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
- <property name="supportedMediaTypes">
- <list>
- <value>text/html;charset=UTF-8</value>
- <value>application/json;charset=UTF-8</value>
- </list>
- </property>
- <property name="features">
- <array>
- <value>WriteMapNullValue</value>
- <value>WriteNullStringAsEmpty</value>
- </array>
- </property>
- </bean>
- </mvc:message-converters>
- </mvc:annotation-driven>
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
这里有一个注意点,当你用Spring 3或者fastjson使用的是1.1.x的版本,在转换带有泛型参数类型的时候无法进行转换,而在Spring4配合fastjson1.2.X的版本可以解决这个问题。FastJsonHttpMessageConverter read的核心代码如下:
- public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter<Object>//
- implements GenericHttpMessageConverter<Object> {
-
- //将json转成javabean的时候会调用。这里的type
- public Object read(Type type, //
- Class<?> contextClass, //
- HttpInputMessage inputMessage //
- ) throws IOException, HttpMessageNotReadableException {
- return readType(getType(type, contextClass), inputMessage);
- }
-
- //这里会通过Spring4TypeResolvableHelper得到类型参数,
- protected Type getType(Type type, Class<?> contextClass) {
- if (Spring4TypeResolvableHelper.isSupport()) {
- return Spring4TypeResolvableHelper.getType(type, contextClass);
- }
-
- return type;
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。