寻找一种方法来定义一个基本 XML 模式,以便在其他模式上重新使用,作为将用于不同 JMS 消息有效负载的 XML 消息。目的是:
- XmlMessage - 定义一个基本消息类,所有消息都将作为该类发送。
- header - 所有消息都将包含的类,其中包含有关消息的元数据
- 主体 - 每个特定消息实现可用于定义每个单独消息的消息负载的抽象类
这种方法将:
- 允许 JMS EJB 将传入的 XML 解码为高级通用 XmlMessage,然后能够评估 Body 实现的类类型以确定如何处理消息。
- 标准化各种消息格式。
- 利用 JAXB 生成要在发送消息的客户端和处理消息的 EJB 上使用的 Java 类。
- 利用 JAXB 编码/解码消息负载中的 XML。
最佳答案
请参阅以下 XSD 模式和 JAXB 实现来完成为消息正文定义抽象类
XmlMessage.xsd 定义所有消息的格式:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.samnunnally.com" targetNamespace="http://www.samnunnally.com" version="1.0">
<xs:element name="xmlMessage">
<xs:complexType>
<xs:sequence>
<xs:element name="header" type="header" minOccurs="1" maxOccurs="1"/>
<xs:element ref="body"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="header">
<xs:sequence>
<xs:element name="message_class" type="xs:string"/>
<xs:element name="message_id" type="xs:int"/>
<xs:element name="message_length" type="xs:int"/>
<xs:element name="software_version" type="xs:string"/>
<xs:element name="correlation_id" type="xs:string"/>
<xs:element name="session_id" type="xs:string"/>
<xs:element name="return_code" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="body" type="body"/>
<xs:complexType name="body" abstract="true">
<xs:sequence/>
</xs:complexType>
实现 XmlMessage.xsd 的示例 xsd。最终成为包含客户列表的消息 Foo。关键是使用 substitutionGroup 属性和 xs:extension base="body"
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.samnunnally.com"
targetNamespace="http://www.samnunnally.com"
version="1.0">
<xs:include schemaLocation="XmlMessage.xsd"/>
<xs:element name="foo" type="foo" substitutionGroup="body"/>
<xs:complexType name="foo">
<xs:complexContent>
<xs:extension base="body">
<xs:sequence>
<xs:element name="customers" type="customer" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="customer">
<xs:sequence>
<xs:element name="customer_id" type="customerId" nillable="false" minOccurs="1" maxOccurs="1"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="street" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="state" type="xs:string"/>
<xs:element name="zip" type="xs:string"/>
<xs:element name="phone" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="customerId">
<xs:sequence>
<xs:element name="id" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
JAXB 生成的关键 Java 类:
留言:
package com.samnunnally;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"header",
"body"
})
@XmlRootElement(name = "xmlMessage")
public class XmlMessage {
@XmlElement(required = true)
protected Header header;
@XmlElementRef(name = "body", namespace = "http://www.samnunnally.com", type = JAXBElement.class)
protected JAXBElement<? extends Body> body;
public Header getHeader() {
return header;
}
public void setHeader(Header value) {
this.header = value;
}
public JAXBElement<? extends Body> getBody() {
return body;
}
public void setBody(JAXBElement<? extends Body> value) {
this.body = value;
}
}
正文:
package com.samnunnally;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "body")
@XmlSeeAlso({
Foo.class
})
public abstract class Body {
}
Foo 消息:
package com.samnunnally;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "foo", propOrder = {
"customers"
})
public class Foo
extends Body
{
@XmlElement(required = true)
protected List<Customer> customers;
public List<Customer> getCustomers() {
if (customers == null) {
customers = new ArrayList<Customer>();
}
return this.customers;
}
}
关于java - 如何使用XML/XSD定义JAXB抽象类并实现继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20169251/