杰克逊将不同的时区序列化为单个时区

时间:2018-01-24 00:45:16

标签: java serialization jackson timezone

我有多个时区,我希望在序列化后完全拥有它们,但jacksonDateFormat转换为单个时区如果我设置DateFormat所有区域转换为上下文时区,如果我没有&#39 ; t set UTC所有区域都转换为DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE(零时区)。

我知道我们在反序列化中有SerializationFeature,我们可以禁用它,但我无法在jackson中找到类似的内容。

无论如何,我可以告诉import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import java.text.SimpleDateFormat; import java.util.TimeZone; public class Test { public static class flight { private XMLGregorianCalendar dateDeparture; private XMLGregorianCalendar dateArrival; public XMLGregorianCalendar getDateDeparture() { return dateDeparture; } public void setDateDeparture(XMLGregorianCalendar dateDeparture) { this.dateDeparture = dateDeparture; } public XMLGregorianCalendar getDateArrival() { return dateArrival; } public void setDateArrival(XMLGregorianCalendar dateArrival) { this.dateArrival = dateArrival; } } public static void main(String[] args) throws DatatypeConfigurationException, JsonProcessingException { XMLGregorianCalendar dateDeparture = DatatypeFactory.newInstance().newXMLGregorianCalendar(2018,1,22,10,15,0,0, TimeZone.getTimeZone("Asia/Istanbul").getRawOffset()/1000/60); XMLGregorianCalendar dateArrival = DatatypeFactory.newInstance().newXMLGregorianCalendar(2018,1,22,13,30,0,0,TimeZone.getTimeZone("Asia/Dubai").getRawOffset()/1000/60); System.out.println("Local Departure Time=" + dateDeparture); System.out.println("Local Arrival Time=" + dateArrival); flight flight = new flight(); flight.setDateDeparture(dateDeparture); flight.setDateArrival(dateArrival); XmlMapper xmlMapper = new XmlMapper(); xmlMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); xmlMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ")); String xml = xmlMapper.writeValueAsString(flight); System.out.println(xml); } } 不要转换时区吗?

这是我的测试类:

Local Departure Time=2018-01-22T10:15:00.000+03:00
Local Arrival Time=2018-01-22T13:30:00.000+04:00
<flight><dateDeparture>2018-01-22T10:45:00+0330</dateDeparture><dateArrival>2018-01-22T01:00:00+0330</dateArrival></flight>

这是输出:

SqlDependency

1 个答案:

答案 0 :(得分:1)

我能想到的唯一方法是创建自己的序列化模块,以便能够自己处理XMLGregorianCalendar序列化。不幸的是,Java已被证明在处理日期方面不太好。

public class XMLCalendarSerializer extends StdSerializer<XMLGregorianCalendar> {
    public XMLCalendarSerializer() {
        this((Class)null);
    }

    public XMLCalendarSerializer(Class<XMLGregorianCalendar> t) {
        super(t);
    }

   public void serialize(XMLGregorianCalendar value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
        DateFormat dateFormatt = provider.getConfig().getDateFormat();
        if(dateFormatt.getCalendar() == null) {
            jgen.writeString(value.toString());
        } else {
            SimpleDateFormat dateFormat = (SimpleDateFormat)dateFormatt;
            GregorianCalendar a = value.toGregorianCalendar();
            Date date = value.toGregorianCalendar().getTime();
            dateFormat.setTimeZone(TimeZone.getTimeZone(value.getTimeZone(value.getTimezone()).getDisplayName()));
            jgen.writeString(dateFormat.format(date));
        }

    }
}

,模块类就像:

public class XMLCalendarModule extends SimpleModule {
    private static final String NAME = "CustomXMLCalendarModule";
    private static final VersionUtil VERSION_UTIL = new VersionUtil() {
};

    public XMLCalendarModule() {
        super("CustomXMLCalendarModule", VERSION_UTIL.version());
        this.addSerializer(XMLGregorianCalendar.class, new XMLCalendarSerializer());
    }
}

您只需将此模块注册为:

xmlMapper.registerModule(new XMLCalendarModule());