文章目录
  1. 1. Get It
    1. 1.1. Maven
    2. 1.2. 下载
  2. 2. 特点
  3. 3. 主要API
  4. 4. 实例
    1. 4.1. User
    2. 4.2. Group
    3. 4.3. Encode
    4. 4.4. Decode
    5. 4.5. Attention
  5. 5. 处理日期
  6. 6. 浏览器和设备兼容
  7. 7. 定制序列化
    1. 7.1. transient
    2. 7.2. 使用Annotation过滤字段
    3. 7.3. 使用SimplePropertyPreFilter过滤属性
    4. 7.4. 定制序列化
  8. 8. 处理超大对象和JSON文本
    1. 8.1. 序列化
      1. 8.1.1. 超大JSON数组序列化
      2. 8.1.2. 超大JSON对象序列化
    2. 8.2. 反序列化
      1. 8.2.1. 大数组
      2. 8.2.2. 大对象

Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景。

Get It

Maven

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.1.41</version>
</dependency>

下载

  1. maven中央仓库
  2. Alibaba OpenSesame
  3. Github Download

特点

  1. FAST:measured to be faster than any other Java parser and databinder, incudes jackson.
  2. Powerful:full data binding for common JDK classes as well as any Java Bean class, Collection, Map, Date or enum
  3. Zero-dependency:does not rely on other packages beyond JDK
  4. Open Source

主要API

fastjson入口类是com.alibaba.fastjson.JSON,主要的API是JSON.toJSONString,和parseObject。

package com.alibaba.fastjson;
public abstract class JSON {
    public static final String toJSONString(Object object);
    public static final <T> T parseObject(String text, Class<T> clazz, Feature... features);
}

序列化:

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>>() {});

实例

User

public class User {

    private Long   id;
    private String name;

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

Group

public class Group {

    private Long       id;
    private String     name;
    private List<User> users = new ArrayList<User>();

    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 List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }
}

Encode

import com.alibaba.fastjson.JSON;

Group group = new Group();
group.setId(0L);
group.setName("admin");

User guestUser = new User();
guestUser.setId(2L);
guestUser.setName("guest");

User rootUser = new User();
rootUser.setId(3L);
rootUser.setName("root");

group.getUsers().add(guestUser);
group.getUsers().add(rootUser);

String jsonString = JSON.toJSONString(group);

System.out.println(jsonString);

Decode

String jsonString = ...;
Group group = JSON.parseObject(jsonString, Group.class);

Attention

如何Java类中定义了带有参数的构造函数,那我们就必须加上默认的构造函数,否则不能解析。(fastjson 严格按照JavaBean的规范来,每一个实体类的属性的get和set方法也都必须写,且方法第四个字母必须大写)

处理日期

fastjson处理日期的API很简单,例如:

JSON.toJSONStringWithDateFormat(date, "yyyy-MM-dd HH:mm:ss.SSS")

使用ISO-8601日期格式

JSON.toJSONString(obj, SerializerFeature.UseISO8601DateFormat);

全局修改日期格式

JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd";
JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat);

反序列化能够自动识别如下日期格式:

  • ISO-8601日期格式
  • yyyy-MM-dd
  • yyyy-MM-dd HH:mm:ss
  • yyyy-MM-dd HH:mm:ss.SSS
  • 毫秒数字
  • 毫秒数字字符串
  • .NET JSON日期格式
  • new Date(198293238)

浏览器和设备兼容

fastjson缺省的序列化内容,是对序列化结果紧凑做了优化配置,使得序列化之后长度更小,但是这种优化配置是对一些浏览器和设备不兼容的。比如说在iphone上兼容emoji(绘文字)。

JSON.toJSONString(o,SerializerFeature.BrowserCompatible);

可以选择的SerializerFeature有很多,可以按照自己的需要去选择使用。

定制序列化

transient

为某些属性加上transient关键字,该属性就不会进行序列化。

private transient Long id;

使用Annotation过滤字段

使用@JSONField定制序列化输出,比如,希望希望序列化采用之后采用”ID”,而不是”id”。

@JSONField(name = "ID")
private Long id;

如果没有缺省构造函数,可以使用@JSONCreator来指定

@JSONCreator
public User(@JSONField(name="id")Long id) {
    this.id = id;
    this.name = "annotation";
}

使用JSONType修改属性顺序、忽略某些属性等

@JSONType(orders = {"name", "id"})
public class User {
    。。。。
}

使用SimplePropertyPreFilter过滤属性

SimplePropertyPreFilter的代码接口如下:

public class SimplePropertyPreFilter implements PropertyPreFilter {      
  public SimplePropertyPreFilter(String... properties){
      this(null, properties);
  }

