Java 是否可以为Spring创建一个定制的Jackson objectMapper,而不使用XML?

Java 是否可以为Spring创建一个定制的Jackson objectMapper,而不使用XML?,java,spring,jackson,Java,Spring,Jackson,对于Spring,但配置需要XML。我正试图减少XML配置的数量,因为在不需要重新部署整个系统的情况下,这些东西实际上不会改变 因此,标题说明了一切——我可以使用注释或其他非XML方法告诉Spring,“嘿,请使用我的自定义对象映射器pls”吗 编辑: 这似乎不起作用 @Configuration @EnableWebMvc public class AppConfig { @Primary @Bean public ObjectMapper mapper(){

对于Spring,但配置需要XML。我正试图减少XML配置的数量,因为在不需要重新部署整个系统的情况下,这些东西实际上不会改变

因此,标题说明了一切——我可以使用注释或其他非XML方法告诉Spring,“嘿,请使用我的自定义对象映射器pls”吗


编辑:

这似乎不起作用

@Configuration
@EnableWebMvc
public class AppConfig {

    @Primary
    @Bean
    public ObjectMapper mapper(){
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
        mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        mapper.registerModule(new JodaModule());
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        return mapper;
    }
}

编辑2: 我不相信Spring正在使用我的ObjectMapper。我有以下代码:

@Primary
@Bean
public ObjectMapper mapper(){
    ObjectMapper mapper = new ObjectMapper();
    JodaModule mod = new JodaModule();
    mod.addSerializer(DateTime.class, new JsonSerializer<DateTime>() {
        @Override
        public void serialize(DateTime dateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
            System.out.println("Hi, bob");
        }
    });
    mapper.registerModule(mod);

    mapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
    mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    mapper.enable(SerializationFeature.INDENT_OUTPUT);

    return mapper;
}
@Primary
@豆子
公共对象映射器映射器(){
ObjectMapper mapper=新的ObjectMapper();
JodaModule mod=新的JodaModule();
mod.addSerializer(DateTime.class,新的JsonSerializer()){
@凌驾
public void serialize(DateTime DateTime、JsonGenerator、JsonGenerator、SerializerProvider SerializerProvider)引发IOException、JsonProcessingException{
System.out.println(“你好,鲍勃”);
}
});
映射器注册表模块(mod);
映射器.setPropertyNamegStrategy(PropertyNamegStrategy.CAMEL\u CASE\u到\u LOWER\u CASE\u,带下划线);
setSerializationInclusion(JsonInclude.Include.ALWAYS);
禁用(SerializationFeature.WRITE_DATES_作为时间戳);
enable(SerializationFeature.INDENT_输出);
返回映射器;
}

但是,当我在
System.out.println(“Hi,bob”)
上设置断点时,它从未被调用过——尽管我肯定是在序列化日期时间。

您可以始终遵循中提供的步骤

如果要完全替换默认的
ObjectMapper
,请定义该类型的
@Bean
,并将其标记为
@Primary

定义类型为
Jackson2ObjectMapperBuilder
@Bean
将允许您自定义默认的
ObjectMapper
XmlMapper
(分别用于
映射Jackson2httpMessageConverter
映射Jackson2xmlhttpMessageConverter

因此,您可以使用
对象映射器定义
@Bean
,如下所示:

@Primary
@Bean
public ObjectMapper mapper() {
    // Customize...
    return new ObjectMapper().setLocale(Locale.UK);
}
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();

    // Customize
    builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
    return builder;
}
或者,定义类型为
Jackson2ObjectMapperBuilder
@Bean
,并按如下方式自定义生成器:

@Primary
@Bean
public ObjectMapper mapper() {
    // Customize...
    return new ObjectMapper().setLocale(Locale.UK);
}
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();

    // Customize
    builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
    return builder;
}
进一步描述定制


为了使用
@Bean
注释注册Bean,必须在
@Configuration
类中声明
@Bean
,如中所述。

这似乎是一个bug。Spring引导文档说,用@Primary注释ObjectMapperbean应该使Spring上下文使用它,而不是Spring的默认映射器。然而,这似乎不起作用。我找到了一种不用XML的解决方法

//Since Spring won't use the custom object mapper Bean defined below for
//HTTP message conversion(eg., when a Java object is returned from a controller,
//and should be converted to json using Jackson), we must override this method
//and tell it to use a custom message converter. We configure that custom converter
//below to use our customized Object mapper.
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(mappingJackson2HttpMessageConverter());
}

//configures the converter to use our custom ObjectMapper
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
    //this line here
    jsonConverter.setObjectMapper(objectMapper());
    return jsonConverter;
}


//Primary annotation tells the Spring container to use this
//mapper as the primary mapper, instead of
//the Spring's defaultly configured mapper. Primary annotation
// DOESN'T work for some reason(this is most likely a bug and will be resolved in the future.
// When resolved, this Bean will be all it takes to tell Spring to use this ObjectMapper everywhere)
// That means that there won't be a need to configure the Http message converters manually(see method above).
@Primary
@Bean
public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    configureObjectMapper(mapper);
    return mapper;
}

//configure ObjectMapper any way you'd like
//This configuration tells the ObjectMapper to 
//(de)serialize all fields(private,protected,public,..) of all objects
//and to NOT (de)serialize any properties(getters,setters).
private void configureObjectMapper(ObjectMapper mapper) {
    //properties for jackson are fields with getters and setters
    //sets all properties to NOT be serialized or deserialized
    mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
    //tell the mapper to traverse all fields and not only default
    //default=public fields + fields with getters and setters
    //set all fields to be serialized and deserialized
    mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
}
//因为Spring不会使用下面为
//HTTP消息转换(例如,当Java对象从控制器返回时,
//并且应该使用Jackson转换为json),我们必须重写此方法
//并告诉它使用自定义消息转换器。我们配置自定义转换器
//使用我们的自定义对象映射器。
@凌驾

公共无效配置MessageConverters(列表仅创建一个并将其注册为bean?@chrylis我该怎么做?我已经在我的问题中添加了信息-我使用了第一个示例,但它似乎不起作用。camelCase名称没有更改为
camel\u case
,并且
java.util.Date
和joda
DateTime
都以正常方式显示。您的@Config启动时扫描的uration类?我必须在@configuration类的web.xml中添加几行配置,并添加了
@ComponentScan(basePackages=
com.mystuff
。它以前没有加载页面,但现在加载了,所以我假设它正在被扫描。在我的
mapper
函数中设置一个断点-它肯定会被命中。spring会自动使用我的ObjectMapper转换对象,还是我必须在某个地方指定?