カスタマイズしたJackson2ObjectMapperBuilderを介して、ObjectMapperを独自の設定にすることができた
これでどこで使っても同じ設定になるわけだが、悲しいことにある外部APIのレスポンスだけ期待とは違うことに気づいた
具体的にはプロパティ名がLOWER_CAMEL_CASE
であることを期待していたが、そのAPIだけUPPER_CAMEL_CASE
になっている
先のカスタマイズしたJackson2ObjectMapperBuilderでは、LOWER_CAMEL_CASE
になるような設定をしているためうまくマッピングされなかった
当然ながらDIしたObjectMapperに対してUPPER_CAMEL_CASE
になるようにオーバーライドしてしまうと、他のAPIでこんどはアンマッチになってしまうので、
このAPIのレスポンスだけに対して行いたい
最速の解決策
UPPER_CAMEL_CASE
用のbuilderを作ることも考えたが、もっとも簡単な解決方法は、そのDTOに@JsonNaming
アノテーションをつけてしまうことだった
@JsonIgnoreProperties(ignoreUnknown = true) @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) @Data public class FooApiResponse { private List<Foo> data; @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) @Data public static final class Foo { private Integer id; private String firstName; private String url; }
これで、このレスポンスだけUPPER_CAMEL_CASE
としてマッピングしてくれる
一点、内部クラスにもアノテーションをつけなければならないことに注意が必要だった
ObjectMapperBuilderをつくる
他の策としてUPPER_CAMEL_CASE
用のbuilderをつくることを考えた
Jackson2ObjectMapperBuilderCustomizer
にPropertyNamingStrategiesの設定をしているので、Customizerを呼び出して設定を上書きするようなことをしなくてはならない
たぶんこのような感じ
@Bean @Primary public ObjectMapper mapper(List<Jackson2ObjectMapperBuilderCustomizer> customizerList, ApplicationContext context) { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.applicationContext(context); for (Jackson2ObjectMapperBuilderCustomizer customizer: customizerList) { customizer.customize(builder); } return builder.build(); } @Bean @Qualifier("upper") public ObjectMapper upperCaseMapper(List<Jackson2ObjectMapperBuilderCustomizer> customizerList, ApplicationContext context) { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.applicationContext(context); for (Jackson2ObjectMapperBuilderCustomizer customizer: customizerList) { customizer.customize(builder); } builder.propertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE); return builder.build(); }