java json含义,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);

}

}

输出的结果如下:

eaeaa5dce258

使用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;

}

其中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的value

Object 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;

@Override

public 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里的核心配置如下:

class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">

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//

implements GenericHttpMessageConverter {

//将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;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值