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

问题描述 投票:0回答:9

Spring 4.1 实例化一个 Jackson

ObjectMapper
实例。我有理由想要将该实例
@Autowire
放入我的一个控制器中:该控制器使用 Jackson 对自己进行一些小的 JSON 解析,但它使用的
ObjectMapper
应该是 Spring 本身正在使用的同一个实例。我该如何实现这一目标?

请注意,我不是问如何自定义配置 Spring 使用的

ObjectMapper
;我对默认值很满意。我只是想捞出 Spring 使用的实例,以便我可以在自己的代码中重新使用现有的实例。

java json spring spring-mvc jackson
9个回答
70
投票

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

@Autowired
private ObjectMapper jacksonObjectMapper;

32
投票

正如其他人所说,您不能

@Autowired
将其直接放入控制器中。

@Emerson Farrugia 建议使用

创建新实例
Jackson2ObjectMapperBuilder.json().build()

对我来说也不起作用,因为获得的实例不遵循我需要的

spring.jackson.*
配置属性。


我找到的解决方案是从Spring的

MappingJackson2HttpMessageConverter
获取可注入的ObjectMapper。

所以我自动装配了它:

@Autowired
private MappingJackson2HttpMessageConverter springMvcJacksonConverter;

然后从中获取 ObjectMapper,如下所示:

ObjectMapper objectMapper = springMvcJacksonConverter.getObjectMapper();

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


24
投票

如果您查看

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
实例在你的控制器中。


17
投票

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

@Autowired
private Jackson2ObjectMapperBuilder mapperBuilder;

然后使用

mapperBuilder.build()
构建一个
ObjectMapper
实例,该实例可以使用
application.properties
中的配置。 官方文档在这里。


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();


    }

我们不能只使用

@SpringBootTest(classes = Jackson2ObjectMapperBuilder.class)
来生成这个构建器。

当我们

bootRun
时,我们就没有这个问题了。

配置通过

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

enter image description here


1
投票

当您尝试 @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;


1
投票

Spring 4.3 更新:

  • 从 Spring 4.3 开始,具有单个构造函数的类可以省略 @Autowired 注解
  • 因此,如果您添加一个采用 ObjectMapper 参数的构造函数,它将自动与 Jackson ObjectMapper 实例连接,而无需使用注释 @Autowired

0
投票

请使用com.fasterxml.jackson.databind.ObjectMapper


-3
投票

如果愿意的话,可以选择两步;

  1. 在您的

    @SpringBootApplication
    课程中,添加:

    @Bean
    public ObjectMapper mapper() {
      return new ObjectMapper();
    }
    
  2. 任何您想使用的地方

    ObjectMapper

    @Autowired
    ObjectMapper mapper;
    

平安!

© www.soinside.com 2019 - 2024. All rights reserved.