JAXB没有拿起@XmlJavaTypeAdapter

时间:2011-02-04 04:53:06

标签: jaxb

我有以下类需要序列化为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注释的可​​见性有关。

感谢。

纳雷什

2 个答案:

答案 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适配器和/或在那里添加一些跟踪输出,只是为了确保适配器真的返回非空字符串吗?