2017-09-16 76 views
1

我有一个基于Maven的多模块Spring应用程序。在我的一个模块的application.properties文件中,我将Jackson设置为而不是将日期序列化为时间戳(数组),以便它们始终作为字符串序列化(这是回退行为)。该物业是这样的:Spring Boot:杰克逊不会从“application.properties”中获取配置

spring.jackson.serialization.write_dates_as_timestamps=false 

问题是...财产似乎并没有通过任何春启动/杰克逊被拾起。我试图序列化的java.time.LocalDate实例总是被写为时间戳。我已经检查了LocalDateSerializer.serialize(...)方法里面的代码(来自杰克逊自己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,不管我的配置是什么。 :(

回答

0

由于Indra的答案,我得到了一个重要线索,帮助我找出问题。

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

所以,当我试图配置杰克逊及其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。

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; 
    } 

} 
+0

是否需要扩展WebMvcConfigurerAdapter? – Enrique

+0

我通常按照上面示例中的方式完成。更多的控制'ObjectMapper'的行为。 –

+0

创建一个自定义的'HttpMessageConverter'使我意识到必须将它明确地注入到我试图配置的RestTemplate实例中。我添加了一个详细说明我的发现的答案。 :) – Enrique