FastJsonの詳細ガイド

FastJsonの概要

FastJsonはAlibabaが開発したオープンソースのJSON解析ライブラリです。JSON形式の文字列を解析し、JavaBeanをJSON文字列にシリアライズしたり、JSON文字列からJavaBeanにデシリアライズしたりすることができます。

FastJsonの利点

  • 高速性: FastJsonは他のJSONライブラリと比較して圧倒的な速度を誇ります。2011年に1.1.xバージョンがリリースされて以来、その性能は他のJava実装のJSONライブラリによって超えられたことがありません。
  • 幅広い採用: FastJsonはAlibabaで大規模に使用され、数千台のサーバーに展開されています。業界でも広く受け入れられ、2012年にはオープンソース中国によって最も人気のある国産オープンソースソフトウェアの一つに選ばれました。
  • 包括的なテスト: FastJsonは非常に多くのテストケースを持ち、1.2.11バージョンでは3321以上のテストケースがあります。各リリースごとに回帰テストが行われ、品質の安定性が保証されています。
  • 使いやすさ: FastJsonのAPIは非常にシンプルで直感的です。
  • 機能の充実: ジェネリクスのサポート、超大テキストのストリーム処理、列挙型のサポート、シリアライズおよびデシリアライズの拡張機能など、多彩な機能を提供します。

依存関係の追加

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

FastJsonシリアライズAPI

シリアライズとは、JavaオブジェクトをJSON形式の文字列に変換するプロセスです。JavaBeanオブジェクト、Listコレクションオブジェクト、Mapコレクションが最も広く使用されています。

Javaオブジェクトのシリアライズ

@Test
public void convertObjectToJson() {
    User user = new User();
    user.setUserId(1);
    user.setUserName("田中");
    user.setUserAge(25);
    user.setLocation("東京都");
    String jsonResult = JSON.toJSONString(user);
    System.out.println(jsonResult);
}
// 結果:
// {"location":"東京都","userAge":25,"userId":1,"userName":"田中"}

Listコレクションのシリアライズ

@Test
public void convertListToJson() {
    User user1 = new User();
    user1.setUserId(1);
    user1.setUserName("田中");
    user1.setUserAge(25);
    user1.setLocation("東京都");

    User user2 = new User();
    user2.setUserId(2);
    user2.setUserName("佐藤");
    user2.setUserAge(30);
    user2.setLocation("大阪府");

    List<User> userList = new ArrayList<>();
    userList.add(user1);
    userList.add(user2);
    String jsonResult = JSON.toJSONString(userList);
    System.out.println(jsonResult);
}
// 結果:
// [{"location":"東京都","userAge":25,"userId":1,"userName":"田中"},{"location":"大阪府","userAge":30,"userId":2,"userName":"佐藤"}]

Mapコレクションのシリアライズ

@Test
public void convertMapToJson() {
    User user1 = new User();
    user1.setUserId(1);
    user1.setUserName("田中");
    user1.setUserAge(25);
    user1.setLocation("東京都");

    User user2 = new User();
    user2.setUserId(2);
    user2.setUserName("佐藤");
    user2.setUserAge(30);
    user2.setLocation("大阪府");

    Map<String, User> userMap = new HashMap<>();
    userMap.put("firstUser", user1);
    userMap.put("secondUser", user2);
    String jsonResult = JSON.toJSONString(userMap);
    System.out.println(jsonResult); 
}
// 結果:
// {"firstUser":{"location":"東京都","userAge":25,"userId":1,"userName":"田中"},"secondUser":{"location":"大阪府","userAge":30,"userId":2,"userName":"佐藤"}}

FastJsonデシリアライズAPI

Javaオブジェクトへのデシリアライズ

@Test
public void convertJsonToObject() {
    String jsonData = "{\"location\":\"東京都\",\"userAge\":25,\"userId\":1,\"userName\":\"田中\"}";
    User user = JSON.parseObject(jsonData, User.class);
    System.out.println(user);
}
// 結果:
// User(userId=1, userName=田中, userAge=25, location=東京都)

Listコレクションへのデシリアライズ

@Test
public void convertJsonToList() {
    String jsonData = "[{\"location\":\"東京都\",\"userAge\":25,\"userId\":1,\"userName\":\"田中\"},{\"location\":\"大阪府\",\"userAge\":30,\"userId\":2,\"userName\":\"佐藤\"}]";
    List<User> userList = JSON.parseArray(jsonData, User.class);
    for (User user : userList) {
        System.out.println(user);
    }
}
// 結果:
// User(userId=1, userName=田中, userAge=25, location=東京都)
// User(userId=2, userName=佐藤, userAge=30, location=大阪府)

Mapコレクションへのデシリアライズ(ジェネリクス付き)

@Test
public void convertJsonToMap() {
    String jsonData = "{\"firstUser\":{\"location\":\"東京都\",\"userAge\":25,\"userId\":1,\"userName\":\"田中\"},\"secondUser\":{\"location\":\"大阪府\",\"userAge\":30,\"userId\":2,\"userName\":\"佐藤\"}}";
    Map<String, User> resultMap = JSON.parseObject(jsonData, new TypeReference<Map<String, User>>(){});

    for (Map.Entry<String, User> entry : resultMap.entrySet()) {
        System.out.println(entry.getKey() + ":::" + entry.getValue());
    }
}
// 結果:
// firstUser:::User(userId=1, userName=田中, userAge=25, location=東京都)
// secondUser:::User(userId=2, userName=佐藤, userAge=30, location=大阪府)

