Skip to content

FastJson 简介

Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,也可以将 JSON 字符串转换为 Java 对象。

Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。

但不推荐使用FastJson,原因如下:

  • FastJson 源码质量较低
  • FastJson Bug、漏洞较多
  • FastJson 牺牲多数场景下的稳定性而提高的效率

官方仓库与文档

Fastjson 特性

  • 提供服务器端、安卓客户端两种解析工具,性能表现较好。
  • 提供了 toJSONString()parseObject() 方法来将 Java 对象与 JSON 相互转换。
    • toJSONString() 方法:将对象转换成 JSON 字符串。
    • parseObject() 方法:将 JSON 字符串转换成对象。
  • 允许转换预先存在的无法修改的对象(只有 class、无源代码)。
  • Java 泛型的广泛支持。
  • 允许对象的自定义表示、允许自定义序列化类。
  • 支持任意复杂对象(具有深厚的继承层次和广泛使用的泛型类型)。

FastJson 基础使用

引入 maven 依赖

xml
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>x.x.x</version>
</dependency>

其中 x.x.x 是版本号,根据需要使用特定版本,建议使用最新版本。

序列化对象成 JSON 字符串

java
User user = new User();
user.setName("校长");
user.setAge(3);
user.setSalary(new BigDecimal("123456789.0123"));
String jsonString = JSON.toJSONString(user);
System.out.println(jsonString);
// 输出 {"age":3,"name":"校长","old":false,"salary":123456789.0123}

反序列化 JSON 字符串成 Java 对象

java
String jsonString = "{\"age\":3,\"birthdate\":1496738822842,\"name\":\"校长\",\"old\":true,\"salary\":123456789.0123}";
 User u = JSON.parseObject(jsonString ,User.class);
 System.out.println(u.getName());
 // 输出 校长

String jsonStringArray = "[{\"age\":3,\"birthdate\":1496738822842,\"name\":\"校长\",\"old\":true,\"salary\":123456789.0123}]";
List<User> userList = JSON.parseArray(jsonStringArray, User.class);
System.out.println(userList.size());
// 输出 1

对于日期的处理

默认序列化 Date 对象输出使用 yyyy-MM-dd HH:mm:ss 格式,可以用 UseISO8601DateFormat 特性换成 yyyy-MM-dd 或者 HH:mm:ss 格式。

java
JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai");
JSON.defaultLocale = Locale.US;
        
public static class Model {

    @JSONField(format = "MMM dd, yyyy h:mm:ss aa")
    private java.util.Date date;

    public java.util.Date getDate() {
        return date;
    }

    public void setDate(java.util.Date date) {
        this.date = date;
    }

    @JSONField(format = "MMM-dd-yyyy h:mm:ss aa")
    public java.sql.Date date2;
}

BeanToArray

在 fastjson 中,支持一种叫做 BeanToArray 的映射模式。普通模式下,JavaBean 映射成 json object,BeanToArray 模式映射为 json array。

Sample 1:在 BeanToArray 模式下,少了 Key 的输出,节省了空间,json 字符串较小,性能也会更好。

java
class Model {
   public int id;
   public String name;
}

Model model = new Model();
model.id = 1001;
model.name = "gaotie";

// {"id":1001,"name":"gaotie"}
String text_normal = JSON.toJSONString(model); 

// [1001,"gaotie"]
String text_beanToArray = JSON.toJSONString(model, SerializerFeature.BeanToArray); 

// support beanToArray & normal mode
JSON.parseObject(text_beanToArray, Feature.SupportArrayToBean);

Sample 2:BeanToArray 可以局部使用。如果 Company 的属性 departments 元素很多,局部采用 BeanToArray 就可以获得很好的性能,而整体又能够获得较好的可读性。

java
class Company {
     public int code;
     public List<Department> departments = new ArrayList<Department>();
}

@JSONType(serialzeFeatures=SerializerFeature.BeanToArray, parseFeatures=Feature.SupportArrayToBean)
class Department {
     public int id;
     public String name;
     public Department() {}
     public Department(int id, String name) {this.id = id; this.name = name;}
}


Company company = new Company();
company.code = 100;
company.departments.add(new Department(1001, "Sales"));
company.departments.add(new Department(1002, "Financial"));

// {"code":10,"departments":[[1001,"Sales"],[1002,"Financial"]]}
String text = JSON.toJSONString(company);

Sample 3:示例2的改进版

java
class Company {
     public int code;

     @JSONField(serialzeFeatures=SerializerFeature.BeanToArray, parseFeatures=Feature.SupportArrayToBean)
     public List<Department> departments = new ArrayList<Department>();
}

设置字段名

java
public class A {
    @JSONField(name="ID")
    private int id;

    public int getId() {return id;}
    public void setId(int value) {this.id = id;}
}

设置是否不序列化某字段

java
public class A {
    @JSONField(serialize=false)
    public Date date;
}

public class A {
    @JSONField(deserialize=false)
    public Date date;
}

设置字段顺序

java
public static class VO {
    @JSONField(ordinal = 3)
    private int f0;

    @JSONField(ordinal = 2)
    private int f1;

    @JSONField(ordinal = 1)
    private int f2;
}

自定义序列化和反序列化

参考资料:

I know where dry desert ends, green grass grows · MooN