Spring 4.1はJackson ObjectMapper
インスタンスをインスタンス化します。 @Autowire
そのコントローラーの1つへのそのインスタンス:コントローラーは、ジャクソンを使用して独自のマイナーJSON構文解析を行いますが、使用するObjectMapper
は、Spring自体が使用しているものと同じインスタンスでなければなりません。それを達成するにはどうすればよいですか?
Springで使用中のObjectMapper
をカスタム構成する方法を尋ねているのではないことに注意してください。デフォルトに満足しています。私は自分のコードで既存のインスタンスを再利用できるように、Spring outで使用されるインスタンスを釣りたいだけです。
RESTコントローラーでJSON解析のクラスパスとデフォルトの実装でジャクソンと共にSpring Bootを使用している場合、これは機能するはずです:
@Autowired
private ObjectMapper jacksonObjectMapper;
MappingJackson2HttpMessageConverter
、新しいObjectMapper
を作成しますが、Beanとして公開しません。ゲッターはありますが、過去に釣り上げた唯一の方法は、MappingJackson2HttpMessageConverter
自分、例えば.
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter jacksonMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = jacksonMessageConverter.getObjectMapper();
objectMapper.registerModule(new JodaModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
converters.add(jacksonMessageConverter);
}
}
Spring Bootを使用している場合は、マニュアルにObjectMapper
を使用する専用の セクション があります。デフォルトのJackson2ObjectMapperBuilder
@Bean
、コントローラの同じObjectMapper
インスタンスを自動配線できるはずです。
他の人から言われたように、@Autowired
を直接コントローラーに入れることはできません。
@Emerson Farrugiaの提案を使用して新しいインスタンスを作成する
Jackson2ObjectMapperBuilder.json().build()
また、取得したインスタンスが必要なspring.jackson.*
構成プロパティに従っていないため、私にとってはうまくいきませんでした。
私が見つけた解決策は、注射可能なMappingJackson2HttpMessageConverter
からObjectMapperを取得することでした。
だから私はそれを自動配線しました:
@Autowired
private MappingJackson2HttpMessageConverter springMvcJacksonConverter;
次に、次のようにObjectMapperを取得します。
ObjectMapper objectMapper = springMvcJacksonConverter.getObjectMapper();
このインスタンスは、Spring MVC自身のメッセージ変換とまったく同じように動作します。おそらくisとにかく同じインスタンスです。
ObjectMapper
は_Jackson2ObjectMapperBuilder
_によって作成され、次を使用してビルダーを挿入できます。
_@Autowired
private Jackson2ObjectMapperBuilder mapperBuilder;
_
次にmapperBuilder.build()
を使用してObjectMapper
インスタンスを構築します。このインスタンスは_application.properties
_の構成を使用できます。 公式ドキュメントはこちら
あなたの@SpringBootApplication
クラス、追加:
@Bean
public ObjectMapper mapper() {
return new ObjectMapper();
}
ObjectMapper
を使用したい場所:
@Autowired
ObjectMapper mapper;
平和!
Spring Bootのソースコードにデバッグしましたが、コンテキスト全体を起動したときにのみ_Jackson2ObjectMapperBuilder
_が_application.yml
_に配置した設定を含むことがわかりました。
これは、JUnit 5を使用して、Spring BootテストでObjectMapperを生成する場合、次のことを行う必要があることを意味します。
_@ExtendWith(SpringExtension.class)
@SpringBootTest
class SomeTest {
@Autowired
private Jackson2ObjectMapperBuilder builder;
...
@Test
void testObjectMapper() {
ObjectMapper mapper = builder.build();
}
_
このビルダーを生成するために@SpringBootTest(classes = Jackson2ObjectMapperBuilder.class)
を作成することはできません。
bootRun
の場合、この問題はありません。
設定はJackson2ObjectMapperBuilderCustomizerConfiguration#customize(Jackson2ObjectMapperBuilder builder)
メソッドで設定されます。
MappingJackson2HttpMessageConverterを@Autowireしようとすると、次のようになります:No qualifying bean of type 'org.springframework.http.converter.json.MappingJackson2HttpMessageConverter' available: expected single matching bean but found 4: mappingJackson2HttpMessageConverter,jacksonHttpMessageConverter,halJacksonHttpMessageConverter,alpsJsonHttpMessageConverter
。
これは大きな問題ではありません。変数名を上記のいずれかに変更して、そのインスタンスを取得できます:@Autowired private MappingJackson2HttpMessageConverter halJacksonHttpMessageConverter;