Skip to content

Instantly share code, notes, and snippets.

@wtokuno
Created March 7, 2012 21:07
Show Gist options
  • Select an option

  • Save wtokuno/1996260 to your computer and use it in GitHub Desktop.

Select an option

Save wtokuno/1996260 to your computer and use it in GitHub Desktop.
Jackson - JSON Processor

䞋曞き

Jacksonずは

JacsonはJSON(JavaScript Object Notation)ず呌ばれるデヌタ蚘述蚀語を扱うためのJavaラむブラリ。

りェブアプリケヌション開発ではJSONが必須の技術になっおきおいる。 JavaでJSONを扱うためのAPIがJava EE 7に含たれる予定。JSR 343ずしお仕様策定䞭。

JSONずは

JSONはJavaScriptのリテラル衚蚘をベヌスにしたデヌタ蚘述蚀語。 クラむアントのりェブブラりザなどで利甚できるJavaScriptで容易に扱えるから、Webサヌバずのデヌタ亀換フォヌマットずしお広く利甚されおいる。

JSONの仕様

RFC 4627で仕様が芏定されおいる。 たたjson.orgでもJSONの仕様を確認するこずができる。 json.orgには日本語のペヌゞも甚意されおいるので英語が苊手な方はこちらを参照。

JSONの抂芁

JSONには6぀のデヌタ型がある。

  • オブゞェクト
  • 配列
  • 文字列
  • 数倀
  • 真停倀
  • null倀

オブゞェクト

オブゞェクトは名前ず倀のペアを集めたデヌタ構造。

{ず}の間に名前ず倀のペアをカンマ区切りで衚蚘する。 名前ず倀のペアは:で区切っお衚蚘する。 名前には文字列の衚蚘を䜿う。 倀には任意のJSONのデヌタを蚘述できる。 スカラヌ倀だけでなく、デヌタ構造も蚘述できるので、オブゞェクトや配列がネストした耇雑なデヌタを衚珟するこずができる。

オブゞェクトの衚蚘䟋

{}                                      // 空オブゞェクト
{"val":null}                            // nullを倀に持぀
{"val1":false, "val2":true}             // 真停倀を倀に持぀
{"val1":123, "val2":12.3, "val3":12E3}  // 数倀を倀に持぀
{"val1":null, "val2":false, "val3":123} // 倀の型が䞀様でなくおもよい
// 倀に配列やオブゞェクトを持぀こずもできる
{
  "extensions": ["java", "js"],
  "java":{"name":"Java", "typing":"static"},
  "js":{"name":"JavaScript", "typing":"dynamic"}
}
{"":"empty"}                            // 名前の郚分は空文字列でもよい

間違ったオブゞェクト衚蚘䟋

{val:"wrong name"}                      // 名前が二重匕甚笊で囲たれおいない
{'val':"wrong name"}                    // 名前が単匕甚笊で囲たれおいる
{123:"wrong name"}                      // 名前が文字列でない
{"val1":"Java", "val2":"JavaScript",}   // 䜙蚈なカンマ
{"val1":"Java", , "val2":"JavaScript"}  // 連続する2぀のカンマ

名前ず倀のペアの衚蚘順序は通垞は意味を持たない。 名前ず倀のペアの衚蚘順序が異なるオブゞェクトであっおも、同じ名前ず倀のペアのセットが衚蚘されおいるなら、それらは意味的に同じ倀を持぀オブゞェクトである。

配列

配列は順序付きで倀を集めたデヌタ構造。

[ず]の間に芁玠ずなる倀をカンマ区切りで衚蚘する。 芁玠には任意のJSONのデヌタを蚘述できる。 スカラヌ倀だけでなく、(以䞋オブゞェクトず同じ)

配列の衚蚘䟋
空配列
倀にスカラヌ
芁玠のデヌタ型が䞀様でない
ネストした耇雑なデヌタ構造
誀った配列の衚蚘䟋
䜙蚈なカンマ
最埌の芁玠の埌ろに䜙蚈なカンマがある
芁玠の間に䜙蚈なカンマがある(2぀以䞊のカンマがある)

配列の芁玠は通垞は順序を持぀デヌタ構造ずしお衚珟される。 衚蚘されおいる芁玠の順序がそのたた配列のデヌタ構造での順序ずなる。

文字列

文字列は文字の䞊びを二重匕甚笊"で囲んで衚蚘する。 二重匕甚笊、バックスラッシュ、制埡文字(U+0000から`U+001F)を文字列の䞭に含めるにぱスケヌプする必芁がある。

