我有以下类需要序列化为XML:
@XmlAccessorType(XmlAccessType.FIELD)
public class Position {
@XmlElement(name = "Quantity", required = true)
private DecimalQuantity quantity;
...
}
我在DecimalQuantity类上放了一个XmlJavaTypeAdapter,因为我希望它只是作为没有DecimalQuantity包装器的BigDecimal序列化。
@XmlJavaTypeAdapter(DecimalQuantityAdapter.class)
@Embeddable
public class DecimalQuantity {
private BigDecimal value;
...
}
这是非常简单的DecimalQuantityAdapter类:
public class DecimalQuantityAdapter
extends XmlAdapter<BigDecimal, DecimalQuantity> {
public DecimalQuantity unmarshal(BigDecimal val) throws Exception {
return new DecimalQuantity(val);
}
public BigDecimal marshal(DecimalQuantity val) throws Exception {
return val.getValue();
}
}
我有一个单元测试,显示适配器工作正常。具有DecimalQuantity的以下Order对象被正确序列化(请注意,此测试类看起来几乎与上面的Position类相同):
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Order")
public class Order {
@XmlElement(name = "Quantity", required = true)
private DecimalQuantity quantity;
...
}
这会被序列化,如下所示 - 没有十进制数字的包装 - 生活很好!
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Order>
<Quantity>10.2</Quantity>
</Order>
当我尝试在其他maven项目中使用DecimalQuantity时,麻烦就开始了。例如,本文开头显示的Position类位于不同的maven项目中。使用Position类的Web服务是另一个maven项目。当Web服务尝试反序列化DecimalQuantity时,它不知道DecimalQuantity是什么,并且无法获取DecimalQuantityAdapter。这是我得到的错误:
Caused by: javax.xml.bind.JAXBException:
class org.archfirst.common.quantity.DecimalQuantity nor any of its super class is known to this context.
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:594)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:648)
... 53 more
我有事件试图在属性本身上添加@XmlJavaTypeAdapter注释,但JAXB不会提取它。摆脱异常的唯一方法是在Position类本身上放置一个@XmlSeeAlso({DecimalQuantity.class})。但是,这会禁用适配器,我会得到以下(不需要的)序列化:
<Quantity xsi:type="ns2:decimalQuantity" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
知道问题出在哪里?我觉得这与包装/项目中DecimalQuantity和DecimalQuantityAdapter上的JAXB注释的可见性有关。
感谢。
纳雷什
答案 0 :(得分:1)
好的,我终于找到了问题。我的单元测试是在Java运行时中获取JAXB实现,而我的真实应用程序(Web服务)正在从GlassFish中获取JAXB实现。显然,与GlassFish(2.2.1.1)捆绑在一起的实现无法处理我的用例。我通过强制我的单元测试使用jaxb-impl-2.2.1.1.jar证明了这一点。此外,似乎已在最新的JAXB实现(2.2.3-1)中修复了该错误,但我正在努力弄清楚如何用这个新版本替换GlassFish的实现(请参阅我的帖子here)。 / p>
答案 1 :(得分:0)
您确定问题出在小数XmlJavaTypeAdapter
上,而不是DecimalQuantity
类型。因为您发布的异常是当JAXB遇到未知类的值时发生的异常。
如果省略@XmlJavaTypeAdapter
注释,会发生什么?我知道它可能无法按你想要的方式工作,但错误信息是什么?是不是一样?
正如您所写,当您添加以下内容时,例外消失了:
@XmlSeeAlso({DecimalQuantity.class})
我会在代码中留下注释,并尝试找出适配器不起作用的原因。
你可以调试你的XML适配器和/或在那里添加一些跟踪输出,只是为了确保适配器真的返回非空字符串吗?