如何使用XML/XSD定义JAXB抽象类并实现继承?

Sam*_*lly 5 java xml xsd jms jaxb

寻找一种方法来定义基本 XML 模式,以便在其他模式上重用为 XML 消息,这些消息将用于不同的 JMS 消息负载。其目的是:

  • XmlMessage - 定义所有消息都将作为其发送的消息基类。
  • 标头 - 所有消息都将具有的包含有关消息的元数据的类
  • Body - 每个特定消息实现可用于定义每个单独消息的消息负载的抽象类

这种方法将:

  • 允许 JMS EJB 将传入的 XML 解组到高级通用 XmlMessage 中,然后能够评估 Body 实现的类类型以确定如何处理消息。
  • 标准化各种消息格式。
  • 利用 JAXB 生成要在发送消息的客户端和处理消息的 EJB 上使用的 Java 类。
  • 利用 JAXB 编组/解编消息负载中的 XML。

Sam*_*lly 5

请参阅以下 XSD 模式和 JAXB 实现来完成为 Message\xe2\x80\x99s Body 定义抽象类

\n\n

XmlMessage.xsd 定义所有消息的格式:

\n\n
<?xml version="1.0" encoding="UTF-8"?>\n<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.samnunnally.com" targetNamespace="http://www.samnunnally.com" version="1.0">\n<xs:element name="xmlMessage">\n    <xs:complexType>\n        <xs:sequence>\n            <xs:element name="header" type="header" minOccurs="1" maxOccurs="1"/>\n            <xs:element ref="body"/>\n        </xs:sequence>\n    </xs:complexType>\n</xs:element>\n<xs:complexType name="header">\n    <xs:sequence>\n        <xs:element name="message_class" type="xs:string"/>\n        <xs:element name="message_id" type="xs:int"/>\n        <xs:element name="message_length" type="xs:int"/>\n        <xs:element name="software_version" type="xs:string"/>\n        <xs:element name="correlation_id" type="xs:string"/>\n        <xs:element name="session_id" type="xs:string"/>\n        <xs:element name="return_code" type="xs:string"/>\n    </xs:sequence>\n</xs:complexType>\n<xs:element name="body" type="body"/>\n<xs:complexType name="body" abstract="true">\n    <xs:sequence/>\n</xs:complexType>\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n

实现 XmlMessage.xsd 的示例 xsd。最终是包含客户列表的消息 Foo。关键是使用 replacementGroup 属性和 xs:extension base="body"

\n\n
<?xml version="1.0" encoding="UTF-8"?>\n<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"\n       xmlns="http://www.samnunnally.com" \n       targetNamespace="http://www.samnunnally.com" \n       version="1.0">\n<xs:include schemaLocation="XmlMessage.xsd"/>\n<xs:element name="foo" type="foo" substitutionGroup="body"/>\n<xs:complexType name="foo">\n    <xs:complexContent>\n        <xs:extension base="body">\n            <xs:sequence>\n                <xs:element name="customers" type="customer" minOccurs="1" maxOccurs="unbounded"/>\n            </xs:sequence>\n        </xs:extension>\n    </xs:complexContent>\n</xs:complexType>\n<xs:complexType name="customer">\n    <xs:sequence>\n        <xs:element name="customer_id" type="customerId" nillable="false" minOccurs="1" maxOccurs="1"/>\n        <xs:element name="name" type="xs:string"/>\n        <xs:element name="street" type="xs:string"/>\n        <xs:element name="city" type="xs:string"/>\n        <xs:element name="state" type="xs:string"/>\n        <xs:element name="zip" type="xs:string"/>\n        <xs:element name="phone" type="xs:string"/>\n    </xs:sequence>\n</xs:complexType>\n<xs:complexType name="customerId">\n    <xs:sequence>\n        <xs:element name="id" type="xs:string" minOccurs="1" maxOccurs="1"/>\n    </xs:sequence>\n</xs:complexType>\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n

JAXB 生成的关键 Java 类:

\n\n

信息:

\n\n
package com.samnunnally;\n\nimport javax.xml.bind.JAXBElement;\nimport javax.xml.bind.annotation.XmlAccessType;\nimport javax.xml.bind.annotation.XmlAccessorType;\nimport javax.xml.bind.annotation.XmlElement;\nimport javax.xml.bind.annotation.XmlElementRef;\nimport javax.xml.bind.annotation.XmlRootElement;\nimport javax.xml.bind.annotation.XmlType;\n\n@XmlAccessorType(XmlAccessType.FIELD)\n@XmlType(name = "", propOrder = {\n    "header",\n    "body"\n})\n@XmlRootElement(name = "xmlMessage")\npublic class XmlMessage {\n\n    @XmlElement(required = true)\n    protected Header header;\n    @XmlElementRef(name = "body", namespace = "http://www.samnunnally.com", type = JAXBElement.class)\n    protected JAXBElement<? extends Body> body;\n\n    public Header getHeader() {\n        return header;\n    }\n\n    public void setHeader(Header value) {\n        this.header = value;\n    }\n\n    public JAXBElement<? extends Body> getBody() {\n        return body;\n    }\n\n    public void setBody(JAXBElement<? extends Body> value) {\n        this.body = value;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

身体:

\n\n
package com.samnunnally;\n\nimport javax.xml.bind.annotation.XmlAccessType;\nimport javax.xml.bind.annotation.XmlAccessorType;\nimport javax.xml.bind.annotation.XmlSeeAlso;\nimport javax.xml.bind.annotation.XmlType;\n\n@XmlAccessorType(XmlAccessType.FIELD)\n@XmlType(name = "body")\n@XmlSeeAlso({\nFoo.class\n})\npublic abstract class Body {\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

福消息:

\n\n
package com.samnunnally;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.xml.bind.annotation.XmlAccessType;\nimport javax.xml.bind.annotation.XmlAccessorType;\nimport javax.xml.bind.annotation.XmlElement;\nimport javax.xml.bind.annotation.XmlType;\n\n@XmlAccessorType(XmlAccessType.FIELD)\n@XmlType(name = "foo", propOrder = {\n    "customers"\n})\npublic class Foo\n    extends Body\n{\n\n    @XmlElement(required = true)\n    protected List<Customer> customers;\n\n    public List<Customer> getCustomers() {\n        if (customers == null) {\n            customers = new ArrayList<Customer>();\n        }\n        return this.customers;\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n