简体   繁体   English

使用Jackson将java.time.localdate序列化为json

[英]Serialize java.time.localdate into json using Jackson

I'm writing a Java 8 Spring MVC application that communicates with a legacy Progress OpenEdge application using a REST service (I'm using Spring's RestTemplate for this). 我正在编写一个Java 8 Spring MVC应用程序,它使用REST服务与传统的Progress OpenEdge应用程序进行通信(我正在使用Spring的RestTemplate)。 The data I need to read from and write to the Progress application contains some dates. 我需要读取和写入Progress应用程序的数据包含一些日期。 In the Java application, I use a java.time.LocalDate datatype to represent these fields and I'm using Jackson to serialize / deserialize the data into / from Json. 在Java应用程序中,我使用java.time.LocalDate数据类型来表示这些字段,我使用Jackson将数据序列化/反序列化到Json中/从Json中反序列化。

The problem I'm having is the following. 我遇到的问题如下。 When I send data from the Progress Application, the date is send as '2015-01-02' and stored in my Java entity as a LocalDate as expected. 当我从Progress Application发送数据时,日期将作为'2015-01-02'发送,并按预期存储在我的Java实体中作为LocalDate。 When the data is send to the web front-end the Json also contains the date in the same format. 当数据发送到Web前端时,Json还包含相同格式的日期。 When I change information in the web front-end and apply it, it's also send back to the Java application as '2015-01-02' and again stored as a LocalDate without problems. 当我在Web前端更改信息并应用它时,它也会以“2015-01-02”的形式发送回Java应用程序,并再次存储为LocalDate而不会出现问题。 But when I than send the data onwards to the Progress application, the Json I receive doesn't contain the date as '2015-01-02' but as an array containing three fields (2015.0, 1.0, 2.0) and the Progress application is unable to assign this back to a date field in the database. 但是,当我将数据发送到Progress应用程序时,我收到的Json不包含日期为'2015-01-02',而是包含三个字段(2015.0,1.0,2.0)的数组,并且Progress应用程序是无法将其分配回数据库中的日期字段。

Offcourse I could write a conversion on the Progress side to convert the array back into a date, but I'd like to avoid this as I would expect the date to always be send in the ISO 8601 format. Offcourse我可以在Progress端编写一个转换来将数组转换回日期,但是我想避免这种情况,因为我希望日期始终以ISO 8601格式发送。

According to the information I find on Jackson, a java.time.LocalDate is represented as an array when WRITE_DATES_AS_TIMESTAMPS is enabled, but I have this disabled (And when the date is send to the web front-end, it's not being send as an array...) 根据我在Jackson上找到的信息,当启用WRITE_DATES_AS_TIMESTAMPS时,java.time.LocalDate表示为一个数组,但我禁用了此功能(当日期发送到Web前端时,它不会被发送为阵列...)

Here is some relevant code: 这是一些相关的代码:

The CustomObjectMapper: CustomObjectMapper:

@Service
public class CustomObjectMapper extends ObjectMapper
{
  public CustomObjectMapper()
  {
    this.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
                   false);
  }
}

The configuration in my servlet.xml 我的servlet.xml中的配置

<mvc:annotation-driven>
  <mvc:message-converters>
    <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
      <property name="objectMapper" ref="customObjectMapper"/>
    </bean>
  </mvc:message-converters>
</mvc:annotation-driven>

<bean id="customObjectMapper" class="com.msoft.utility.CustomObjectMapper"/>

The field definition: 字段定义:

@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate deliveryDate;

I'm using Java 8 with Spring 4.1.5 and Jackson 2.5.1. 我正在使用带有Spring 4.1.5和Jackson 2.5.1的Java 8。

Any tips how I could get this working or were to search for a solution would be greatly appreciated as I've already been working on this for almost 2 days... 任何提示我如何使这个工作或寻找解决方案将非常感激,因为我已经在这2天工作了...

Thanks 谢谢

EDIT: 编辑:

Some extra info... 一些额外的信息......

I've included the Jackson JSR-310 module in my pom.xml. 我在我的pom.xml中包含了Jackson JSR-310模块。 Here is the releveant part of my pom file... 这是我的pom文件的相关部分......

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.5.1</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.5.1</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.5.1</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-jsr310</artifactId>
  <version>2.5.1</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>4.1.5.RELEASE</version>
  <scope>test</scope>
  <type>jar</type>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>4.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-jpa</artifactId>
  <version>1.7.2.RELEASE</version>
</dependency>

Also, if I understood correctly, Spring will register this module automatically when it's detected. 此外,如果我理解正确,Spring会在检测到时自动注册该模块。 See the info on Jackson2ObjectMapperFactoryBean 请参阅Jackson2ObjectMapperFactoryBean上的信息

Note that Jackson's JSR-310 and Joda-Time support modules will be registered automatically when available (and when Java 8 and Joda-Time themselves are available, respectively). 请注意,Jackson的JSR-310和Joda-Time支持模块将在可用时自动注册(当Java 8和Joda-Time本身可用时)。

So I don't think I should have to do anything else to get this working correctly, but obviously I'm still missing something... 所以我认为我不应该做任何其他事情来使这个工作正常,但显然我仍然缺少一些东西......

This worked for me, and I'm not using Spring boot. 这对我有用,我没有使用Spring启动。

@Configuration
@EnableWebMvc
public class SpringMvcConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
    }
}

I think you just need to register JSR-310 (Java 8 Date/Time) module: 我想你只需要注册JSR-310(Java 8 Date / Time)模块:

https://github.com/FasterXML/jackson-datatype-jsr310/ https://github.com/FasterXML/jackson-datatype-jsr310/

since Jackson core can not rely on any Java 8 features (baseline at this point, with 2.5, is Java 6). 因为Jackson核心不能依赖任何Java 8特性(此时基线为2.5,是Java 6)。 And going forward support for most datatype libraries will go through plug-in modules anyway. 对大多数数据类型库的后续支持无论如何都将通过插件模块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 修复 Jackson 无法构造 Java.time.LocalDate 的实例 - Fix Jackson cannot construct instance of Java.time.LocalDate 将 java.time.LocalDate 与 JSTL 一起使用<fmt:formatDate>行动 - Using java.time.LocalDate with JSTL <fmt:formatDate> action 无法构造`java.time.LocalDate` 的实例 - Spring boot、elasticseach、jackson - Cannot construct instance of `java.time.LocalDate` - Spring boot, elasticseach, jackson com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造`java.time.LocalDate的实例 - com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDate Jackson 使用 Spring 引导 2 和 Kotlin 反序列化,无法构造 `java.time.LocalDate` 的实例 - Jackson deserialization with Spring Boot 2 and Kotlin, Cannot construct instance of `java.time.LocalDate` 数据类型为 java.time.LocalDate 的 @ApiModelProperty 无法解析 - @ApiModelProperty with dataType java.time.LocalDate not resolvable 上周是java.time.LocalDate吗? - Was a java.time.LocalDate in last week? Slick 3 java.time.LocalDate映射 - Slick 3 java.time.LocalDate mapping 导入java.time.LocalDate失败 - Import failing for java.time.LocalDate java.time.LocalDate 范围内的生日 - Birthdays in the scope of java.time.LocalDate
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM