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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28745557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 14:07:12  来源:igfitidea点击:

Serialize java.time.localdate into json using Hymanson

javajsonspringHymanson

提问by HeinoVDS

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). The data I need to read from and write to the Progress application contains some dates. In the Java application, I use a java.time.LocalDate datatype to represent these fields and I'm using Hymanson to serialize / deserialize the data into / from Json.

我正在编写一个 Java 8 Spring MVC 应用程序,它使用 REST 服务与遗留的 Progress OpenEdge 应用程序进行通信(我为此使用了 Spring 的 RestTemplate)。我需要读取和写入 Progress 应用程序的数据包含一些日期。在 Java 应用程序中,我使用 java.time.LocalDate 数据类型来表示这些字段,并且我使用 Hymanson 将数据序列化/反序列化到/从 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. When the data is send to the web front-end the Json also contains the date in the same format. 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. 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 应用程序发送数据时,日期作为“2015-01-02”发送,并按预期作为 LocalDate 存储在我的 Java 实体中。当数据发送到 Web 前端时,Json 还包含相同格式的日期。当我更改 Web 前端中的信息并应用它时,它也会作为“2015-01-02”发送回 Java 应用程序,并再次存储为 LocalDate 没有问题。但是当我将数据继续发送到 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 Hymanson, 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...)

根据我在 Hymanson 上找到的信息,当 WRITE_DATES_AS_TIMESTAMPS 启用时,java.time.LocalDate 表示为一个数组,但我禁用了它(当日期发送到 Web 前端时,它不会作为大批...)

Here is some relevant code:

这是一些相关的代码:

The 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.MappingHymanson2HttpMessageConverter">
      <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 Hymanson 2.5.1.

我在 Spring 4.1.5 和 Hymanson 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 Hymanson JSR-310 module in my pom.xml. Here is the releveant part of my pom file...

我在 pom.xml 中包含了 Hymanson JSR-310 模块。这是我的 pom 文件的相关部分...

<dependency>
  <groupId>com.fasterxml.Hymanson.core</groupId>
  <artifactId>Hymanson-core</artifactId>
  <version>2.5.1</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.Hymanson.core</groupId>
  <artifactId>Hymanson-annotations</artifactId>
  <version>2.5.1</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.Hymanson.core</groupId>
  <artifactId>Hymanson-databind</artifactId>
  <version>2.5.1</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.Hymanson.datatype</groupId>
  <artifactId>Hymanson-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. See the info on Hymanson2ObjectMapperFactoryBean

另外,如果我理解正确,Spring 会在检测到该模块时自动注册它。请参阅有关Hymanson2ObjectMapperFactoryBean的信息

Note that Hymanson'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).

请注意,Hymanson 的 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...

所以我认为我不需要做任何其他事情来让它正常工作,但显然我仍然缺少一些东西......

回答by Niclas

This worked for me, and I'm not using Spring boot.

这对我有用,而且我没有使用 Spring Boot。

@Configuration
@EnableWebMvc
public class SpringMvcConfiguration extends WebMvcConfigurerAdapter {

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

回答by StaxMan

I think you just need to register JSR-310 (Java 8 Date/Time) module:

我认为您只需要注册 JSR-310(Java 8 日期/时间)模块:

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

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

since Hymanson core can not rely on any Java 8 features (baseline at this point, with 2.5, is Java 6). And going forward support for most datatype libraries will go through plug-in modules anyway.

因为 Hymanson 核心不能依赖任何 Java 8 功能(此时的基线,2.5,是 Java 6)。无论如何,对大多数数据类型库的未来支持都将通过插件模块。