Spring Boot:Jackson 不会从“application.properties”中获取配置

Posted

技术标签:

【中文标题】Spring Boot:Jackson 不会从“application.properties”中获取配置【英文标题】:Spring Boot: Jackson won't pick up configuration from "application.properties" 【发布时间】:2018-02-25 05:03:42 【问题描述】:

我有一个基于 Maven 的多模块 Spring Boot 应用程序。在我的一个模块的 application.properties 文件中,我将 Jackson 设置为 not 将日期序列化为时间戳(数组),以便它们始终序列化为字符串(这是回退行为)。属性是这样的:

spring.jackson.serialization.write_dates_as_timestamps=false

问题是...... Spring Boot/Jackson 似乎都没有选择该属性。我试图序列化的java.time.LocalDate 实例总是被写为时间戳。我检查了LocalDateSerializer.serialize(...) 方法中的代码(来自Jackson 自己的JavaTimeModule),发现了这个:

@Override
public void serialize(LocalDate date, JsonGenerator generator, SerializerProvider provider) throws IOException

    if (useTimestamp(provider))   // This always returns true
        generator.writeStartArray();
        generator.writeNumber(date.getYear());
        generator.writeNumber(date.getMonthValue());
        generator.writeNumber(date.getDayOfMonth());
        generator.writeEndArray();
     else 
        String str = (_formatter == null) ? date.toString() : date.format(_formatter);
        generator.writeString(str);
    

useTimestamp() 方法总是返回 true,无论我的配置是什么。 :(

【问题讨论】:

【参考方案1】:

也许您可以创建自定义MappingJackson2HttpMessageConverterObjectMapper。这是一个示例配置类,

@Configuration
public class MyConfiguration extends WebMvcConfigurerAdapter 
    @Bean
    public MappingJackson2HttpMessageConverter 
        getMappingJacksonHttpMessageConverter() 
        MappingJackson2HttpMessageConverter converter =
            new MappingJackson2HttpMessageConverter();
        ...

        ObjectMapper mapper = new ObjectMapper();
        ...
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        //or   
        // mapper.configure(
        // SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        converter.setObjectMapper(mapper);
        return converter;
    


【讨论】:

是否需要扩展WebMvcConfigurerAdapter? 我通常按照上面示例中的方式进行操作。对ObjectMapper 的行为进行更多控制。 创建自定义 HttpMessageConverter 让我意识到我必须将其显式注入到我尝试配置的 RestTemplate 实例中。我添加了一个答案,详细说明了我的发现。 :)【参考方案2】:

感谢因陀罗的回答,我得到了一个重要线索,帮助我找出了问题。

事实证明,我的 Spring Boot 应用程序在其应用程序上下文中有多个 RestTemplate 实例(它是一个非常大的系统,并且依赖于一些自定义的专有框架来工作)。大多数RestTemplate 实例只是为了支持我的系统架构。我应该关心只有一个 RestTemplate 实例:我编写并允许我的业务逻辑工作的实例(通过使我的系统能够使用远程RESTful API)。

所以,当我尝试配置 Jackson 及其 ObjectMapper 时,我并没有真正影响 我的 RestTemplate 实例。在读取我的配置时,RestTemplate 早已使用 Spring Boot 提供的默认设置进行了初始化。

这是我最终的配置类的样子:

@Configuration
public class RestConfiguration 

    @Bean
    public RestTemplate myRestTemplate(HttpMessageConverters customConverters) 
        RestTemplate restTemplate = new RestTemplate();
 restTemplate.setMessageConverters(customConverters.getConverters());
        return restTemplate;
    

    /*
     * The following custom HttpMessageConverter is injected into myRestTemplate
     * in order to appropriately configure the serialization/deserialization of LocalDate
     * instances into/from strings.
     */
    @Bean
    public HttpMessageConverters customConverters() 
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());  
     mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        converter.setObjectMapper(mapper);
        return new HttpMessageConverters(converter);
    


我所做的是显式配置需要配置的RestTemplate实例

以下文档也很有帮助:HttpMessageConverters。它描述了如何声明自定义 HttpMessageConverters 以在应用程序上下文中使用。

【讨论】:

以上是关于Spring Boot:Jackson 不会从“application.properties”中获取配置的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 升级后 Jackson 序列化不起作用

Spring Boot Jackson - 根据深度选择性序列化嵌入式对象属性

Spring Boot (Jackson):如何避免类名被序列化为 JSON

Spring Boot 2.3 中带有 Maven 的 Jackson 版本

更新到 Spring Boot 2 后 Jackson 模块未注册

Spring boot与Jackson ObjectMapper