【问题标题】:JAXB with namespace unmarshalling (using Jersey from REST service)具有命名空间解组的 JAXB(使用来自 REST 服务的 Jersey)
【发布时间】:2010-06-22 22:23:07
【问题描述】:

我正在尝试从 Convio 的公共 api 中解组一个简单的 xml 文档。以下代码我没有收到任何编译器错误,但它也不会产生结果。值为空。如果我从 xml 文档中删除模式和命名空间项并从 POJO 中删除命名空间属性,那么它将运行得很好。为了能够使用 xsd 文档/命名空间,我缺少什么?

我正在尝试解析的 XML 示例

<?xml version='1.0' encoding='UTF-8'?>
<getSingleSignOnTokenResponse xsi:schemaLocation="http://convio.com/crm/v1.0 http://service.convio.net/xmlschema/crm.public.v1.xsd" xmlns="http://convio.com/crm/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <token>abcdefghijklmnopqrstuvwxyz</token>
  <cons_id>0123456789</cons_id>
</getSingleSignOnTokenResponse>

还有带有注释的 POJO:

@XmlRootElement(name = "getSingleSignOnTokenResponse", namespace = "http://convio.com/crm/v1.0")
public class SingleSignOnResponseBean
{
  @XmlElement(name = "token")
  public String token;
  @XmlElement(name = "cons_id")
  public int consId;
}

现在,我正在使用 Jersey 来完成实际工作,但由于我无法使用 Jersey 对其进行解组,因此我在我的机器上使用静态 xml 文件手动设置了一个解组器,上面的 XML 结果:

    JAXBContext jc = JAXBContext.newInstance(new Class[] {org.orgname.utility.convio.sso.api.SingleSignOnResponseBean.class});
    Unmarshaller u = jc.createUnmarshaller();
    SingleSignOnResponseBean bean2 = (SingleSignOnResponseBean) u.unmarshal(new File("C:/token.xml"));
    System.out.println(bean2.token);

这可能非常简单,我只是不明白为什么如果定义了架构和命名空间元素它将不起作用。我已经看到其他一些关于设置某种 SAX 过滤器以去除名称空间的 cmets,但由于我是通过 jersey 的 REST 调用直接进入的,所以我不相信我有机会这样做。有什么想法吗?

【问题讨论】:

    标签: java jaxb jersey


    【解决方案1】:

    您可以添加一个包级别的注释(这是在一个名为 package-info 的类上完成的)并指定 elementFormDefault="qualified",那么您就不需要限定每个 @XmlElement 注释。

    @javax.xml.bind.annotation.XmlSchema(
       namespace="http://convio.com/crm/v1.0".
       elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 
    package com.convio.crm; 
    

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

    【讨论】:

    • 如何提供多个命名空间?
    【解决方案2】:

    命名空间不是由绑定类上的字段“继承”的。您还需要在字段上定义命名空间:

    @XmlRootElement(name = "getSingleSignOnTokenResponse", namespace = "http://convio.com/crm/v1.0")
    public class SingleSignOnResponseBean
    {
      @XmlElement(name = "token", namespace = "http://convio.com/crm/v1.0")
      public String token;
      @XmlElement(name = "cons_id", namespace = "http://convio.com/crm/v1.0")
      public int consId;
    }
    

    如果您省略它们,则这些字段将返回到“默认”命名空间(即没有命名空间)。

    有点刺激,但就是这样。

    【讨论】:

    • 完美!我知道我一定错过了一些非常简单的东西。这有点令人恼火,尤其是在花了半个下午与之抗争之后。谢谢。
    • 前缀呢?
    猜你喜欢
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 2020-11-30
    • 2010-12-10
    • 2013-10-24
    • 2014-11-28
    • 1970-01-01
    相关资源
    最近更新 更多