JAXB反序列化时Timestamp类型XmlAdapter失效问题排查
JAXB反序列化时Timestamp字段无法赋值,自定义XmlAdapter未触发
尝试将给定XML反序列化为Java对象时,所有字段均正常赋值,仅timeStamp字段例外。已编写自定义XmlAdapter用于解析Timestamp,但调试时从未进入该适配器,字段始终无法被赋值。
示例XML
<RootElement> <Id>4</Id> <Number>628</Number> <rId>110080110</rId> <OrderNmbr>1234</OrderNmbr> <Responses> <Response> <Date>2016-10-21T12:56:19.549+05:30</Date> <Premium>1232131</Premium> <Income>1231232</Income> <E1>251345</E1> <E2>7645233</E2> <Tags> <Tag> <timeStamp xsi:type="java:java.lang.String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1970-01-10 02:07:36.453</timeStamp> <Cd>3425235</Cd> <Cd1>1</Cd1> <ValText>1</ValText> <TokenId>1234</TokenId> </Tag> <Tag> <timeStamp xsi:type="java:java.lang.String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1970-01-10 02:07:36.453</timeStamp> <Cd>3425236</Cd> <Cd1>2</Cd1> <ValText>2</ValText> <TokenId>1235</TokenId> </Tag> </Tags> </Response> </Responses> </RootElement>
项目中的Java类
ExampleClass
@XmlRootElement(name = "RootElement") public class ExampleClass { @XmlElement(name = "Id") protected String pId; @XmlElement(name = "Number") protected Integer cNumber; protected Integer rId; protected String orderNmbr; @XmlElementWrapper(name = "responses") @XmlElement(name = "Response") protected List<Response> responses; // Getters and setters public class Response { protected Date date; protected BigDecimal premium; protected BigDecimal income; protected BigDecimal e1; protected BigDecimal e2; protected List<Tag> tags; // Getters and setters public class Tag { @XmlElement(name = "timeStamp", namespace = "http://www.w3.org/2001/XMLSchema-instance", type = String.class) @XmlJavaTypeAdapter(CustomTimeStampAdapter.class) protected Timestamp timeStamp; protected Integer cd; protected Integer cd1; protected String valText; protected String tokenId; // Getters and setters } } }
自定义XmlAdapter
public class CustomTimeStampAdapter extends XmlAdapter<String, Timestamp> { /** * Convert a value type to a bound type. * * @param timeStamp The value to be converted. Can be null. * @throws Exception if there's an error during the conversion. The caller is responsible for * reporting the error to the user through {@link ValidationEventHandler}. */ @Override public Timestamp unmarshal(String timeStamp) throws Exception { if (StringUtils.isBlank(timeStamp)) { return null; } return Timestamp.valueOf(timeStamp.trim()); } /** * Convert a bound type to a value type. * * @param timeStamp The value to be converted. Can be null. * @throws Exception if there's an error during the conversion. The caller is responsible for * reporting the error to the user through {@link ValidationEventHandler}. */ @Override public String marshal(Timestamp timeStamp) throws Exception { return timeStamp.toString(); } }
JAXB配置Bean
@Bean(name = "jaxb2Marshaller") public Jaxb2Marshaller getJaxb2Marshaller() { Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller(); jaxb2Marshaller.setClassesToBeBound( //all the classes the context needs to know about ExampleClass.class, Response.class, Tag.class); return jaxb2Marshaller; }
排查更新
测试发现,移除timeStamp节点中的xsi:type="java:java.lang.String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"属性后,调试器能正常进入CustomTimeStampAdapter,字符串可成功转换为Timestamp类型。确认问题与命名空间相关,正在进一步排查。
内容的提问来源于stack exchange,提问作者Lucky
相关产品推荐
相关产品推荐

