3

我目前正在尝试在我的 XML 模式中对Spring LDAP 过滤器进行建模。这涉及多态类型,可以任意嵌套:

<andFilter>
  <notFilter>
     <equalsFilter name="mail" value="asfd@example.com" />
  </notFilter>
  <likeFilter name="mail" value="asdf*" />
</andFilter>

这就是我在 xsd 中定义上述过滤器的方式(我实际上定义了一些中间抽象类型,但为简单起见将它们省略了):

<xsd:complexType name="baseFilterType" abstract="true" />
<xsd:element name="filter" type="tns:baseFilterType" />

<xsd:complexType name="andFilterType">
  <xsd:sequence>
    <xsd:element ref="tns:filter" minOccurs="1" maxOccurs="unbounded" />
  </xsd:sequence>
</xsd:complexType>
<xsd:element name="andFilter" type="tns:andFilterType" substitutionGroup="tns:filter" />

<xsd:complexType name="notFilterType">
  <xsd:sequence>
    <xsd:element ref="tns:filter" />
  </xsd:sequence>
</xsd:complexType>
<xsd:element name="notFilter" type="tns:notFilterType" substitutionGroup="tns:filter" />

<xsd:complexType name="likeFilterType">
  <xsd:sequence>
    <xsd:element ref="tns:attributeName" />
    <xsd:element ref="tns:value" />
  </xsd:sequence>
</xsd:complexType>
<xsd:element name="likeFilter" type="tns:likeFilterType" substitutionGroup="tns:filter" />

<xsd:complexType name="equalsFilterType">
  <xsd:sequence>
    <xsd:element ref="tns:attributeName" />
    <xsd:element ref="tns:value" />
  </xsd:sequence>
</xsd:complexType>
<xsd:element name="equalsFilter" type="tns:equalsFilterType" substitutionGroup="tns:filter" />

我已经用一些自定义行为扩展了每个过滤器类(以实现访问者模式),但我不知道如何让 JAXB 绑定到这些过滤器类,而不是JAXBElement<? extends BaseFilterType>在整个生成的类中使用它。

JAXB 模型类是在构建时生成的,因此我不能直接修改它们——我必须使用外部定制绑定来进行任何定制。我已经尝试了implClassbaseClass自定义,但无法弄清楚如何做到这一点。

任何人都可以帮忙吗?

编辑:我使用 Spring's Jaxb2Marshallerwith contextPathsset 进行编组和解组。我希望这可以ObjectFactory用于对象实例化,但似乎并非如此。

编辑 2:过滤器元素由顶级元素以及彼此引用,例如:

<xsd:element name="GetAttributesRequest">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element ref="filter:filter" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

因此,GetAttributesRequest对象将被标记,@XmlRootElement而过滤器类本身则不会。但是,即使是顶级GetAttributesRequest对象也没有被ObjectFactory...实例化

4

1 回答 1

0

编辑 :

问题作者使用的解决方案:

我最终使用 JAXB 绑定自定义来使 ObjectFactory 生成我的类的实例,然后在 Spring 的 Jaxb2Marshaller 上设置 com.sun.xml.internal.bind.ObjectFactory(注意内部)unmarshaller 属性以强制它使用工厂。


原始答案:

是的,可以将行为添加到生成的类中。您想查看相关文档

这是文档中的一个简单示例:

JAXB 生成的代码

package org.acme.foo;

@XmlRootElement
class Person {
  private String name;

  public String getName() { return name; }
  public void setName(String) { this.name=name; }
}

@XmlRegistry
class ObjectFactory {
  Person createPerson() { ... }
}

扩展类

包 org.acme.foo.impl;

class PersonEx extends Person {
  @Override
  public void setName(String name) {
    if(name.length()<3) throw new IllegalArgumentException();
    super.setName(name);
  }
}

@XmlRegistry
class ObjectFactoryEx extends ObjectFactory {
  @Override
  Person createPerson() {
    return new PersonEx();
  }
}

解组示例

Unmarshaller u = context.createUnmarshaller();
u.setProperty("com.sun.xml.bind.ObjectFactory",new ObjectFactoryEx());
PersonEx p = (PersonEx)u.unmarshal(new StringReader("<person />"));

更多信息在这里

于 2013-01-15T15:54:09.243 回答