如何使用JAXB确保架构可扩展性

时间:2009-01-07 14:41:36

标签: java web-services jaxb

如果我在Glassfish v2下使用JAXB作为Metro Web Services的一部分,那么如何告诉JAXB添加:

 <xsd:any/> and <xsd:anyAttribute/>

标记到我生成的复杂类型,这样如果我将来进行更改以向我的响应对象添加元素或属性,那么我当前的客户端将不会中断。

JAXB文档似乎有些缺乏。

2 个答案:

答案 0 :(得分:1)

只需使用java.lang.Object类型即可。默认情况下,JAXB将生成xsd:any。我已成功从Web服务方法返回了一个org.w3c.dom.Node实例,其中java.lang.Object作为返回类型。我对xsd:anyAttribute会有类似的东西 - 也许使用Object返回类型和XmlAttribute JAXB注释?

增加: 以下注释看起来像是实现了您的目标。两者都是JAXB 2.0规范的一部分。

@XmlAnyAttribute @XmlAnyElement

答案 1 :(得分:1)

好的,这就是我的工作方式:

import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;
import org.w3c.dom.Element;


public class SchemaExtensible
{
    @XmlAnyElement(lax=true)
    private List<Element> otherElements;

    @XmlAnyAttribute
    private Map<QName,Object> otherAttributes;
}

这并不理想,因为现在我必须为每个我想要扩展的响应类扩展这个类(在某些情况下,这会阻止我从请求类扩展)。如果这两种方法&amp;可以增强字段级别注释以允许它们在类级别添加,然后他们可以简单地说“将相应的标记添加到模式中,如果遇到则只丢弃数据”这将是很好的。

架构片段最终看起来像这样:

<xs:complexType name="SchemaExtensible">
  <xs:sequence>
    <xs:any processContents="lax" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:anyAttribute namespace="##other" processContents="skip"/>
 </xs:complexType>

对我来说,仅允许响应对象的这种可扩展性优于Web服务版本控制,因为它允许您一点一点地发展架构,如果您愿意,而不必担心管理许多不同版本,并且不必担心如果向响应对象添加单个新属性或元素,则任何现有客户端都将中断。