1

我有以下简单的测试

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。然后我用

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?谢谢,弗拉基米尔

4

1 回答 1

-2

DateTimeDeserializer 的源代码显示它使用 DeserializationContext 中的时区,该时区由 ObjectMapper 在反序列化期间提供。如果您查看 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) 上设置它。

于 2020-04-25T00:21:37.930 回答