如何根据请求设置jackson的时区?

时间:2014-06-14 15:37:17

标签: java json datetime timezone jackson

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

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

修改

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

1 个答案:

答案 0 :(得分:0)

您可以考虑自定义标准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

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