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



我有多个时区,我想在序列化后完全拥有它们,但是如果我设置DateFormat所有区域都转换为上下文时区并且如果我没有设置DateFormat所有区域都转换为UTC(零时区(,jackson将它们转换为单个时区。

我知道我们在反序列化方面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>

我能想到的唯一方法是创建自己的序列化模块,以便能够自己处理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());

相关内容

  • 没有找到相关文章

最新更新