@JsonFormat DEFAULT_TIMEZONE 似乎不起作用

8t1*_*081 7 java serialization jackson

我在日期逻辑方面遇到了一些问题,我已将其与 JSON 序列化程序 Jackson 隔离。

在数据库和应用程序的调试点中,日期是正确的,并且所有内容都使用默认时区编写。但是,在序列化中增加了 4 个小时。我发现这可以通过专门告诉 Jackson 使用 EST(默认为 UTC)来解决。如下:

@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss.SSSZ", timezone="America/New_York")
private Date startDate;
Run Code Online (Sandbox Code Playgroud)

但是,问题是只有本地使用 EST,而服务器将使用 UTC。我需要杰克逊使用系统默认值。

幸运的是,我发现了这个文档支持的类似问题。新解决方案:

@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss.SSSZ", timezone=JsonFormat.DEFAULT_TIMEZONE)
private Date startDate;
Run Code Online (Sandbox Code Playgroud)

然而,它不起作用!我也尝试过timezone='DEFAULT_TIMEZONE'其他各种方法,但在所有情况下,api 输出似乎仍然比数据库中的数字早 4 小时。

我尝试过的其他事情:

  • 注销JsonFormat.DEFAULT_TIMEZONE返回##default
  • 日志TimeZone.getDefault().getDisplayName()返回Eastern Standard Time

杰克逊版本是 2.9。

有什么建议?

8t1*_*081 10

解决了我自己的问题。这是我发现的:

JsonFormat.DEFAULT_TIMEZONE不是系统默认值,如文档SO 答案所建议的那样,但实际上默认为 UTC。

org.springframework.http.converter.json.Jackson2ObjectMapperBuilder

/**
 * Override the default {@link TimeZone} to use for formatting.
 * Default value used is UTC (NOT local timezone).
 * @since 4.1.5
 */
public Jackson2ObjectMapperBuilder timeZone(TimeZone timeZone) {
Run Code Online (Sandbox Code Playgroud)

com.fasterxml.jackson.annotation.JsonFormat

/**
 * Value that indicates that default {@link java.util.TimeZone}
 * (from deserialization or serialization context) should be used:
 * annotation does not define value to use.
 *<p>
 * NOTE: default here does NOT mean JVM defaults but Jackson databindings
 * default, usually UTC, but may be changed on <code>ObjectMapper</code>.
 */
public final static String DEFAULT_TIMEZONE = "##default";
Run Code Online (Sandbox Code Playgroud)

解决方案

@Autowired
com.fasterxml.jackson.databind.ObjectMapper objectMapper;
Run Code Online (Sandbox Code Playgroud)

并且objectMapper.setTimeZone(TimeZone.getDefault())在配置类,如下所示:

package path.to.config;
import ...

@Configuration
public class JacksonConfiguration {

    @Autowired
    public JacksonConfiguration(ObjectMapper objectMapper){
        objectMapper.setTimeZone(TimeZone.getDefault());
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该将 Jackson ObjectMapper 设置为使用系统默认值而不是 Jackson 默认值 (UTC)。