我正在使用第三方库将XML消息转换为POJO。 该库使用jaxb注释。 其中一个类的例子。
package com.xxx.convert;
import java.util.Date;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.xxx.convert.jaxb.extensions.DateTimeAdapter;
......................
@XmlRootElement(
namespace = "http://xsd.com/xxx/convertor",
name = "NonTradingOrder"
)
@XmlType(
name = "NonTradingOrder",
propOrder = {"requestor", "valueDate",
"raised", "state", "description", "rawOrder"}
)
@XmlSeeAlso({CashInOrder.class,
CashInterAccountTransferOrder.class,
CashOutOrder.class})
public abstract class NonTradingOrder extends Order {
private UserRef requestor;
private LocalDate valueDate;
private Date raised;
private OrderState state;
private String description;
private String rawOrder;
..........
@XmlAttribute(
name = "Raised",
required = true
)
@XmlJavaTypeAdapter(DateTimeAdapter.class)
public Date getRaised() {
return this.raised;
}
.......
}
我遇到了com.xxx.convert.jaxb.extensions.DateTimeAdapter类中的问题。 目前,我需要处理来自我之前没有处理过的新来源的消息。我发现这个库不了解新来源的日期时间格式。
我无法更改源消息中的日期时间格式。
我可以要求修复库中的问题,但是大约需要两个月,我没有时间。
该库包含大约100个不同类型消息的类,我不想重写它。目前我有很多使用这个库的代码。
有没有人对HOT FIX这个问题有什么想法?
其他一些信息:
class com.xxx.convert.jaxb.extensions.DateTimeAdapter
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class DateTimeAdapter extends XmlAdapter<String, Date> {
private final SimpleDateFormat dateTimeFormat =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S");
.......
public Date unmarshal(String value) throws Exception {
SimpleDateFormat var2 = this.dateTimeFormat;
synchronized(this.dateTimeFormat) {
this.dateTimeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
return this.dateTimeFormat.parse(value);
}
}
}
消息示例:
<?xml version="1.0"?>
<proto:Message xmlns:tr=............>
<proto:MainObject>
<tr:NonTradingOrderNew EventTime="2017-06-26T12:21:38.6397505+03:00">
<tr:Order xsi:type="tr:CashInterAccountTransferOrder"
ID="...."
CreationTime="2017-06-26T12:21:38.6397505+03:00"
ValueDate="2017-06-26"
Raised="2017-06-26T12:21:38.6397505+03:00">
<tr:Requestor ID="6019" Name="......." />
<tr:State Status="Executing" StatusDate="2017-06-26" />
<tr:Source ..... />
<tr:Target ..... />
<c:Amount Value="300000.00" Currency="EUR" />
</tr:Order>
</tr:NonTradingOrderNew>
</proto:MainObject>
</proto:Message>
处理邮件的主要代码:
import com.xxx.convert.Message;
import javax.xml.bind.*;
import java.io.StringReader;
import java.io.StringWriter;
public class SerializerEx {
private static JAXBContext context;
private static void initIfNeed() throws JAXBException {
if (null == context) {
context = JAXBContext.newInstance(
Message.class
);
}
}
public static Object deserialize(String xmlText) {
try {
initIfNeed();
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader stringReader = new StringReader(xmlText);
Object ddmObject = unmarshaller.unmarshal(stringReader);
return ddmObject;
} catch (Exception ex) {
LOG.error("Cannot read xml message for " + xmlText, ex);
context = null;
return null;
}
}
.........................
}
我有一次尝试解决问题,但我失败了。
我创建了新的数据时间处理器(我使用java 8)
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.TimeZone;
public class DateTimeAdapterNew extends XmlAdapter<String, Date> {
........
public Date unmarshal(String value) throws Exception {
ZonedDateTime zonedDateTime = ZonedDateTime.parse(value);
java.util.Date date = Date.from(zonedDateTime.toInstant());
return date;
}
}
在包com.xxx.convert
中创建文件package-info.java@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(type=Date.class,
value=DateTimeAdapterNew.class),
})
package com.xxx.convert;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
import java.util.Date;
import com............DateTimeAdapterNew;
但在测试中引发了异常:
Cannot read xml message for <?xml version="1.0"?>
<proto:Message .........>
javax.xml.bind.UnmarshalException: Unable to create an instance of ........NonTradingOrder
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726) ~[?:1.8.0_92]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247) ~[?:1.8.0_92]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:690) ~[?:1.8.0_92]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:171) ~[?:1.8.0_92]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiTypeLoader.startElement(XsiTypeLoader.java:65) ~[?:1.8.0_92]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:559) ~[?:1.8.0_92]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538) ~[?:1.8.0_92]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:380) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2787) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:118) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213) ~[?:1.8.0_92]
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643) ~[?:1.8.0_92]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243) ~[?:1.8.0_92]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214) ~[?:1.8.0_92]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) ~[?:1.8.0_92]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214) ~[?:1.8.0_92]
at ...........SerializerEx.deserialize(SerializerEx.java:51) [classes/:?]