Spring 4.1 实例化一个 Jackson
ObjectMapper
实例。我有理由想要将该实例 @Autowire
放入我的一个控制器中:该控制器使用 Jackson 对自己进行一些小的 JSON 解析,但它使用的 ObjectMapper
应该是 Spring 本身正在使用的同一个实例。我该如何实现这一目标?
请注意,我不是问如何自定义配置 Spring 使用的
ObjectMapper
;我对默认值很满意。我只是想捞出 Spring 使用的实例,以便我可以在自己的代码中重新使用现有的实例。
如果您在类路径上使用 Spring Boot 和 Jackson,并在 REST 控制器中使用 JSON 解析的默认实现,那么这应该可以工作:
@Autowired
private ObjectMapper jacksonObjectMapper;
正如其他人所说,您不能
@Autowired
将其直接放入控制器中。
@Emerson Farrugia 建议使用
创建新实例Jackson2ObjectMapperBuilder.json().build()
对我来说也不起作用,因为获得的实例不遵循我需要的
spring.jackson.*
配置属性。
我找到的解决方案是从Spring的
MappingJackson2HttpMessageConverter
获取可注入的ObjectMapper。
所以我自动装配了它:
@Autowired
private MappingJackson2HttpMessageConverter springMvcJacksonConverter;
然后从中获取 ObjectMapper,如下所示:
ObjectMapper objectMapper = springMvcJacksonConverter.getObjectMapper();
这个实例的行为与 Spring MVC 自己的消息转换完全相同 - 无论如何它可能是同一个实例。
如果您查看
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
实例在你的控制器中。
ObjectMapper
由Jackson2ObjectMapperBuilder
创建,您可以使用以下方式注入构建器:
@Autowired
private Jackson2ObjectMapperBuilder mapperBuilder;
然后使用
mapperBuilder.build()
构建一个ObjectMapper
实例,该实例可以使用application.properties
中的配置。 官方文档在这里。
我调试了Spring Boot的源代码,发现只有当我们启动整个上下文时
Jackson2ObjectMapperBuilder
才会包含我们放入application.yml
中的配置。
这意味着,如果我们想在 Spring Boot 测试中使用 JUnit 5 生成 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)
方法设置。
当您尝试 @Autowire MappingJackson2HttpMessageConverter 时,它会给您:
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;
Spring 4.3 更新:
请使用com.fasterxml.jackson.databind.ObjectMapper
在您的
@SpringBootApplication
课程中,添加:
@Bean
public ObjectMapper mapper() {
return new ObjectMapper();
}
任何您想使用的地方
ObjectMapper
:
@Autowired
ObjectMapper mapper;
平安!