WEB SERVICE是个好东西,好就好在它能够解决不同语言之间数据通信的问题。JAXB也是个好东西,它能在JAVA语言中实现XML和OBJECT之间的编组和解组,但是它也带来了麻烦,不能很好的共用先前已经产生的实体类或者普通类。假设我们有如此一个WSDL文件,描述了通过两个操作,通过ID获得一个部门,通过一个部门查询条件获得相应的部门对象列表:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:dept="http://www.example.org/soa/department"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
name="DepartmentWebService"
targetNamespace="http://www.example.org/soa/department">
<wsdl:types>
<xsd:schema
targetNamespace="http://www.example.org/soa/department">
<xsd:element name="getDepart">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="in" type="xsd:int" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="getDepartResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="out" type="dept:DepartType" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="getAllDepart">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="in" type="dept:DepartType"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="getAllDepartResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="out" type="dept:DepartType"
maxOccurs="unbounded" minOccurs="0">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="DepartType">
<xsd:sequence>
<xsd:element name="id" type="xsd:int"></xsd:element>
<xsd:element name="depno" type="xsd:string"></xsd:element>
<xsd:element name="depname" type="xsd:string"></xsd:element>
<xsd:element name="disable" type="xsd:byte"></xsd:element>
<xsd:element name="createdate" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="getDepartRequest">
<wsdl:part element="dept:getDepart" name="parameters" />
</wsdl:message>
<wsdl:message name="getDepartResponse">
<wsdl:part element="dept:getDepartResponse" name="parameters" />
</wsdl:message>
<wsdl:message name="getAllDepartRequest">
<wsdl:part name="parameters" element="dept:getAllDepart"></wsdl:part>
</wsdl:message>
<wsdl:message name="getAllDepartResponse">
<wsdl:part name="parameters"
element="dept:getAllDepartResponse">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="DepartmentWebService">
<wsdl:operation name="getDepart">
<wsdl:input message="dept:getDepartRequest" />
<wsdl:output message="dept:getDepartResponse" />
</wsdl:operation>
<wsdl:operation name="getAllDepart">
<wsdl:input message="dept:getAllDepartRequest"></wsdl:input>
<wsdl:output message="dept:getAllDepartResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DepartmentWebServiceSOAP"
type="dept:DepartmentWebService">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="getDepart">
<soap:operation
soapAction="http://www.example.org/soa/department/NewOperation" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="DepartmentWebService">
<wsdl:port binding="dept:DepartmentWebServiceSOAP"
name="DepartmentWebServiceSOAP">
<soap:address
location="http://www.doubleshow.com/soa/department/" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
在上面的文档中我们定义了一个DepartType的类型,
<xsd:complexType name="DepartType">
<xsd:sequence>
<xsd:element name="id" type="xsd:int"></xsd:element>
<xsd:element name="depno" type="xsd:string"></xsd:element>
<xsd:element name="depname" type="xsd:string"></xsd:element>
<xsd:element name="disable" type="xsd:byte"></xsd:element>
<xsd:element name="createdate" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
映射后产生的类:
package org.example.soa.department;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for DepartType complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="DepartType">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="id" type="{http://www.w3.org/2001/XMLSchema}int"/>
* <element name="depno" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="depname" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="disable" type="{http://www.w3.org/2001/XMLSchema}byte"/>
* <element name="createdate" type="{http://www.w3.org/2001/XMLSchema}string"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "DepartType", propOrder = {
"id",
"depno",
"depname",
"disable",
"createdate"
})
public class DepartType {
protected int id;
@XmlElement(required = true)
protected String depno;
@XmlElement(required = true)
protected String depname;
protected byte disable;
@XmlElement(required = true)
protected String createdate;
/**
* Gets the value of the id property.
*
*/
public int getId() {
return id;
}
/**
* Sets the value of the id property.
*
*/
public void setId(int value) {
this.id = value;
}
/**
* Gets the value of the depno property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getDepno() {
return depno;
}
/**
* Sets the value of the depno property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setDepno(String value) {
this.depno = value;
}
/**
* Gets the value of the depname property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getDepname() {
return depname;
}
/**
* Sets the value of the depname property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setDepname(String value) {
this.depname = value;
}
/**
* Gets the value of the disable property.
*
*/
public byte getDisable() {
return disable;
}
/**
* Sets the value of the disable property.
*
*/
public void setDisable(byte value) {
this.disable = value;
}
/**
* Gets the value of the createdate property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getCreatedate() {
return createdate;
}
/**
* Sets the value of the createdate property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setCreatedate(String value) {
this.createdate = value;
}
}
这个类型的内容是完全和我们在实体类的内容完全相同,但是在文档描述中我们很难用Department去替换他,其一是命名空间的问题,第二Department 是由自动映射工具生成的实体类,它的构造和DepartType文档生成有一定的差异性。
package com.doubleshow.base.resource.mapping;
import javax.xml.bind.annotation.XmlElement;
/**
* Department entity.
*
* @author MyEclipse Persistence Tools
*/
public class Department implements java.io.Serializable {
// Fields
private Integer id;
private String depno;
private String depname;
private Byte disable;
private String createdate;
// Constructors
/** default constructor */
public Department() {
}
/** full constructor */
public Department(String depno, String depname, Byte disable,
String createdate) {
this.depno = depno;
this.depname = depname;
this.disable = disable;
this.createdate = createdate;
}
// Property accessors
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDepno() {
return this.depno;
}
public void setDepno(String depno) {
this.depno = depno;
}
public String getDepname() {
return this.depname;
}
public void setDepname(String depname) {
this.depname = depname;
}
public Byte getDisable() {
return this.disable;
}
public void setDisable(Byte disable) {
this.disable = disable;
}
public String getCreatedate() {
return this.createdate;
}
public void setCreatedate(String createdate) {
this.createdate = createdate;
}
}
现在我们对比这两个JAVA接口,就可以发现有如下几点不同:
1、DepartType 描述了字段内容的顺序,XML中的内容是按照上述propOrder 的顺序生成的,Department是按照字段名称排序生成的
2、DepartType 不能生成任何构造器,而Department有
3、DepartType注明了字段是属于元素还是属性,而Department实体类没有。
有一个相同点那就是字段的属性内容和类型是完全相同的,自然而然我们就会像用Department去替换DepartType 的内容。
根据上面文档生成的web SERVICE接口:
package com.doubleshow.soa.department;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import org.example.soa.department.DepartType;
@WebService(name = "DepartmentWebService", targetNamespace = "http://www.example.org/soa/department")
@SOAPBinding(use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
public interface DepartmentWebService {
@WebMethod(operationName = "getAllDepart", action = "http://www.example.org/soa/department/getAllDepart")
@WebResult(name = "out", targetNamespace = "")
public List<DepartType> getAllDepart(
@WebParam(name = "in", targetNamespace = "http://www.example.org/soa/department")
DepartType in);
@WebMethod(operationName = "getDepart", action = "http://www.example.org/soa/department/getDepart")
@WebResult(name = "out", targetNamespace = "http://www.example.org/soa/department")
public DepartType getDepart(@WebParam(name = "in", targetNamespace = "")
int in);
}
用Department替换DepartType生成后的,当然SERVICE实现类也要进行类似的替换。
package com.doubleshow.soa.department;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import com.doubleshow.base.resource.mapping.Department;
@WebService(name = "DepartmentWebService", targetNamespace = "http://www.example.org/soa/department")
@SOAPBinding(use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
public interface Department WebService {
@WebMethod(operationName = "getAllDepart", action = "http://www.example.org/soa/department/getAllDepart")
@WebResult(name = "out", targetNamespace = "")
public List<Department> getAllDepart(
@WebParam(name = "in", targetNamespace = "http://www.doubleshow.com/base/resource/mapping")
Department in);
@WebMethod(operationName = "getDepart", action = "http://www.example.org/soa/department/getDepart")
@WebResult(name = "out", targetNamespace = "http://www.doubleshow.com/base/resource/mapping")
public Department getDepart(@WebParam(name = "in", targetNamespace = "")
int in);
}
其他的一些参数辅助类也进行类似的替换:
GetAllDepart.java
GetAllDepartReponse.java
GetDepart.java
GetDepartResponse.java
ObjectFactory.java
如此替换之后,就就消除了不同接口之间的转换了,只不过这样做丧失了xml的灵活性,Department会将所有的属性当作元素表示,如果有些内容必须要用属性去表示,上面的替换原则就不适用了。