【问题标题】:How to set timezone of jackson on a per-request-basis?如何根据每个请求设置杰克逊的时区?
【发布时间】:2014-08-04 23:16:20
【问题描述】:

我正在使用 Spring WebMVC、JodaTime 和 Jackson 来构建 RESTful 网络服务。 每个对此网络服务执行操作的用户都将其默认时区保存在数据库中。
我需要在用户时区提供所有时间戳。我能够将响应对象中的每个时间戳转换为用户的对应时区,但杰克逊将每个时间戳反序列化为特定时区,例如 UTC。

如何防止杰克逊这样做?我希望在其时区中序列化一个日期时间字段,而不是为杰克逊设置的时区。
我使用的是完整的 ISO6801 格式。

编辑:

对于偶然发现这个问题的任何人,Github 目前正在讨论这个主题: https://github.com/FasterXML/jackson-datatype-joda/issues/43

【问题讨论】:

标签: java json datetime timezone jackson


【解决方案1】:

您可以考虑自定义标准 Joda 时间反序列化器,以从每个请求设置的线程局部变量中读取时区信息。

这是一个例子:

public class JacksonTimezone {

    public static class DataTimeDeserializerTimeZone extends DateTimeDeserializer {
        public static final ThreadLocal<DateTimeZone> TIME_ZONE_THREAD_LOCAL = new ThreadLocal<DateTimeZone>() {
            @Override
            protected DateTimeZone initialValue() {
                return DateTimeZone.getDefault();
            }
        };

        public DataTimeDeserializerTimeZone() {
            super(DateTime.class);
        }

        @Override
        public ReadableDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
            return super.deserialize(jp, ctxt).toDateTime().withZone(TIME_ZONE_THREAD_LOCAL.get());
        }
    }

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        JodaModule module = new JodaModule();
        module.addDeserializer(DateTime.class,
                (JsonDeserializer) new DataTimeDeserializerTimeZone());
        mapper.registerModule(module);

        DateTime dateTime1 = DateTime.parse("2014-02-03T10:00");
        String json = mapper.writeValueAsString(dateTime1);
        System.out.println(json + " " + TIME_ZONE_THREAD_LOCAL.get());
        System.out.println(mapper.readValue(json, DateTime.class));
        TIME_ZONE_THREAD_LOCAL.set(DateTimeZone.forID("US/Hawaii"));
        System.out.println(mapper.readValue(json, DateTime.class));

    }
}

输出:

1391418000000 Europe/Oslo
2014-02-03T10:00:00.000+01:00
2014-02-02T23:00:00.000-10:00

TIME_ZONE_THREAD_LOCAL 静态变量的值应在 JSON 数据到达 Jackson 之前设置为正确的时区。

【讨论】:

  • 如果扩展现有的序列化程序是唯一的选择,我会这样做。谢谢你的例子!
猜你喜欢
  • 1970-01-01
  • 2011-11-25
  • 2018-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多