【问题标题】:How to use Java 14 records with Spring framework and Jackson [duplicate]如何在 Spring 框架和 Jackson 中使用 Java 14 记录 [重复]
【发布时间】:2020-04-25 00:04:25
【问题描述】:

我有以下简单的测试

import org.springframework.web.client.RestTemplate;
import pages.TimezonePage;

class GETSimple
{
    private RestTemplate restTemplate;
    private String URL = "http://worldtimeapi.org/api/timezone/America/Los_Angeles";

    @BeforeEach
    void setUp()
    {
        restTemplate = new RestTemplate();
    }

    @Test
    void GETasPOJO()
    {
        TimezonePage response = restTemplate.getForObject(URL, TimezonePage.class);
        assertEquals("PDT", response.getAbbreviation());
        assertTrue(response.getDst());
    }
}

它适用于具有 getter 和 setter 的 TimezonePage 类。
pom.xml 的相关部分如下

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.3</version>
</dependency>

我创建了一个 Java 14 记录 TimezoneRecord,其变量与 TimezonePage 相同,但没有 getter 和 setter。然后我用

替换了get调用
TimezoneRecord response = restTemplate.getForObject(URL, TimezoneRecord.class);

没有语法错误。 运行测试时,我收到以下异常

org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class pages.TimezoneRecord]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `pages.TimezoneRecord` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

有什么办法可以解决吗?或者我不能将杰克逊与记录一起用作 POJO? 谢谢, 弗拉基米尔

【问题讨论】:

  • Records 是如此新 - 并且处于预览阶段 - 很少有图书馆能够很好地支持它们。
  • 据我了解,Jackson 尚未符合唱片公司的规定。看看这个答案:stackoverflow.com/a/61141433/2840178
  • 希望Jackson 开发者能够修复POJO 映射问题。

标签: java spring jackson jackson-databind java-14


【解决方案1】:

DateTimeDeserializer 的源代码显示它使用反序列化期间 ObjectMapper 提供的 DeserializationContext 中的时区。如果您查看 ObjectMapper API,您会看到有一种设置 TimezonePage 的方法:

public ObjectMapper setTimeZone(TimeZone tz)

因此,您可以使用此方法来配置您的 ObjectMapper 并将时区设置为正确的。

关于默认值,Javadoc 似乎说的是一回事,但代码显示的是另一回事。

Javadoc for ObjectMapper.setTimeZone(TimeZone tz):

/** * 覆盖用于格式化的默认 TimeZone 的方法。 * 使用的默认值为 {@link TimeZone#getDefault()}。 */ 但是,代码明确设置时区:

protected final static BaseSettings DEFAULT_BASE = new BaseSettings(
    ...
    // TimeZone.getDefault()
    TimeZone.getTimeZone("GMT"),
    ...

因此,显然,它实际上使用的是 GMT,而不是默认的 JVM 默认值。

我会说最好的选择可能是不依赖它并在 ObjectMapper.setTimeZone(TimeZone tz) 上自行设置。

【讨论】:

  • Alireza Zabetan,我的问题是关于使用 Java 记录而不是 POJO。时区代码只是说明问题的一个例子。你的回答没有解决。
猜你喜欢
  • 1970-01-01
  • 2020-07-30
  • 2017-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 1970-01-01
  • 2015-04-19
相关资源
最近更新 更多