SerializerFeature列挙型

デフォルトではnullのフィールドは表示されません

@Test
public void testDefaultBehavior() {
    User user = new User();
    user.setUserId(1);
    user.setUserName(null);
    user.setUserAge(25);
    // user.setLocation("東京都");
    user.setRegistrationDate(new Date());
    String jsonResult = JSON.toJSONString(user);
    System.out.println(jsonResult);
}
// 結果:
// {"registrationDate":1684245428959,"userAge":25,"userId":1}

列挙定数WriteMapNullValueを使用してnullフィールドをシリアライズ:

@Test
public void testNullSerialization() {
    User user = new User();
    user.setUserId(1);
    user.setUserName(null);
    user.setUserAge(25);
    // user.setLocation("東京都");
    String jsonResult = JSON.toJSONString(user, SerializerFeature.WriteMapNullValue);
    System.out.println(jsonResult);
}
// 結果:
// {"location":null,"registrationDate":1684245428959,"userAge":25,"userId":1,"userName":null}

列挙定数WriteNullStringAsEmptyを使用してnullフィールドを空文字列に:

@Test
public void testEmptyStringForNull() {
    User user = new User();
    user.setUserId(1);
    user.setUserName(null);
    user.setUserAge(25);
    // user.setLocation("東京都");
    String jsonResult = JSON.toJSONString(user, SerializerFeature.WriteNullStringAsEmpty);
    System.out.println(jsonResult);
}
// 結果:
// {"location":"","userAge":25,"userId":1,"userName":""}

列挙定数WriteNullNumberAsZeroを使用してnull数値を0に、WriteNullBooleanAsFalseを使用してnullブール値をfalseに:

@Test
public void testDefaultValuesForNull() {
    User user = new User();
    user.setUserId(1);
    user.setUserName(null);
    user.setUserAge(null);  // nullの数値
    user.setActive(null);   // nullのブール値
    String jsonResult = JSON.toJSONString(user, 
        SerializerFeature.WriteNullNumberAsZero, 
        SerializerFeature.WriteNullBooleanAsFalse);
    System.out.println(jsonResult);
}
// 結果:
// {"active":false,"userAge":0,"userId":1,"userName":""}

フォーマット機能

列挙定数PrettyFormatを使用した整形出力とWriteDateUseDateFormatを使用した日付フォーマット:

@Test
public void testFormattingFeatures() {
    User user = new User();
    user.setUserId(1);
    user.setUserName("田中");
    user.setUserAge(25);
    user.setRegistrationDate(new Date());
    
    String jsonResult = JSON.toJSONString(user, 
        SerializerFeature.WriteDateUseDateFormat, 
        SerializerFeature.PrettyFormat);
    
    System.out.println(jsonResult);
}
// 結果:
// {
// 	"registrationDate":"2023-05-16 21:54:20",
// 	"userAge":25,
// 	"userId":1,
// 	"userName":"田中"
// }

@JSONFieldアノテーション

このアノテーションはメソッド、フィールド、パラメータに作用します。シリアライズおよびデシリアライズ時に機能をカスタマイズできます。

アノテーション属性

  • name: シリアライズ後の名前
  • ordinal: シリアライズ後の順序
  • format: シリアライズ後のフォーマット
  • serialize: このフィールドをシリアライズするかどうか
  • deserialize: このフィールドをデシリアライズするかどうか
  • serialzeFeatures: シリアライズ時の特性定義
@Data
public class User {
    @JSONField(ordinal = 2)
    private Integer userId;
    @JSONField(name = "fullName")
    private String userName;
    @JSONField(ordinal = 1)
    private Integer userAge;
    @JSONField(serialize = false)
    private String location;
    @JSONField(format = "yyyy-MM-dd")
    private Date registrationDate;
    @JSONField(name = "isActive")
    private Boolean active;
}
@Test
public void testJsonFieldAnnotation() {
    User user = new User();
    user.setUserId(1);
    user.setUserName("田中");
    user.setUserAge(25);
    user.setLocation("東京都");
    user.setRegistrationDate(new Date());
    user.setActive(true);
    String jsonResult = JSON.toJSONString(user);
    System.out.println(jsonResult);
}
// 結果:
// {"fullName":"田中","userAge":25,"userId":1,"registrationDate":"2023-05-16","isActive":true}

@JSONTypeアノテーション

このアノテーションはクラスに作用し、そのクラスのフィールドのシリアライズおよびデシリアライズ時の機能をカスタマイズします。

アノテーション属性

  • includes: シリアライズするフィールド
  • orders: シリアライズ後の順序
  • serialzeFeatures: シリアライズ時の特性定義
@Data
@JSONType(includes = {"userId", "userName", "userAge"}, orders = {"userAge", "userId", "userName"})
public class User {
    private Integer userId;
    private String userName;
    private Integer userAge;
    private String location;
    private Date registrationDate;
    private Boolean active;
}
@Test
public void testJsonTypeAnnotation() {
    User user = new User();
    user.setUserId(1);
    user.setUserName("田中");
    user.setUserAge(25);
    user.setLocation("東京都");
    user.setRegistrationDate(new Date());
    user.setActive(true);
    String jsonResult = JSON.toJSONString(user);
    System.out.println(jsonResult);
}
// 結果:
// {"userAge":25,"userId":1,"userName":"田中"}

8月6日 01:25 投稿