しいしせねっと
[Java] [ABNF]

JSONを実装してみる

概要

WebのAPIでよく使われるようになったJSON、もともとJavaScriptのデータ形式だったようなものがいろいろあってRESTなどでXMLに代わるデータ形式として定着、RFC 8259などで標準化されている。

JSONにたどり着くには

JavaでJSONを扱うには、JavaのCollection系やオブジェクトと相互変換できると便利です。

JSON for Java標準的なAPIもあるようですが、GSON、Jacksonなどが有名なようです。とりあえずどちらも知らないので使わない(謎)

JSONの延長線上には

などいろいろありますが、それは略。REST方面へ続ける。

JavaでRESTを扱うのは、JAX-RSかJAX-WSか、また別のものです。

作る過程

バイト列から切り取る方法でJSONパーサを作ってしまいます。

RFCに仕様があるのでParserを作るのも簡単、いくつか作ってみたというものもあるようなので、ここでもParserを作ってみますがJSON Parserは書きません。

JSONを実装するにはABNF構文を使って解析していくことが必要なため、まず最初にABNFを作ります。

RFCで使われている記述方式で、今回これもSoftLibABNFとして実装したので[ABNF]別途解説。JSON以外のものも楽々実装できる形に仕上がってしまいました。

本来この過程は構文解析などを使ったり書いたりするようなのですが、ABNFで構文解析をするという変な方向から攻めたので手間はABNFの方に封入してしまいました。JSON自体は構文解析の手間がほとんどありません。

JSONのABNF構文をさらっと通し、JSONの要素をJavaのオブジェクトに対応させていくだけでほぼ完成です。エスケープの処理などが多少複雑になったりしますが最新のJSONはUTF-8のみなのでいろいろ楽です。

分解して生成された要素を組み立てていくだけでJSONをJavaのMapやListで構成したJavaオブジェクト化が可能です。パースエラー生成は苦手です。

JSON Pointer, JSON Patchなども実装してみたあたりで JSON for Java(JSONP)と比較してみたところ、ほぼ似たような構成なので寄せてみることに。jsonでは統合してみましたがjson2では分離してJSONPも実装しています。

Object MappingとあわせてJavaのどのあたりの要素に関連づけるかいろいろ試行錯誤しましたが、最終的に一度低いところに置くことで落ち着きました。net.siisise.json と net.siisise.json2 と2系統あるので最終的には2の方を使う予定です。2の系統ではJSONPとObject Mappingを整理し本体から分離できました。

こんな感じの仕上がりでオブジェクトマッピングも柔軟に相互変換可能かもしれない構造に仕上げます。

そこからObjectやBeanにマッピングしていくことで、JavaとJSONのオブジェクトの変換的なものが実現します。プリミティブ型、配列、class、CollectionとJSONをどのように対応づけるかは好みによるところかもしれません。

SottLibJSONのご紹介

SoftLibJSONは、基本的にはJSONのParserとオブジェクトマッピング関連の強化ライブラリです。ABNFのParserをつついていてできた副産物のようなものです。

依存ライブラリ

基本的にJava 8標準と自家製ライブラリ(SoftLib,SoftLibABNF)のみ利用しています。Apacheなどのライブラリは不要です。

最近はオブジェクトマッピング機能をつついているのでそちら方面はお得です。

現在開発中ですが、実装は2+1系統あります。違いはデータの持ち方で、中間クラスを使用した実装にしてみたものが1系、List,Map系に入れたデータをそのまま使ってしまい、表面だけJSON実装にしてみたのが2系です。2系の継続を考えているのでそっちがおすすめです。2系の拡張でJSON for Java(JSONP)にあわせてみたものもあるので+1です。