2

I am using Spring WebMVC, JodaTime and Jackson to build a RESTful webservice. Every user who performs actions on this webservice has his default timezone saved in the database.
I need to provide all timestamp in the users timezone. I am able to convert every timestamp in a response object to the correspondending timezone of the user, but jackson deserializes every timestamp to a specific timezone, for example UTC.

How do I prevent jackson from doing this? I want a datetime field to be serialized in its timezone, not the timezone set for jackson.
I am using full ISO6801 format.

Edit:

For anyone who stumbles upon this question, there is currently a discussion going on at Github about this topic: https://github.com/FasterXML/jackson-datatype-joda/issues/43

Thomas Eizinger
  • 1,404
  • 14
  • 25
  • Some code and data examples would be helpful. See [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). – Matt Johnson-Pint Jun 15 '14 at 17:53
  • Possibly related: [How to serialize Joda DateTime with Jackson JSON processer?](http://stackoverflow.com/q/3269459/634824) – Matt Johnson-Pint Jun 15 '14 at 17:56
  • @MattJohnson I appreciate your links but I don't see how a code example would be any helpful here, mainly because I use Spring and I therefore don't invoke the ObjectMapper instance myself. Also the other question is only somehow related because I don't have any problems with serializing in general. – Thomas Eizinger Jun 16 '14 at 00:16
  • However, [this](https://stackoverflow.com/questions/21440619/spring-controller-jackson-joda-date-time-how-maintain-timezone?rq=1) question is related but unanswered. – Thomas Eizinger Jun 16 '14 at 00:20

1 Answers1

0

You can consider customizing the standard Joda time deserializer to read the timezone information from a thread local variable set by every request.

Here is an example:

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));

    }
}

Output:

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

The value of the TIME_ZONE_THREAD_LOCAL static variable should be set to the correct timezone before JSON data reaches Jackson.

Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48