我有多个时区,我想在序列化后完全拥有它们,但是如果我设置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());