゚スケヌプの衚蚘方法は2皮類ある。

䞀぀はよく䜿う文字をバックスラッシュず特定のASCII文字の2文字で衚蚘する方法。 この方法で衚蚘できる゚スケヌプは次の通り。

  • \": 二重匕甚笊(", U+0022)
  • \\: バックスラッシュ(\, U+005C)
  • \/: スラッシュ(/, U+002F)
  • \b: バックスペヌス(U+0008)
  • \f: フォヌムフィヌド(U+000C)
  • \n: 改行、ラむンフィヌド(U+000A)
  • \r: 埩垰、キャリッゞリタヌン(U+000D)
  • \t: 氎平タブ(U+0009)

もう䞀぀はナニコヌドのコヌドポむントを衚蚘する方法。 ゚スケヌプ察象の文字が基本倚蚀語面(BMP, U+0000からU+FFFF)の範囲であるなら、バックスラッシュ\ずuに続けお4桁の16進数でコヌドポむントを衚蚘するこずで゚スケヌプする。 基本倚蚀語面の範囲倖の拡匵文字はUTF-16のサロゲヌトペアを組み合わせお衚珟する。

文字列の衚蚘䟋
空文字列
ASCIIの範囲の文字列
ASCII範囲倖の文字列
゚スケヌプの䟋
2文字゚スケヌプ
コヌドポむントの゚スケヌプ
サロゲヌトペア
誀った文字列の衚蚘䟋
単匕甚笊で囲む

数倀

数倀は笊号郚、敎数郚、小数郚、指数郚をこの順序で組み合わせお衚蚘する。

笊号郚マむナス蚘号-で衚蚘する。プラス笊号+を䜿うこずはできず、正の倀の堎合には笊号郚を省略する。

敎数郚は10進数の数字の列。敎数郚の倀が0である堎合を陀いお、0で始たる衚蚘はできない。 敎数郚は省略できない。

小数郚も10進数の数字の列。小数郚は䜙蚈な0が埌ろにあっおもよい。敎数郚ず小数郚は小数点.で区切る。 小数郚は省略できる。

指数郚は笊号ず10進数の数倀の列で衚蚘する。 指数郚の笊号には-笊号だけでなく+笊号も䜿える。指数郚の10進数の数倀の列は䜙蚈な0で始たっおいおもよい。 敎数郚や小数郚ず、指数郚はeかEのどちらか区切る。指数郚は省略できる。

数倀の衚蚘䟋
れロ
敎数
マむナス
小数
指数
小数ず指数の組み合わせ
誀った数倀の衚蚘䟋
+笊号を぀ける
敎数郚を省略

真停倀

真停倀はtrueやfalseず衚蚘する。すべお小文字でなければならない。

真停倀の衚蚘䟋
true
false
誀った衚蚘䟋
倧文字

null倀

null倀は意味のある倀がないこずを瀺す。null倀はnullず衚蚘する。すべお小文字でなければならない。

null倀の衚蚘䟋
null
誀った衚蚘䟋
倧文字

JSONずJavaScriptの衚蚘の違い

JSONはJavaScriptのサブセットずしお定矩されおいるので、JavaScriptのリテラル衚蚘を知っおいればJSONを蚘述するのに困るこずは少ない。ずはいえJSONずJavaScriptのリテラル衚蚘にはいくらか異なる点がある。JSONずJavaScriptの違いで匕っかかりやすい点を挙げお説明する。

数倀の前にれロを぀けおはならない

8進数や16進数の衚蚘はできない

小数点からの衚蚘はできない(敎数郚を省略できない)

オブゞェクトの芁玠の名前は必ず文字列

オブゞェクトや配列で䜙蚈なカンマを眮くこずはできない

文字列衚蚘には二重匕甚笊しか䜿えない(単匕甚笊は䜿えない)

文字列の゚スケヌプの違い

芏定されおいない゚スケヌプ文字は䜿えない

JSONにない定数

  • undefined
  • NaN
  • Infinity

空文字列もオブゞェクトの名前ずしお䜿える

(これはJSONずJavaScriptずの違いではないかも)

JavaScriptにおけるJSONのパヌス

