[java][bson]POJOをBSON形式でシリアライズする

JavaのオブジェクトをBSON形式でファイルに保存する為、いくつかの実装を試してみました。

BSONのバイナリに変換できるライブラリ

BSONのページのImplementationJava実装が列挙されている為、今回はこれらを試してみました。

  1. mongo-java-driver
  2. bson4jasckson
  3. ebson

mongo-java-driver

名前にあるとおりMongoDBのドライバですが、BasicBSONEncoderを使って、Javaのオブジェクト(BSONObjct)を直接BSONのバイナリに変換することもできます。バイナリからBSONObjctに戻すには、BasicBSONDecoderを使います。

bson4jasckson

JSONを扱うJacksonのFactoryを拡張してBSONを扱えるようにしたのがbson4jascksonです。Jacksonと同様、ObjectMapperを使うとPOJOを直接BSONのバイナリに変換することができます。

    @Test
    public void testSerialize() throws JsonGenerationException, JsonMappingException, IOException{
        Employee emp = new Employee();
        emp.setA(76);
        emp.setName("babb");
        emp.setSal(Integer.MAX_VALUE-2);

        //serialize
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectMapper mapper = new ObjectMapper(new BsonFactory());
        mapper.writeValue(baos, emp);
        byte[] buffer = baos.toByteArray();

        // deserialize
        ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
        Employee dst = mapper.readValue(bais, Employee.class);
        assertThat(dst.getA(), is(76));
        assertThat(dst.getName(), is("babb"));
        assertThat(dst.getSal(), is(Integer.MAX_VALUE-2));
    }

また、Jacksonは複数のシリアライズ方法を提供しており、ObjectMapperに任せると都合が悪い場合はmongo-java-driverのBSONObjectのような汎用型を扱うTreeModel、さらに細かく調整する場合にはStreamingAPIを使うこともできます。詳細は以下のURLに記載されています。
http://wiki.fasterxml.com/JacksonFAQ#Processing_Models

ebson

これはスクラッチで作成されたBSON実装です。サマリには「Extensible BSON encoder/decoder library written in Java with pluggable Java-to-BSON type mappings.」とあり、独自のマッピングを記述しやすいのが特徴です。
残念なのは、APIのインターフェースにByteBufferが使用されていること。ByteBufferは途中でcapacityを変更できない為、ちょっと使いづらかったというのが正直な感想です。
代わりにコードはかなり整理されており、参考になる点が多数ありました。

まとめ

POJOを直接BSONバイナリに変更したい場合はbson4jascksonのObjectMapperが便利ですが、特殊なマッピングを行うのであればebsonも面白いと思います。MongoDB絡みで連携可能な既存資産があれば、mongo-java-driverかな。