カスタマイズした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();
}