具有命名空间解组功能的 JAXB(使用 REST 服务中的 Jersey)

发布于 2024-09-06 19:24:08 字数 1477 浏览 1 评论 0原文

我正在尝试从 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 对其进行解组,因此我使用 a 手动设置了一个解组器我的机器上的静态 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 过滤器来删除名称空间的其他评论,但由于我是直接从 jersey 通过 REST 调用进入的,所以我不相信我有机会这样做。有什么想法吗?

I'm trying to unmarshal a simple xml document from a public api from Convio. I'm not getting any compiler errors with the following code, but it won't produce a result either. The values are null. If I remove the schema and namespace items from the xml document and remove the namespace attribute from the POJO then it will run just fine. What am I missing to be able to work with the xsd document / namespace?

XML example that I'm trying to parse

<?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>

And the POJO with annotations:

@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;
}

Now, I'm using Jersey to do the actual work, but since I couldn't get it to unmarshal using Jersey, I set up an unmarshaller by hand using a static xml file on my machine of the XML result above:

    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);

This is probably very simple and I'm just not seeing it on why it won't work if the schema and namespace elements are defined. I've seen some other comments about setting up some sort of SAX filter to strip out the namespace, but since I'm coming in via a REST call from jersey directly I don't believe I have the opportunity to do that. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

叹梦 2024-09-13 19:24:09

您可以添加包级别注释(这是在名为 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 和命名空间的更多信息,请参阅:

You could add a package level annotation (this is done on a class called package-info) and specify elementFormDefault="qualified", then you wouldn't need to qualify each @XmlElement annotation.

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

For more information on JAXB and namespaces see:

筑梦 2024-09-13 19:24:09

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

@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;
}

如果省略它们,则字段将返回“默认”命名空间(即无命名空间)。

这有点令人恼火,但事实就是这样。

The namespace is not "inherited" by the fields on the bound class. You need to define the namespace on the fields as well:

@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;
}

If you omit them, then the fields go back to the "default" namespace (i.e. no namespace).

It's mildly irritating, but that's the way it is.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文