25
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Jacksonメモ

Last updated at Posted at 2014-09-05

Jackson の使い方などのメモ
今後追加していく予定

JSON変換高速化

Jacksonでの JSON への変換時にボトルネックとなっている部分として、どうにも ObjectMapper のインスタンスの生成が遅い気がする。
さらに、マルチスレッドで並列に生成しようとすると、排他処理がかかっているのか(ソースを見ていないので違っていたらゴメンナサイ)、シリアルにJSON変換が行われているように見える。

そこで、ObjectMapperがスレッドセーフであれば、あらかじめ生成した ObjectMapper を使いまわす事で、処理の高速化を計れそう。

っということで、ObjectMapperがスレッドセーフか調査

http://wiki.fasterxml.com/JacksonFAQ

Is ObjectMapper thread-safe?

Short answer: yes

Long answer: yes, as long as you always configure instance before use, and do not call configure methods during operation (or synchronize such calls appropriately). Usually it is better to construct separate mapper instance if configurations differ in any case.

Further: it is beneficial to use just one instance (or small number of instances) for data binding; many optimizations for reuse (of symbol tables, some buffers) depend on ObjectMapper instances being reused.

For more information, check out JacksonFAQThreadSafety

どうやら、read/wirte中にObjectMapperの設定が変更されなければスレッドセーフということなので、
単純な使い方だけなら問題なさそう。

#ジェネリクスのJSONデシリアライズ

ジェネリクスをJSONにシリアライズすることは特に意識しなくてもできるが、
それを再度デシリアライズしてオブジェクトに戻そうとすると、
JsonMappingException が発生してしまう。

これの解決策として、@JsonTypeInfo で型情報を一緒にJSONに出力することで、ジェネリクスでもJSONからオブジェクトにデシリアライズできる

#####サンプル

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, property="classType")
public abstract class SuperClass {
    public int id;
}

public class SubClass extends SuperClass {
    public String name;
}

public class DerivedClass extends SuperClass {
    public int number;
}

public class Array extends SuperClass {
    List<SuperClass> list = new ArrayList<SuperClass>();
}


public static void main() {

   SubClass sub = new SubClass();
   sub.id = 1234;
   sub.name = "aiueo";

   DerivedClass derived = new DerivedClass();
   derived.id = 5678;
   derived.number = 1;

   Array hoge = new Array();
   hoge.list.add(sub);
   hoge.list.add(derived);

   ObjectMapper mapper = new ObjectMapper();
   String json = mapper.writeValueAsString(hoge);
   
   System.out.println(json);
   
   Array hoge2 = mapper.readValue(json, Array.class);
   String json2 = mapper.writeValueAsString(hoge2);
   System.out.println("desirialize success ?");
   System.out.println(json.equals(json2));
}

#####結果


{
    "classType": "Array",
    "id": 0,
    "list": [
        {
            "classType": "SubClass",
            "id": 1234,
            "name": "aiueo"
        },
        {
            "classType": "DerivedClass",
            "id": 5678,
            "number": 1
        }
    ]
}

desirialize success ?
true

###JsonTypeInfo

■ use 属性

型情報の出力方法を指定。
今回は Id.CLASS を指定しているので、パッケージを含めたクラス名で出している

■ propety 属性

JSON出力時のキー名を指定。

制限

サンプルにある Array クラスが以下のようになっている場合、JsonTypeInfo が出力されません。
おそらく list 内で、JsonTypeInfo を出力できないクラスが混じる可能性がある場合は出力しないようになっているのではないかと思われ・・・

public class Array extends SuperClass {
    //List<SuperClass> list = new ArrayList<SuperClass>();
    List<Object> list = new ArrayList<Object>();
}

デシリアライズ時のコンストラクタ指定

こちら

Jackson でオブジェクトの Serializer を作ってみる

こちら

25
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?