如何获得Spring 4.1使用的Jackson ObjectMapper?

Ada*_*ass 43 java spring json spring-mvc jackson

Spring 4.1实例化了一个Jackson ObjectMapper实例.我有理由希望@Autowire将该实例放入我的一个控制器中:控制器使用Jackson对其自己进行一些小的JSON解析,但ObjectMapper它使用的应该是Spring本身正在使用的同一个实例.我该如何完成呢?

请注意,我不是问如何自定义ObjectMapperSpring正在使用的配置; 我对默认值感到满意.我只想捕获Spring使用的实例,以便我可以在我自己的代码中重用现有实例.

Tun*_*uno 38

如果您在类路径中使用Spring Boot with Jackson并在REST控制器中使用JSON解析的默认实现,那么这应该可行:

@Autowired
private ObjectMapper jacksonObjectMapper;
Run Code Online (Sandbox Code Playgroud)

  • 不行.使用Spring引导1.4.0.M2测试,它使用spring 4.3.0.RC1并抛出NoSuchBeanDefinitionException (16认同)
  • 第一:在组件中自动装配时与 spring boot 1.5.3 一起使用。第二:警告:这是我迄今为止最危险的想法之一。由于它的单例性质,使用 Spring Objectmapper 作为 @Autowired bean 时可能会遇到非常难看的问题,例如,您的控制器中的任何对象都不再序列化,因为您在任何类中使用自动装配映射器。所以请:只在您确定只需要映射器的 ootb 功能时才使用它。对于每个其他用例,扩展它并创建您自己的自定义映射器 (6认同)
  • @afaulconbridge我多次遇到的一个常见问题是错误地导入org.codehaus.jackson.map.ObjectMapper而不是com.fasterxml.jackson.databind.ObjectMapper,这是Spring Boot实际创建bean的包。改变这一点,自动装配曾经对我有用。 (2认同)

Eme*_*gia 13

如果你看一下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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您正在使用Spring Boot,那么本手册中有一专门用于处理ObjectMapper如果您创建默认值Jackson2ObjectMapperBuilder @Bean,您应该能够ObjectMapper在控制器中自动装配相同的实例.

  • 是的,我遇到过这条路径,但它涉及重新创建 Spring 创建的默认 Jackson 设置。我不想这样做。 (2认同)
  • 为什么见鬼的春天使用不同的 OM 实例。这太令人困惑了。Spring Boot 文档说 spring.jackson.serialization.indent_output=true 只是您需要美化 Web 响应的唯一内容。但它实际上只是改变了 bean,对转换的消息没有影响。 (2认同)

net*_*key 13

正如其他人所说,你不能@Autowired直接进入你的控制器.

@Emerson Farrugia建议使用创建新实例

Jackson2ObjectMapperBuilder.json().build()
Run Code Online (Sandbox Code Playgroud)

也没有为我工作,因为获得的实例不遵循spring.jackson.*配置属性,我需要它.


我找到的解决方案是从Spring获取MappingJackson2HttpMessageConverter可注入的ObjectMapper .

所以我自动装配了它:

@Autowired
private MappingJackson2HttpMessageConverter springMvcJacksonConverter;
Run Code Online (Sandbox Code Playgroud)

然后像这样从它获取ObjectMapper:

ObjectMapper objectMapper = springMvcJacksonConverter.getObjectMapper();
Run Code Online (Sandbox Code Playgroud)

这个实例的行为与Spring MVC自己的消息转换完全一样 - 无论如何它可能相同的实例.

  • MappingJackson2HttpMessageConverter不可注射:( (3认同)
  • 可注入但objectmapper为null,因此为NPE。 (2认同)

Lym*_*Zoy 12

ObjectMapper创建Jackson2ObjectMapperBuilder,您可以使用以下方法注入构建器:

@Autowired
private Jackson2ObjectMapperBuilder mapperBuilder;
Run Code Online (Sandbox Code Playgroud)

然后使用mapperBuilder.build()构建一个ObjectMapper实例,这个实例可以使用application.properties. 官方文档在这里。


Wes*_*Gun 10

我调试了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();


    }
Run Code Online (Sandbox Code Playgroud)

我们不能只@SpringBootTest(classes = Jackson2ObjectMapperBuilder.class)生成这个构建器。

当我们bootRun没有这个问题的时候。

配置在Jackson2ObjectMapperBuilderCustomizerConfiguration#customize(Jackson2ObjectMapperBuilder builder)方法中设置。

在此输入图像描述

  • 您可以使用“@JsonTest”测试片来获取配置的映射器,而无需像“@SpringBootTest”那样启动整个应用程序。快多了。请参阅https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-test-auto-configuration.html (2认同)