WebService实战

wsld中几种数据类型的处理

我们通过wsld来生成java代码,都会把参数和返回值包装成一个类。

1) 参数类中对象作为属性

在返回的参数类中,我们加上一个成员变量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;
    }
}

2) 返回值类中集合作为参数

我们看一下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;
    }
}

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"/>
      <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>

4) 返回值为空

wsld中空类型的表示

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

5)文件上传

在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>

你可能感兴趣的:(WebService实战)