WebService實戰

zxc123e發表於2015-07-26

wsld中幾種資料型別的處理

我們通過wsld來生成的java程式碼,都會把引數和返回值包裝成一個類。

1)wsdl2java命令

這裡寫圖片描述

2) 引數類中物件作為屬性

在返回的引數類中,我們加上一個成員變數address,address為Address類的一個例項。我們看看wsld檔案中wsdl:type標籤中的表述。

<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://test.chm.com/" elementFormDefault="unqualified" targetNamespace="http://test.chm.com/" version="1.0">

  <xs:element name="parameterName" type="tns:paramType"/>

  <xs:element name="resultName" type="tns:resultType"/>

  <xs:complexType name="paramType">
    <xs:sequence>
      <xs:element minOccurs="0" name="name" type="xs:string"/>
      <xsd:element name="address" type="tns:address"></xsd:element><!-- 關鍵點-->
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="resultType">
    <xs:sequence>
      <xs:element minOccurs="0" name="helloResult" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xsd:complexType name="address">
    <xsd:sequence>
        <xsd:element name="shoolAddress" type="xsd:string"></xsd:element>
        <xsd:element name="homeAddress" type="xsd:string"></xsd:element>
    </xsd:sequence>
  </xsd:complexType>
</xs:schema>
</wsdl:types>

再看看引數類

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "paramType", propOrder = {
    "name",
    "address"
})
public class ParamType {

    protected String name;
    @XmlElement(required = true)
    protected Address address;

    public String getName() {
        return name;
    }

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

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address value) {
        this.address = value;
    }
}

3) 返回值類中集合作為引數

我們看一下wsld中關鍵部分

  <wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://test.chm.com/" elementFormDefault="unqualified" targetNamespace="http://test.chm.com/" version="1.0">

  <xs:element name="parameterName" type="tns:paramType"/>

  <xs:element name="resultName" type="tns:resultType"/>

  <xs:complexType name="paramType">
    <xs:sequence>
      <xs:element minOccurs="0" name="name" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="resultType">
    <xs:sequence>
      <xs:element minOccurs="0" name="helloResult" type="xs:string"/>
      <xsd:element name="addrList" type="tns:addr" minOccurs="0" maxOccurs="unbounded"></xsd:element>
    </xs:sequence> <!-- 關鍵點 -->
  </xs:complexType>

  <xsd:complexType name="addr">
    <xsd:sequence>
        <xsd:element name="shoolAddress" type="xsd:string"></xsd:element>
        <xsd:element name="homeAddress" type="xsd:string"></xsd:element>
    </xsd:sequence>
  </xsd:complexType>


</xs:schema>
  </wsdl:types>

對應生成的返回類

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "resultType", propOrder = {
    "helloResult",
    "addrList"
})
public class ResultType {

    protected String helloResult;
    protected List<Addr> addrList;

    public String getHelloResult() {
        return helloResult;
    }

    public void setHelloResult(String value) {
        this.helloResult = value;
    }

    public List<Addr> getAddrList() {
        if (addrList == null) {
            addrList = new ArrayList<Addr>();
        }
        return this.addrList;
    }
}

4) 引數類中列舉型別的屬性

我們看一下wsld中關鍵程式碼部分

<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://test.chm.com/" elementFormDefault="unqualified" targetNamespace="http://test.chm.com/" version="1.0">

  <xs:element name="parameterName" type="tns:paramType"/>

  <xs:element name="resultName" type="tns:resultType"/>

  <xs:complexType name="paramType">
    <xs:sequence>
      <xs:element minOccurs="0" name="name" type="xs:string"/>
      <xsd:element name="grade"  type="tns:grade"></xsd:element> <!-- 一個列舉型別的成員變數 -->
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="resultType">
    <xs:sequence>
      <xs:element minOccurs="0" name="helloResult" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

 <xsd:simpleType name="grade"> <!-- 宣告列舉型別 -->
    <xsd:restriction base="xsd:string">
        <xsd:enumeration value="excellent"></xsd:enumeration>
        <xsd:enumeration value="medium"></xsd:enumeration>
        <xsd:enumeration value="pass"></xsd:enumeration>
    </xsd:restriction>
 </xsd:simpleType>

</xs:schema>
</wsdl:types>

5) 返回值為空

wsld中空型別的表示

<xsd:complexType>
    <xsd:sequence/>
</xsd:complexType>

6)檔案上傳

在wsld中如何表示一個檔案的上傳?用位元組陣列,然後就是IO的操作了

  <xs:complexType name="paramType">
    <xs:sequence>
      <xs:element minOccurs="0" name="name" type="xs:string"/>
      <xsd:element name="file" type="xsd:base64Binary"></xsd:element> <!-- 關鍵點 -->
    </xs:sequence>
  </xs:complexType>

對應生成的java程式碼

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "paramType", propOrder = {
    "name",
    "file"
})
public class ParamType {

    protected String name;
    @XmlElement(required = true)
    protected byte[] file;
    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }
    public byte[] getFile() {
        return file;
    }
    public void setFile(byte[] value) {
        this.file = value;
    }

}

對於小檔案這樣傳輸是沒問題,但是對於大的檔案(幾兆以上吧)就可能報記憶體溢位的錯誤了,那麼我們需要使用另一種方法,Using MTOM(SOAP Message Transmission Optimization Mechanism ),可到連線這個地址檢視

<xs:complexType name="paramType">
    <xs:sequence>
        <xs:element minOccurs="0" name="name" type="xs:string"/>
        <xsd:element name="file" type="xsd:base64Binary" xmime:expectedContentTypes="application/octet-stream"/> <!-- -->
    </xs:sequence>
</xs:complexType>
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "paramType", propOrder = {
    "name",
    "file"
})
public class ParamType {

    protected String name;
    @XmlElement(required = true)
    @XmlMimeType("application/octet-stream")
    protected DataHandler file;

    public String getName() {
        return name;
    }

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

    public DataHandler getFile() {
        return file;
    }

    public void setFile(DataHandler value) {
        this.file = value;
    }

}

cxf預設情況下沒有開啟對MTOM的支援,我們需要同時在客戶端和服務端開啟對MTOM的支援。

客戶端

StudentService ss = new StudentService(wsdlURL, SERVICE_NAME);
        People port = ss.getStudentPort();  
        SOAPBinding binding = (SOAPBinding) ((BindingProvider)port).getBinding();
        binding.setMTOMEnabled(true);

        System.out.println("Invoking sayGood...");
        com.chm.test.ParamType parameters = new ParamType();
        DataSource dataSource = new FileDataSource(new File("D:/test.xls"));
        parameters.setFile(new DataHandler(dataSource));
        parameters.setName("aa");
        port.sayGood(parameters);

服務端

Object implementor = new StudentPortImpl();
        String address = "http://localhost:8080/myservice3";
        Endpoint ep = Endpoint.publish(address, implementor);
        SOAPBinding binding = (SOAPBinding)ep.getBinding();
        binding.setMTOMEnabled(true);

cxf與spring整合

web.xml

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:jaxws="http://cxf.apache.org/jaxws" <!-- 增加名稱空間 -->
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://cxf.apache.org/jaxws 
                        http://cxf.apache.org/schemas/jaxws.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <!--<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>-->
    <!--<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>-->
    <jaxws:endpoint id="myservice" implementor="com.chm.test.MyServiceImpl" address="/myserver"></jaxws:endpoint>

</beans>

客戶端

<jaxws:client id="service" address="http://localhost:8080/myserver" serviceClass="com.chm.test.MyService"></jaxws:client>

相關文章