  public SimplePropertyPreFilter(Class<?> clazz, String... properties){
      ... ...
  }

  public Class<?> getClazz() {
      return clazz;
  }

  public Set<String> getIncludes();

  public Set<String> getExcludes();
...
}

可以配置includes、excludes。当class不为null时,针对特定类型;当class为null时,针对所有类型。

当includes的size > 0时,属性必须在includes中才会被序列化,excludes优先于includes。

在1.1.23版本之后,JSON提供新的序列化接口toJSONString,如下:

String toJSONString(Object, SerializeFilter, SerializerFeature...);

使用:

SimplePropertyPreFilter filter = new SimplePropertyPreFilter(VO.class, "name");
JSON.toJSONString(vo, filter));

定制序列化

fastjson支持定制序列化,提供定制序列化的方式包括:

// 根据PropertyName判断是否序列化
public interface PropertyPreFilter extends SerializeFilter {
  boolean apply(JSONSerializer serializer, Object object, String name);
}

// 根据PropertyName和PropertyValue来判断是否序列化
public interface PropertyFilter extends SerializeFilter {
  boolean apply(Object object, String propertyName, Object propertyValue);
}

// 修改Key,如果需要修改Key,process返回值则可
public interface NameFilter extends SerializeFilter {
  String process(Object object, String propertyName, Object propertyValue);
}

// 修改Value
public interface ValueFilter extends SerializeFilter {
  Object process(Object object, String propertyName, Object propertyValue);
}

// 序列化时在最前添加内容
public abstract class BeforeFilter implements SerializeFilter {
  protected final void writeKeyValue(String key, Object value) { ... }
  // 需要实现的抽象方法,在实现中调用writeKeyValue添加内容
  public abstract void writeBefore(Object object);
}


// 序列化时在最前添加内容
public abstract class AfterFilter implements SerializeFilter {
  protected final void writeKeyValue(String key, Object value) { ... }
  // 需要实现的抽象方法,在实现中调用writeKeyValue添加内容
  public abstract void writeAfter(Object object);
}

以上的SerializeFilter在JSON.toJSONString中可以使用。

SerializeFilter filter = ...; // 可以是上面5个SerializeFilter的任意一种。
JSON.toJSONString(obj, filter);

处理超大对象和JSON文本

当需要处理超大JSON文本时,需要Stream API,在fastjson-1.1.32版本中开始提供Stream API。

序列化

超大JSON数组序列化

如果你的JSON格式是一个巨大的JSON数组,有很多元素,则先调用startArray,然后挨个写入对象,然后调用endArray。

JSONWriter writer = new JSONWriter(new FileWriter("/tmp/huge.json"));
writer.startArray();
for (int i = 0; i < 1000 * 1000; ++i) {
    writer.writeValue(new VO());
}
writer.endArray();
writer.close();

超大JSON对象序列化

如果你的JSON格式是一个巨大的JSONObject,有很多Key/Value对,则先调用startObject,然后挨个写入Key和Value,然后调用endObject。

JSONWriter writer = new JSONWriter(new FileWriter("/tmp/huge.json"));
writer.startObject();
for (int i = 0; i < 1000 * 1000; ++i) {
    writer.writeKey("x" + i);
    writer.writeValue(new VO());
}
writer.endObject();
writer.close();

反序列化

大数组

JSONReader reader = new JSONReader(new FileReader("/tmp/huge.json"));
reader.startArray();
while(reader.hasNext()) {
    VO vo = reader.readObject(VO.class);
    // handle vo ...
}
reader.endArray();
reader.close();

大对象

JSONReader reader = new JSONReader(new FileReader("/tmp/huge.json"));
reader.startObject();
while(reader.hasNext()) {
    String key = reader.readString();
    VO vo = reader.readObject(VO.class);
    // handle vo ...
}
reader.endObject();
reader.close();
文章目录
  1. 1. Get It
    1. 1.1. Maven
    2. 1.2. 下载
  2. 2. 特点
  3. 3. 主要API
  4. 4. 实例
    1. 4.1. User
    2. 4.2. Group
    3. 4.3. Encode
    4. 4.4. Decode
    5. 4.5. Attention
  5. 5. 处理日期
  6. 6. 浏览器和设备兼容
  7. 7. 定制序列化
    1. 7.1. transient
    2. 7.2. 使用Annotation过滤字段
    3. 7.3. 使用SimplePropertyPreFilter过滤属性
    4. 7.4. 定制序列化
  8. 8. 处理超大对象和JSON文本
    1. 8.1. 序列化
      1. 8.1.1. 超大JSON数组序列化
      2. 8.1.2. 超大JSON对象序列化
    2. 8.2. 反序列化
      1. 8.2.1. 大数组
      2. 8.2.2. 大对象