转换LocalDateTime字段

时间:2016-08-18 15:13:43

标签: spring mongodb spring-boot spring-data spring-data-rest

在我们的项目中,我们使用spring data rest(MongoDB)。 文件:

@Document(collection = "brands")
@Data
@Accessors(chain = true)
public class BrandDocument {
    @Id
    private String id;

    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;

    private String name;
    private Set<String> variants;
}

配置:

@SpringBootApplication
@EnableDiscoveryClient
@EnableMongoAuditing
public class DictionaryService extends RepositoryRestConfigurerAdapter {
    public static void main(String[] args) {
        SpringApplication.run(new Object[]{ DictionaryService.class }, args);
    }

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(BrandDocument.class);
    }
}

如果我尝试获取BrandDocument:

curl -X GET -H "Cache-Control: no-cache" -H "Postman-Token: c12dbb65-e173-7ff3-2187-bdb6adbdebe9" "http://localhost:7090/typeDocuments/"

我会看到答案:

{
...
   "lastModifiedDate": {
       "content": "2016-08-10T15:50:05.609"
   }
...
}

在gradle deps中我有转换java 8 LocalDateTime:

compile     group: 'com.fasterxml.jackson.datatype',    name: 'jackson-datatype-jsr310'

如果我尝试保存对象,请将POST请求发送到http://localhost:7090/typeDocuments/,内容为:

{
    ...
       "lastModifiedDate": {
           "content": "2016-08-10T15:50:05.609"
       }
    ...
}

我有转换错误,但是如果:

{
...
"lastModifiedDate": "2016-08-10T15:50:05.609"
...
}

保存确定。

为什么杰克逊为“lastModifiedDate”添加“内容”字段?我怎么能改变它?

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,结果是弹簧启动/弹簧数据问题,而不是杰克逊。

Spring数据扫描数据类并检测类型LocalDateTime的字段。此类未注册为&#34;简单类型&#34;因此,在序列化之前,它已转换为PersistentEntityResource(带有名为content的字段)。 content来自哪里。

解决方案是将所有JSR-310类型注册为simpe类型:

@Bean
public MongoMappingContext mongoMappingContext() {
    MongoMappingContext context = new MongoMappingContext();
    context.setSimpleTypeHolder(new SimpleTypeHolder(new HashSet<>(Arrays.asList(
            Instant.class,
            LocalDateTime.class,
            LocalDate.class,
            LocalTime.class,
            MonthDay.class,
            OffsetDateTime.class,
            OffsetTime.class,
            Period.class,
            Year.class,
            YearMonth.class,
            ZonedDateTime.class,
            ZoneId.class,
            ZoneOffset.class
    )), MongoSimpleTypes.HOLDER));
    return context;
}

答案 1 :(得分:0)

您是否指定杰克逊的ObjectMapper使用jackson-datatype-jsr310的序列化/反序列化器的任何地方?如果不是,你可以这样做:

@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModules(new JavaTimeModule());
        return mapper;
    }
}