如何调试 JAXB 解组?
Posted
技术标签:
【中文标题】如何调试 JAXB 解组?【英文标题】:How to debug JAXB unmarshalling? 【发布时间】:2012-02-03 18:31:46 【问题描述】:我遇到了 JAXB 解组的问题。我想我已经正确编码了,但是我的未编组对象返回空参数。因此,我假设在解组时,JAXB 没有看到它所期望的适当的 XML 结构。但是,我没有收到任何错误消息或抛出任何异常。
是否可以逐步完成解组过程,以准确查看它在哪里/为什么无法填充我的对象?
实际的解组代码相当普通:
public <T> T unmarshall(Node node, Class<T> clazz) throws JAXBException
// Creating an unmarshaller
Unmarshaller u = JAXBContext.newInstance(clazz).createUnmarshaller();
// unmarshal an instance node into Java content
return clazz.cast(u.unmarshal(node, clazz).getValue());
但是,当我调用它时,我得到了一个 clazz 类型的对象返回(如预期的那样),但未填充。
我试图解组的 DOM 对象是由第三方 API 生成的。我已经在解组时遇到了一些非常奇怪的行为,这就是为什么我希望能够调试该过程。例如,如果我尝试解组 DOM 对象中的子元素(即:doc.getByElementName("myElement").item(0)),它会静默失败。但是,如果我将文档转换为字符串,然后将其重新导入新文档,则可以正常转换。
我开始感到很沮丧,不知道如何调试这个问题。
感谢您的任何见解!
埃里克
【问题讨论】:
【参考方案1】:其他人是否应该像我一样偶然发现这一点。 https://www.kevinhooke.com/2014/03/25/debugging-jaxb-unmarshalling-issues/
这篇博文很重要
将以下内容传递到您的启动命令中
-Djaxb.debug=true
然后添加以下EventHandler。
Unmarshaller um = jaxbContext.createUnmarshaller();
um.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler());
希望对您有所帮助。在我的 jetty web 应用程序中,这会导致明显的错误冒泡,我很容易发现命名空间问题。
【讨论】:
【参考方案2】:JAXBContext context = JAXBContext.newInstance(jaxbObjectClass);
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler());
【讨论】:
关于此代码 sn-p 如何回答问题的一两条评论会有所帮助。 DefaultValidationEventHandler 是旧的 JAXB 1.0 处理程序 - 对吧?您是否建议将此作为答案,因为旧处理程序会吐出更详细的错误消息? 来自 javadocs:公共类 DefaultValidationEventHandler 扩展 Object 实现 ValidationEventHandler JAXB 1.0 唯一的默认验证事件处理程序。这是从 JAXBContext 创建的所有对象的默认处理程序,它管理由 JAXB 1.0 绑定编译器生成的模式派生代码。此处理程序导致解组和验证操作在第一个错误或致命错误时失败。【参考方案3】:您可以采用的一种方法是使用 JAXB 从带注释的类中生成 XML 模式。这表示 JAXB 期望输入文档的样子。然后根据这个 XML 模式验证您的 XML 文档,看看它是否符合 JAXB 的期望。
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JAXB/GenerateSchema【讨论】:
感谢您的链接。以前从未尝试过;会试一试。但是鉴于我从 XSD 生成了 JAXB 类,这似乎是倒退了。但我仍然认为它不是一个优雅的解决方案。 JAXB 就像一个完整的黑匣子,没有任何指标来解释它在做什么,我不知道它为什么会失败。我很想找到一种方法让我“看到”它在做什么和/或问题出在哪里。 感谢您的建议。我尝试使用验证器,它抛出了一个我不明白的错误。我为此创建了一个单独的线程(***.com/questions/8761930/…)。如果您能提出任何建议,我将不胜感激。谢谢。 确实,这是迄今为止我发现的最佳方法,因为other approaches 根本不会产生好的和/或富有成效的结果。但是,我建议不要使用soapUI
来生成测试消息,因为它会生成一个没有任何(假)数据值的消息框架,迫使您手动键入容易出错的所有内容,尤其是对于大型消息。相反,Altova 的 XMLSpy 创造了奇迹。您需要做的就是选择create New SOAP request" item from the
SOAP` 菜单,瞧!您得到了一个完美的(假的)消息。以上是关于如何调试 JAXB 解组?的主要内容,如果未能解决你的问题,请参考以下文章
在将 XML 文件解组为对象后,如何让 JAXB 调用方法?
如果命名空间声明在 SOAP 信封上,如何使用 JAXB 解组 SOAP 响应?