Jackson:ObjectMapperのコンフィギュレーション



ObjectMapperの「適切な」コンフィギュレーション

未だに確実なところがわからないのだが、とりあえず現在のところJacksonのObjectMapperを「適切に」設定する方法をまとめてみた。「適切な」の意味は以下である。

  • オブジェクトのフィールドのみを読み書きさせる。GetterやSetterがあってもそれらは無視する。
  • デシリアライズ時にJSON中に不明なフィールド(デシリアライズ先のクラスに無いフィールド)があってもエラーにしない。単純に無視する。
  • シリアライズ時にnull値を出力しない、無駄なので。
  • 空のクラスでもOKにする。なぜかフィールドが一つも無いクラスをシリアライズしようとするとデフォルトではエラーになってしまう。
ObjectMapper mapper = new ObjectMapper()

          /* フィールドのみをシリアライズ・デシリアライズ対象とする、
           * つまり、Getter/Setterは一切無視する
           */
          .setVisibility(PropertyAccessor.ALL, Visibility.NONE)
          .setVisibility(PropertyAccessor.FIELD, Visibility.ANY)

          /* シリアライズ時にnull値を出力しない */
          .setSerializationInclusion(Include.NON_NULL)

          /* デシリアライズ時に、JSON中には存在するフィールドがJavaクラスには無い場合、
           * エラーにせず、単純に無視する
           */
          .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

          /*
           * 空のクラスでもOKにする。以下のようなもの。
           * これがないとエラーが発生してしまう。
           * class Empty {
           * }
           */
          .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
          ;

JacksonJaxbJsonProviderでの同じ設定

JAX-RSを使用する場合、例えば以下のように設定するのだが、

import javax.ws.rs.client.*;

import org.glassfish.jersey.client.*;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.*;

import com.fasterxml.jackson.databind.*;
//////
  final Client client = ClientBuilder.newClient(new ClientConfig(
      new JacksonJaxbJsonProvider()
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

JacksonJaxbJsonproviderには、setVisibility等のメソッドが無いため、先のObjectMapperと同一の設定をすることができない(もしかしたら、何らかの方法で可能なのかもしれないが、探し出せない)。

これをどう解決すべきなのか、探してみると以下の記事があった。

つまり、new JacksonJaxbJsonProvider()でJacksonJaxbJsonProviderを作成したら、setMapperでObjectMapperを設定してしまえば良いということのようだ。つまり、以下のようになるのか。

import javax.ws.rs.client.*;

import org.glassfish.jersey.client.*;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.*;

import com.fasterxml.jackson.databind.*;

/////

  JacksonJaxbJsonProvider getJacksonJaxbJsonProvider() {
    JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
    provider.setMapper(objectMapper);
    return provider;
  }

  final Client client = ClientBuilder.newClient(new ClientConfig(
      getJacksonJaxbJsonProvider()
  ));