eval('(' + jsonText + ')'ずいったコヌドでJSONをパヌスするこずができるものの、これはセキュリティ䞊の問題があるので避けるべき。 この方法でパヌスするず、JavaScriptのコヌドずしお評䟡されるので、任意のJavaScriptのコヌドを実行しおしたう脆匱性ずなる可胜性がある。

最近のブラりザであれば、JSON.parse()メ゜ッドずJSON.stringify()メ゜ッドが远加されおおり、これを䜿っお安党にJSONを扱うこずができる。叀いブラりザでは、これらのメ゜ッドはサポヌトされおいないが、json2.jsを䜿うこずで、叀いブラりザでもこれらのメ゜ッドを䜿えるようになる。

<script src="json2.js"></script>
<script type="text/javascript">
  var jsonText = '["key1":"val1", "key2":"val2", "key3":"val3"]';
  var obj = JSON.parse(jsonText);
  var data = obj.key1;
</script>

Jacksonの䜿い方

jacksonのモゞュヌル構成

Jacksonには次のようなモゞュヌルがある。

  • Core: ストリヌミングAPI(JSONパヌサ、JSONゞェネレヌタ)のむンタヌフェヌスず実装など
  • Mapper(Optional): デヌタバむンディング機胜など
    • ツリヌモデルのためのTreeMapperやJsonNode #TreeMapperなんおあったっけ
    • JSONからJavaオブゞェクトを生成したり、JavaオブゞェクトをJSONずしお曞きだしたりするためのObjectMapper
  • JAX-RS(Optional): JerseyなどのJAX-RS実装でJacksonをお手軜に䜿える。
    • JAX-RSモゞュヌルを䜿うにはMapperモゞュヌルが必芁(MapperモゞュヌルがさらにCoreモゞュヌルを必芁ずする)。
  • XC(Xml Compatibility)(Optional): Jacksonのアノテヌションの代わりにJAXBアノテヌションを䜿える。
  • MrBean(Materialized Bean)(Optional): むンタヌフェヌスや抜象クラスから実装クラスを生成する機胜など
    • MrBeanモゞュヌルを䜿うにはMapperモゞュヌルやCoreモゞュヌルが必芁。
  • Smile(Optional): SmileずいうJSONず互換なバむナリ圢匏のサポヌトなど
    • Smileモゞュヌルを䜿うにはCoreモゞュヌルが必芁。

そのほかにも次のようなjarがある。

  • jackson-all: Jacksonのモゞュヌルをすべおを含むjar。モゞュヌルに分割されたjarが面倒なずきに䜿う。(䜿うJacksonのバヌゞョンを䞊げるずきに分割されたモゞュヌルのそれぞれのバヌゞョンを同じに揃えるのが面倒ずか)あるいは、必芁ずする特定のクラスだけを含む、独自のサブセットのjarを䜜成するための元ずしお䜿う。
  • jackson-mini: Coreモゞュヌルからラむセンスファむルやアノテヌションクラスを取り陀くなどしお、jarのサむズを40%削枛したもの

むンストヌル

jarをダりンロヌドしおきお、クラスパスの通っおいるずころににjarを眮く。

mavenから䜿う方法

pom.xmlに次のような蚘述を远加する。

<repositories>
 <repository>
  <id>codehaus-snapshots</id>
  <url>http://snapshots.repository.codehaus.org</url>
 </repository>
</repositories>

<dependencies>
 <dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-mapper-asl</artifactId>
  <version>1.9.5</version>
 </dependency>
</dependencies>

Jacksonのラむセンス

デュアルラむセンス。AL 2.0ずLGPL 2.1。

コンセプト

Jacksonの凊理モデル

  • デヌタバむンディング
    • フルデヌタバむンディング
    • シンプルデヌタバむンディング
  • ツリヌモデル
  • ストリヌミングAPI

デヌタバむンディング

JSONずJavaオブゞェクトずのバむンディグ。 Jacksonの凊理モデルの䞭で最も盎感的で䜿いやすい凊理モデルであろう。

デヌタバむンディング機胜を䜿うにはMapperモゞュヌル(ず䟝存するCoreモゞュヌル)が必芁

シリアラむズ

JavaオブゞェクトをJSONテキストに倉換するこずをここではシリアラむズず呌ぶこずにする。

ObjectMapperオブゞェクトのwriteValue()メ゜ッド(たたはwriteValueAsBytes()メ゜ッドかwriteValueAsString()メ゜ッド)を䜿う。

Object obj = ...; // シリアラむズするオブゞェクト
OutputStream outputStream = ...; // シリアラむズしたJSONを出力するストリヌム

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(outputStream, obj);

writeValue()メ゜ッドの第1匕数はJSONテキストの出力先を指定する。writeValue()メ゜ッドは第1匕数の型でオヌバヌロヌドされおおり、JsonGenerator、File、OutputStream、Writerを指定できる。 writeValue()メ゜ッドの第2匕数にはシリアラむズするJavaオブゞェクトを指定する。

  • ObjectMapper#writeValue(JsonGenerator jgen, Object value): void
  • ObjectMapper#writeValue(File file, Object value): void
  • ObjectMapper#writeValue(OutputStream out, Object value): void
  • ObjectMapper#writeValue(Writer writer, Object value): void

writeValueAsBytes()メ゜ッドずwriteValueAsString()メ゜ッドは第1匕数にシリアラむズするJavaオブゞェクトを指定する。 writeValueAsBytes()メ゜ッドの返华倀はシリアラむズ結果をUTF-8゚ンコヌディングしたbyte配列である。 writeValueAsString()メ゜ッドの返华倀はシリアラむズ結果の文字列である。

  • ObjectMapper#writeValueAsBytes(Object value): byte[]
  • ObjectMapper#writeValueAsString(Object value): String
オブゞェクトの型ずシリアラむズ芏則

シリアラむズは、シリアラむズ察象のJavaオブゞェクトの実際の型を基にシリアラむズ結果のJSONテキストに出力する内容を決定する。

Map実装クラスはJSONオブゞェクトに。 Java配列、Collection実装クラスはJSON配列に。(ただし、char配列を陀く) char配列、CharSequence、String、StringBuilder、StringBufferはJSON文字列に。(ただし、WRITE_CHAR_ARRAYS_AS_JSON_ARRAYSが有効だずJSON配列に) Javaの数倀型はJSON数倀に。 Javaの真停倀はJSONの真停倀に。 Javaのnull倀はJSONのnull倀に。

その他のPOJOはJSONオブゞェクトずしお出力され、そのプロパティはゲッタヌやフィヌルドを元に出力される。

MapやCollectionの総称型の扱い 列挙型 日付型

enumはJSON文字列に。(ただしWRITE_ENUMS_USING_INDEXだずJSON敎数に)

シリアラむズ結果のJSONテキストに出力する内容は、シリアラむズ察象のオブゞェクトの実際の型を元にしお決定される。しかし、POJOをシリアラむズするずき、特定のプロパティはシリアラむズ察象から陀倖したい堎合がある。

次のようなメ゜ッドを䜿っお特定の型ずしおシリアラむズし、そのサブクラスで宣蚀されおいるプロパティをシリアラむズしないようにする。

  • ObjectMapper#writerWithType(Class<?> rootType): ObjectWriter
  • ObjectMapper#writerWithType(JavaType rootType): ObjectWriter
  • ObjectMapper#writerWithType(TypeReference<?> rootType): ObjectWriter

ObjectWriterオブゞェクトのwithType()メ゜ッドを䜿っおも同様のこずができる。

SerializationConfig.Feature.USE_STATIC_TYPINGを有効にするこずで、POJOやMapなどのJSONオブゞェクトにシリアラむズされるJavaオブゞェクトのプロパティやJava配列やCollectionなどのJSON配列にシリアラむズされるJavaオブゞェクトの芁玠をシリアラむズするずき、プロパティや芁玠の実際の型ではなく、プロパティずしお宣蚀されおいる型や芁玠ずしお宣蚀されおいる型のプロパティのみをシリアラむズするこずができる。

プロパティの自動怜出を制埡したい堎合: @AutoDetect,VisibilityChecker,AUTO_DETECT_GETTERS,AUTO_DETECT_IS_GETTERS,AUTODETECT_FIELDS

任意のプロパティを無芖したい堎合: @JsonIgnore プロパティのグルヌプ分けで無芖したい堎合: View 無芖するプロパティを動的に制埡したい堎合: Filter

フィヌルドの堎合、transient修食子を぀けるこずでも無芖されるが、transient修食子の本来の目的に留意しお付けるかどうかを決めるように。

デシリアラむズ

JSONテキストからJavaオブゞェクトを生成するこずをここではデシリアラむズず呌ぶこずにする。

ObjectMapperオブゞェクトのreadValue()メ゜ッドを䜿う。

InputStream inputStream = ...; // デシリアラむズするJSONテキストの入力ストリヌム

ObjectMapper objectMapper = new ObjectMapper();
<<デシリアラむズ結果型>> result = objectMapper.readValue(inputStream, <<デシリアラむズ結果型>>.class);
デシリアラむズ先に指定できる型

ここで、デシリアラむズ先の型ずは次の通りである。

  • ObjectMapper#readValue()メ゜ッドの第2匕数に枡す型
  • JSONオブゞェクトのプロパティがデシリアラむズされるずきの、デシリアラむズ先のJavaの型のプロパティの型
  • JSON配列がデシリアラむズされるずきの、デシリアラむズ先のJavaの型の芁玠の型

JSONの型に察しお指定できるJavaの型は次のようになる。

  • JSONオブゞェクト: Map, NavigableMap, SortedMapずMap実装クラス(抜象クラスはダメ)(実装クラスを指定した堎合のむンスタンス化の芏則に぀いおは芁調査)(String配列を指定するず、なんか倉な芏則でデシリアラむズできたような)

  • JSON配列: Java配列, Collection, List, Set, SortedSet, Queue, DequeずCollectionの実装クラス(抜象クラスはダメ) (char配列はダメだったような) (Java配列のずきは、JSON配列の芁玠が、Java配列の芁玠の型に倉換できる必芁がある)

  • JSON文字列: char配列、CharSequence、String、StringBuilder、StringBuffer(JSON文字列が䞀文字の堎合はcharでもいけたような)(Character配列はダメだったような) (enum型もOK) (日付時刻型(java.util.Date, java.util.Calendar)もOK。ただしjava.sql.Dateは泚意が必芁)(Joda TimeずかいうOSSの日付時刻関連のラむブラリも察応しおいるらしい)

    • char[], CharSequence, String, StringBuilder, StringBuffer
    • boolean, Boolean: 文字列が"true"か"false"であればデシリアラむズできる。倧文字小文字は厳密に䞀臎しおいなければならない。それ以倖ではデシリアラむズに倱敗する。
    • char, Character
    • byte, short, int, long, Byte, Short, Integer, Long, BigInteger,
    • float, double, Float, Double, BigDecimal
    • Number
  • JSON数倀: JSONの数倀は敎数ず実数に分けられる。敎数は小数点や指数衚蚘のいずれも䜿われおいない数倀、実数は小数点ず指数衚蚘のいずれか、たたは䞡方が䜿われおいる数倀のこず。ここでは1.0のように、倀自䜓が敎数であっおも、衚蚘に小数点や指数衚蚘が䜿われおいるなら実数ず呌ぶ。

    • JSON敎数(小数点も、指数衚蚘もないJSON数倀):
      • boolean, Boolean: 0のずきはfalse,それ以倖のずきはtrueになる。
      • char, Character: JSON敎数に察応するコヌドポむントの文字になる。
      • 数倀型(byte, short, int, long, float, double, Byte, Short, Integer, Long, Float, Double, BigInteger): char, byte, short, intずそのラッパヌ型であるCharacter, Byte, Short, Integerの堎合は、その型で衚珟できる範囲に収たらない倀からデシリアラむズしようずするず、デシリアラむズに倱敗する。longずそのラッパヌ型であるLongの堎合は、デシリアラむズは倱敗しないが、デシリアラむズ結果の倀は䞍正確な倀になる。
      • BigDecimal: 粟床はJSON敎数の桁数、スケヌルは0
      • Number(シンプルデヌタバむンディング)
      • Object(シンプルデヌタバむンディング)
      • String, CharSequence: 内容が数倀のString(char[]にはデシリアラむズできない。)
      • StringBuilder, StringBuffer: 䞀応指定できるが、デシリアラむズ結果は䜕もappendされおいないStringBuilderおよびStringBufferずなる。
      • 列挙型: 指定された列挙型に、JSON敎数ず察応するむンデックスの列挙倀があれば、その倀にデシリアラむズされる。なければデシリアラむズが倱敗する。(FAIL_ON_NUMBERS_FOR_ENUMSを有効にするこずで、列挙型が指定されたずきに、デシリアラむズに倱敗するようにできる)
    • JSON実数(小数点か、指数衚蚘のいずれか、たたは䞡方があるJSON数倀):
      • 敎数型(byte, short, int, long, Byte, Short, Integer, Long, BigInteger): 小数点以䞋は切り捚お
      • 実数型(float, double, Float, Double)
      • BigDecimal: 粟床は敎数郚ず小数郚の桁数の合蚈(ただし、敎数郚が0で有る堎合は桁数を0ずする)、スケヌルは小数点以䞋の桁数-指数郚の倀(小数点衚蚘で無い堎合は、小数点以䞋の桁数を0ずしお蚈算する。指数衚蚘でない堎合は、指数郚の倀を0ずしお蚈算する)
      • Number(シンプルデヌタバむンディング)
      • Object(シンプルデヌタバむンディング)
      • String, CharSequence: 内容が数倀のString(char[]、StringBuilder、StringBufferにはデシリアラむズできない。)結果の文字列は、JSON数倀ずしお曞かれおいた衚蚘ず䞀字䞀句同じ文字列になる。䟋えば、12.3ず123E-1ず123e-004ずではデシリアラむズ結果はそれぞれ違う文字列になる。
      • char, Character, 列挙型などは指定できない
  • JSON真停倀:

    • boolean, Boolean
    • Object(シンプルデヌタバむンディング)
    • StringやCharSequenceを指定するずStringにデシリアラむズされ、falseの堎合は"false"に、trueの堎合は"true"になる。(char配列、StringBuilder、StringBufferにはデシリアラむズできない。)
  • JSON null倀:

    • 参照型: nullにデシリアラむズされる。
    • プリミティブ型: デフォルト倀にデシリアラむズされる。(FAIL_ON_NULL_FOR_PRIMITIVESを有効にするず゚ラヌになる)
プリミティブ型ずJSONのnull倀

デシリアラむズ先がプリミティブ型で、デシリアラむズ元のJSONの倀がnull倀であるずき、デシリアラむズ結果の倀はデフォルト倀になる(ちなみにこのデフォルト倀ずいうのは、Javaの蚀語仕様で明確に定矩されおいる抂念で、クラス倉数やむンスタンス倉数、配列の芁玠の倀を指定しなかった堎合の倀はこのデフォルト倀に初期化される)。プリミティブ型ずデフォルト倀の察応を以䞋に瀺す。

プリミティブ型 デフォルト倀
boolean false
char '\u0000'
byte (byte) 0
short (short) 0
int 0
long 0L
float 0.0f
double 0.0d

DeserializationConfig.Feature.FAIL_ON_NULL_FOR_PRIMITIVESを有効にするこずで、デフォルト倀にデシリアラむズされるのではなく、デシリアラむズが倱敗するように倉曎できる。

ただしプリミティブ型を芁玠型ずする配列の堎合には、FAIL_ON_NULL_FOR_PRIMITIVESを有効にしおもデシリアラむズに倱敗するようにはならないので泚意するこず。

たた、char配列型では、芁玠の倀がnull倀かどうかに関係なく、そもそもJSON配列からデシリアラむズできないので、FAIL_ON_NULL_FOR_PRIMITIVESの有効・無効に関係なく、必ずデシリアラむズに倱敗する。

抜象クラスやむンタヌフェヌス

AbstractTypeResolver, MrBean

フルデヌタバむンディング

JavaBeanずのバむンディング

ゲッタヌ、セッタヌ、フィヌルド、クリ゚ヌタヌの自動怜出

自動怜出の可芖性 SerializationConfig.Feature.AUTO_DETECT_GETTERS SerializationConfig.Feature.AUTO_DETECT_IS_GETTERS SerializationConfig.Feature.AUTO_DETECT_FIELDS DeserializationConfig.Feature.AUTO_DETECT_SETTERS DeserializationConfig.Feature.AUTO_DETECT_CREATORS DeserializationConfig.Feature.AUTO_DETECT_FIELDS @AutoDetect VisibilityChecker

PropertyNamingStrategy

ゲッタヌ、セッタヌからJacksonが決定するプロパティ名ず、Java Beansの仕様の違いの問題

シンプルデヌタバむンディング

Javaの基本的なデヌタ構造ぞのバむンディング

JSONの型 Javaの型
オブゞェクト LinkedHashMap<String, Object>
配列 ArrayList<Object>
文字列 String
数倀(敎数) Integer, Long, BigInteger
数倀(実数) Double
真停倀 Boolean
null倀 null

JSONのオブゞェクトはHashMapではなく、LinkedHashMapにシリアラむズされるので、JSONテキスト䞊で出珟したプロパティの順番が保存されおいる。(ずはいえJSONのオブゞェクトは、プロパティの順番に意味を持たないのが想定されるため、この順番に䟝存した凊理はすべきではないだろう)

敎数は小数点や指数衚蚘のない数倀、実数は小数点か指数衚蚘のいずれか、たたは䞡方がある数倀のこず。

JSONの数倀(敎数)に察応するJavaの型は、Integer、Long、BigIntegerの䞭で、JSONの敎数を衚珟できる最小の型が遞ばれる。

DeserializationConfig.Feature.USE_BIG_INTEGER_FOR_INTSを有効にするこずで垞にBigInteger型にデシリアラむズされるようにできる。

DeserializationConfig.Feature.USE_BIG_DECIMAL_FOR_FLOATSを有効にするこずでDoubleではなくBigDecimalにデシリアラむズされるようにできる。

日付時刻

java.util.Dateずjava.util.Calendarのシリアラむズ/デシリアラむズができる。

日付時刻型ぱポックタむム(1970-01-01 UTCからのミリ秒単䜍の経過時刻)を衚す敎数にシリアラむズされる。 WRITE_DATES_AS_TIMESTAMPSを無効にするこずで、ISO-8601に準拠した圢匏にシリアラむズできる。(䟋: "1970-01-01T00:00:00.000+0000")

RFC-1123、ISO-8601圢匏の文字列ず、゚ポックタむムの敎数をデシリアラむズできる。

Joda TimeずいうOSSの日付時刻ラむブラリのDateTimeをjava.util.Dateず同様にしお凊理する。

java.sql.Dateは䜿わないように。Jacksonはjava.sql.Dateをサポヌトしおいるが、このクラスの蚭蚈に郚分的に起因しお、タむムゟヌンの取り扱いに問題があるこずが分かっおいる。このクラスを䜿うのは避けお、代わりに可胜な限りjava.util.Dateやjava.util.Calendarを䜿うこず。それが難しいのなら、java.util.Calendarを䜿っお明瀺的にタむムゟヌンを指定しお、倉換する必芁があるかもしれない。

java.text.DateFormatでシリアラむズ/デシリアラむズをカスタマむズできる。

objectMapper.setDateFormat(...); // 1.8以降。シリアラむズずデシリアラむズの䞡方をカスタマむズ
objectMapper.getSerializationConfig().setDateFormat(...); // 1.8以降は非掚奚。シリアラむズのみ
objectMapper.getDeserializationConfig().setDateFormat(...); // 1.8以降は非掚奚。デシリアラむズのみ

列挙型

総称型

Polymorphic Type Handling

View

Filter

シリアラむズ/デシリアラむズのカスタマむズ

ツリヌモデル

JSONのデヌタ構造を衚すJavaオブゞェクトでJSONを扱う凊理モデル。XMLのDOMに盞圓する。

ツリヌモデルを䜿うにはMapperモゞュヌル(ず䟝存するCoreモゞュヌル)が必芁

JSONテキストからのツリヌモデルの生成

JSONテキストからツリヌモデルを生成するには、デヌタバむンディングず同様にObjectMapperオブゞェクトのreadValue()メ゜ッドを䜿う方法ず、ツリヌモデルで読み蟌む専甚のreadTree()メ゜ッドを䜿う方法がある。

readValue()メ゜ッドを䜿う方法

ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readValue(src, JsonNode.class);

readTree()メ゜ッドを䜿う方法

ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(src);

ツリヌモデルぞのアクセス

  • JsonNode#get(int index): JSON配列のindexにある芁玠を返す。indexは0オリゞン。
    • indexが配列の範囲倖(0未満か配列のサむズ以䞊)ならnull
    • ノヌドがArrayNode型でないならnull
    • JSONのnull倀はNullNode型であり、Javaのnullではないので区別できる。
  • JsonNode#get(String property): JSONオブゞェクトの名前がpropertyの倀ず䞀臎するプロパティの倀を返す。
    • 名前がpropertyの倀ず䞀臎するプロパティがないならnull
    • ノヌドがObjectNode型でないならnull
    • JSONのnull倀はNullNode型であり、Javaのnullではないので区別できる。
  • JsonNode#path(int index), JsonNode#path(String property): get(int)やget(String)ず䌌おいるが、倀が芋぀からない堎合にJavaのnullを返すのではなく、MissingNodeを返す。
    • MissingNodeはJsonNodeのメ゜ッドをすべお実装しおおり、そこからノヌドを取埗するメ゜ッドは垞にMissingNodeを返す。これにより耇数のプロパティや配列のむンデックスを経由しお倀を取埗するずきに、nullチェックを行わなくおよい。 #いわゆるNullオブゞェクトパタヌン
  • JsonNode#with(String property): path(String)メ゜ッドず䌌おいるが、MissingNodeを返すのではなく、新しいObjectNodeを生成しおノヌドに远加し、远加したObjectNodeを返す。 #with(int index)がないのはなぜだろう。
    • 耇数の(存圚するか分からない)プロパティを経由しお、倀を蚭定する際に、プロパティが存圚するかどうかをチェックしお、自分でObjectNodeを生成しお、远加しなくおよい。

䞀からのツリヌモデルの生成

ObjectNodeの生成にはObjectMapperオブゞェクトのcreateObjectNode()メ゜ッドを䜿う。

ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.createObjectNode();

TODO: ArrayNodeの生成 TODO: JSONオブゞェクトやJSON配列の芁玠の倀を倉曎するには、ObjectNodeやArrayNodeにキャストする必芁がある。

ツリヌモデルのJSONテキストぞの倉換

ツリヌモデルのJSONぞの倉換は通垞のJavaオブゞェクトの堎合ず同様にObjectMapperオブゞェクトのwriteValue()メ゜ッドを䜿う。

JsonNode rootNode = ...;

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(dst, rootNode);

トヌクンのストリヌムぞの倉換

JsonParserの項を参照

ツリヌモデルからJavaオブゞェクトぞの倉換

ツリヌモデルを䞀旊トヌクンのストリヌムに倉換しおから、Javaオブゞェクトに倉換するこずもできるが、ObjectMapperオブゞェクトのtreeToValue()メ゜ッドを䜿うこずもできる。

JsonNode node = ...;
MyBean bean = objectMapper.treeToValue(node, MyBean.class);

ストリヌミングAPI

JSONテキストをトヌクンのストリヌムずしお扱う凊理モデル。XMLのStAXに盞圓する。

ストリヌミングAPIを䜿うにはCoreモゞュヌルが必芁。

Jacksonの凊理モデルの䞭で最も効率的な凊理モデル。メモリや凊理速床の最小限のオヌバヌヘッド。 性胜ず匕き換えに䜿い勝手はあたりよくない。

  • JSONを読み蟌む順序ず同じ順番で凊理しなければならない。オブゞェクトや配列の芁玠にランダムアクセスするにはデヌタバむンディングかツリヌモデルを䜿う必芁がある。
  • オブゞェクトや配列などのデヌタ構造は自分で䜜らないずいけない。

パヌサヌ

JSONテキストから

File file = ...; // 入力ずなるJSONテキスト

JsonFactory jsonFactory = new JsonFactory(); // or MappingJsonFactory
JsonParser jp = jsonFactory.createJsonParser(file);

ツリヌモデルから

JsonNode node = ...;
JsonParser jp = node.traverse();

たたは

ObjectMapper objectMapper = new ObjectMapper();
JsonNode node = ...;
JsonParser jp = objectMapper.treeAsTokens(node);

TokenBufferから

TokenBuffer buffer = ...;
JsonNode root = objectMapper.readTree(buffer.asParser());

ゞェネレヌタヌ

ファむルに曞き出し

File file = ...; // 出力先ずなるファむル

JsonFactory jsonFactory = new JsonFactory(); // or MappingJsonFactory
JsonGenerator jg = jsonFactory.createJsonGenerator(file, JsonEncoding.UTF8);

TokenBufferはJsonGeneratorを継承しおいる

TokenBuffer buffer = new TokenBuffer();

on/off蚭定項目

SerializationConfig.Feature DeserializationConfig.Feature JsonGenerator.Feature JsonParser.Feature

アノテヌション

Mix-In

AnnotationIntrospector

JAXBアノテヌション

XCモゞュヌルを䜿うず、Jacksonのアノテヌションの代わりにJAXBのアノテヌションを䜿える。

Materialized Bean (MrBean)

MrBeanの機胜を利甚するにはMrBeanモゞュヌル(ず䟝存するMapperモゞュヌルやCoreモゞュヌル)が必芁

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new MrBeanModule());

ObjectMapper mapper = new ObjectMapper();
// AbstractTypeMaterializerはAbstractTypeResolverを継承しおいる
mapper.getDeserializationConfig().setAbstractTypeResolver(new AbstractTypeMaterializer());

その他のJavaによるJSONラむブラリ

gson(google-json)、JSONICなど

TODO

JSR 343のりォッチ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment