【问题标题】:JAXB unmarshal has always null value for nested objectJAXB unmarshal 对于嵌套对象始终具有空值
【发布时间】:2012-09-16 09:11:38
【问题描述】:

我有一个 Web 服务,通过编写它的 WSDL 和底层 XSD 来定义,并且 java 服务器代码类/java 绑定是使用 JAXB/xjc 生成的。

一切看起来都很好服务正在正常运行......但是对于每个请求(在查看日志输出时接收后看起来格式正确),通过我的 java 代码访问时嵌套元素似乎总是为空。

有人能弄清楚为什么 customerId.getCustomer() 总是返回 null 吗?

我的 XSD(部分):

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns:tip="http://example.org/tip" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.org/tip/pro">

<complexType name="id">
  <attribute name="id" type="int" use="required"/>
  <attribute name="name" type="string" use="optional"/>
</complexType>

<complexType name="customer_id">
  <sequence>
    <element name="customer" type="tip:id" minOccurs="0"/>
  </sequence>
</complexType>

<element name="get_customer_request" type="tip:customer_id"/>

</schema>

生成的类CustomerId:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "customer_id", propOrder = {"customer"})
public class CustomerId {
  protected Id customer;

  public Id getCustomer() {
    return customer;
  }

  public void setCustomer(Id value) {
    this.customer = value;
  }
}

为 Id 生成的类看起来很相似,我不认为有什么特别之处。 在我的请求处理程序中,我得到了以下摘录:

处理程序:

JAXBElement<?> request = requestHandler.unmarshallRequest(inputStream);
Object jaxbClass = request.getDeclaredType();
expectedClass = CustomerId.class;
// next line does not throw exception with given XML
if (jaxbClass != expectedClass) throw new IllegalArgumentException();

CustomerId customerId = (CustomerId)request.getValue();
if (customerId == null) {
  logInfo("customerId: null");
} else if (customerId.getCustomer() == null) {
  // this is the part that always will be executed... why?
  logInfo("customerId.customer: null");
} else {
  logInfo("customer id: " + customerId.getCustomer().getId());
  // return mbean.getCustomer(customerId);
}

最后是一个示例请求 XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<m:get_customer_request xmlns:m="http://example.org/tip/pro">
  <customer id="0" name="help"/>
</m:get_customer_request>

我去掉了 SOAP 信封和正文标签,因为这不会造成任何问题。 谁能看到,我做错了什么? (我很确定,我确实……) 感谢您的努力!

【问题讨论】:

  • 如果你编组出你的对象的一个​​实例,生成的 XML 看起来像什么,以与我放置的内容进行比较?
  • 看起来像:example.org/tip/pro">
  • 如果你编组一个完全填充的对象模型,你会明白吗?
  • 嗯,是的。这是我从服务器日志中获取的完整输出。
  • @BlaiseDoughan:你的问题告诉我,我的完全限定对象模型的输出应该有很大不同。预期的输出是什么?除了缺少的(因为为空)客户元素之外,我看不出有什么太奇怪的东西。

标签: java xml web-services jaxb unmarshalling


【解决方案1】:

第 1 部分

当我创建一个新的 ID 并设置 customerId.customer 时,完整的 输出是

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<get_customer_request xmlns="example.com/tip/pro">
    <customer name="xy" id="1"/>
</get_customer_request>

根据此信息,您的 JAXB 映射似乎期望 customer 元素位于 example.com/tip/pro 命名空间中,并且您的请求文档应该是:

<?xml version="1.0" encoding="ISO-8859-1"?>
<m:get_customer_request xmlns:m="http://example.org/tip/pro">
  <m:customer id="0" name="help"/>
</m:get_customer_request>

第 2 部分

在我的请求中将 m: 前缀添加到客户元素时,解析器 抱怨他找到了 m:customer 和预期的客户。

这意味着您的 XML 架构与您的映射不匹配。如果您希望 customer 元素位于命名空间中,您可以将 XML 架构更改为以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<schema 
    xmlns:tip="http://example.org/tip" 
    xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://example.org/tip/pro"
    elementFormDefault="qualified">

    ...

</schema>

有关 JAXB 和命名空间的更多信息,请参阅:

【讨论】:

  • 感谢您提供清晰的答案和有用的链接。我会尝试这个并回来将您的答案标记为解决方案,我确信它会解决我的问题。
  • 我有一个月的时间来处理这个客户的其他优先事项,所以这个问题需要等待。但最终您的回答将我引向了解决方案。
猜你喜欢
  • 2011-02-07
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多