cxf构建webservice的两种方式

简介: 一、简介   对于基于soap传输协议的webservice有两种开发模式,代码优先和契约优先的模式。代码优先的模式是通过编写服务器端的代码,使用代码生成wsdl;契约优先模式首先编写wsdl,再通过wsdl生成服务器端的代码。

一、简介

  对于基于soap传输协议的webservice有两种开发模式,代码优先和契约优先的模式。代码优先的模式是通过编写服务器端的代码,使用代码生成wsdl;契约优先模式首先编写wsdl,再通过wsdl生成服务器端的代码。对于代码优先的模式在使用cxf构建webservice 一文中已经做出介绍,这里主要介绍第二种方式。

二、wsdl文件结束

  一般wsdl文件结构如下:

<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://testauto.cxf.com/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
    name="MyServiceImplService" targetNamespace="http://testauto.cxf.com/">

    <!-- 元素和元素类型 -->
    <wsdl:types>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:tns="http://testauto.cxf.com/" elementFormDefault="unqualified"
            targetNamespace="http://testauto.cxf.com/" version="1.0">

            <xs:element name="sayHello" type="tns:sayHello" />
            <xs:element name="sayHelloResponse" type="tns:sayHelloResponse" />

            <xs:complexType name="sayHello">
                <xs:sequence>
                    <xs:element minOccurs="0" name="arg0" type="xs:string" />
                    <xs:element minOccurs="0" name="arg1" type="xs:string" />
                    <xs:element minOccurs="0" name="arg2" type="xs:string" />
                </xs:sequence>
            </xs:complexType>

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

        </xs:schema>
    </wsdl:types>
    
    <!-- message -->
    <wsdl:message name="sayHelloResponse">
        <wsdl:part element="tns:sayHelloResponse" name="parameters">
        </wsdl:part>
    </wsdl:message>
    <wsdl:message name="sayHello">
        <wsdl:part element="tns:sayHello" name="parameters">
        </wsdl:part>
    </wsdl:message>
  
    <!-- operation -->  
    <wsdl:portType name="MyService">
        <wsdl:operation name="sayHello">
            <wsdl:input message="tns:sayHello" name="sayHello">
            </wsdl:input>
            <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse">
            </wsdl:output>
        </wsdl:operation>
    </wsdl:portType>
    
    <!-- binding  -->
    <wsdl:binding name="MyServiceImplServiceSoapBinding" type="tns:MyService">
        <soap:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="sayHello">
            <soap:operation soapAction="" style="document" />
            <wsdl:input name="sayHello">
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output name="sayHelloResponse">
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    
    <wsdl:service name="MyServiceImplService">
        <wsdl:port binding="tns:MyServiceImplServiceSoapBinding"
            name="MyServiceImplPort">
            <soap:address location="http://localhost:9000/myservice" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

  对于根元素中的xmlns与targetNamespace是包名的反转,name为实现类的名称。其他的属性都是固定的。

  <wsdl:types> 中主要定义元素和元素的类型。 一般对于一个接口来说,参数的整体作为一个输入元素类型,接口的返回值也是作为一个输出的元素类型。

  <wsdl:message > 主要定义接口的请求和响应消息。<wsdl:part>中的element属性使用到了<wsdl:types> 中定义的元素。

  <wsdl:portType name="MyService"> 主要定义了接口的操作,name表示接口的名称;<wsdl:operation name="sayHello">定义了具体的方法,name为方法的名称。子元素input和output使用到了message元素。

   <wsdl:binding name="MyServiceImplServiceSoapBinding" type="tns:MyService"> type为wsdl:portType中的那么值;name为我们自己定义的。子元素<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />是固定的。 <wsdl:operation name="sayHello">中子元素input和outputname和operation中子元素的name一直。

  <wsdl:service name="MyServiceImplService">定义了绑定的信息,<wsdl:port binding="tns:MyServiceImplServiceSoapBinding">type就是绑定的时候定义的name,子元素address为定义的地址;增加接口的时候不需要更改。

  wsdl是一个基于schema的xml文件,通过这个文件我们可以定义出接口的名称,参数类型,返回值等信息,也可以同该文件生成客户端和服务器端代码。

三、wsdl的各种返回类型

  1、返回列表类型

       对应于 List<Student> getStudentsByAge(int age) 方法,wsdl相关定义如下:

<wsdl:types>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://testauto.cxf.com/" elementFormDefault="unqualified"  targetNamespace="http://testauto.cxf.com/" version="1.0">
        <xsd:element name="getStudentsByAgeRequest" type="tns:AgetType"></xsd:element>
        <xsd:element name="getStudentsByAgeResponse" type="tns:StudentsType"></xsd:element>
    </xs:schema>
</wsdl:types>

<xsd:complexType name="AgetType">
    <xsd:sequence>
        <xsd:element name="age" type="xsd:int"></xsd:element>
    </xsd:sequence>
</xsd:complexType>
                
<xsd:complexType name="StudentsType">
    <xsd:sequence>
        <xsd:element name="students" minOccurs="0" maxOccurs="unbounded" type="tns:StudentType"></xsd:element> <!-- 元素出现的次数为0-无限多次 -->
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="StudentType">
    <xsd:sequence>
        <xsd:element name="id" type="xsd:int"></xsd:element>
        <xsd:element name="name" type="xsd:string"></xsd:element> 
    </xsd:sequence>
</xsd:complexType>

<!-- message -->
<wsdl:message name="getStudentsByAgeRequest">
    <wsdl:part name="parameters" element="tns:getStudentsByAgeRequest"></wsdl:part>
</wsdl:message>
<wsdl:message name="getStudentsByAgeResponse" >
    <wsdl:part name="parameters" element="tns:getStudentsByAgeResponse"></wsdl:part>
</wsdl:message>

<!-- operation -->
<wsdl:portType name="MyService"> 
    <wsdl:operation name="getStudentsByAge">
        <wsdl:input message="tns:getStudentsByAgeRequest" name="getStudentsByAgeRequest"></wsdl:input>
        <wsdl:output message="tns:getStudentsByAgeResponse" name="getStudentsByAgeResponse"></wsdl:output>
    </wsdl:operation> 
</wsdl:portType>


<!-- binding  info  -->
<wsdl:binding name="MyServiceImplServiceSoapBinding" type="tns:MyService"> 
    <wsdl:operation name="getStudentsByAge">
        <soap:operation soapAction="" style="document"/>
        <wsdl:input name="getStudentsByAgeRequest">
            <soap:body use="literal"/>
        </wsdl:input>
        <wsdl:output name="getStudentsByAgeResponse">
            <soap:body use="literal"/>
        </wsdl:output>
    </wsdl:operation> 
</wsdl:binding>

  在MyServiceImplPortImpl中的实现方法,可以做如下类似实现

public com.cxf.test.StudentsType getStudentsByAge(AgetType parameters) { 
        LOG.info("Executing operation getStudentsByAge");
        System.out.println(parameters);
        try {
            System.out.println("getStudentsByAge invoked!");
            System.out.println("gae : " + parameters.getAge());
            com.cxf.test.StudentsType students =  new StudentsType();
            StudentType stu1 = new StudentType();
            stu1.setName("zhangsan1");
            
            StudentType stu2 = new StudentType();
            stu1.setName("zhangsan2");
            
            students.getStudents().add(stu1);
            students.getStudents().add(stu2);
            
            return students;
        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }

  2、voide 无返回值类型

   对应于 void deleteById(int id) 方法,wsdl相关定义如下:

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

        <xsd:element name="deleteByIdRequest" type="tns:IdType"></xsd:element>
        <xsd:element name="deleteByIdResponse">
            <xsd:complexType>
                <xsd:sequence></xsd:sequence>
            </xsd:complexType>
        </xsd:element>
        <xsd:complexType name="IdType">
            <xsd:sequence>
                <xsd:element name="id" type="xsd:int"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>

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

<!-- message -->
<wsdl:message name="deleteByIdRequest">
    <wsdl:part name="parameters" element="tns:deleteByIdRequest"></wsdl:part>
</wsdl:message>
<wsdl:message name="deleteByIdResponse">
    <wsdl:part name="parameters" element="tns:deleteByIdResponse"></wsdl:part>
</wsdl:message>

<!-- operation -->
<wsdl:portType name="MyService">
    <wsdl:operation name="deleteById">
        <wsdl:input message="tns:deleteByIdRequest" name="deleteByIdRequest"></wsdl:input>
        <wsdl:output message="tns:deleteByIdResponse" name="deleteByIdResponse"></wsdl:output>
    </wsdl:operation>
</wsdl:portType>

<!-- binding info -->
<wsdl:binding name="MyServiceImplServiceSoapBinding" type="tns:MyService">
    <wsdl:operation name="deleteById">
        <soap:operation soapAction="" style="document" />
        <wsdl:input name="deleteByIdRequest">
            <soap:body use="literal" />
        </wsdl:input>
        <wsdl:output name="deleteByIdResponse">
            <soap:body use="literal" />
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>

  此时我们可以将生成的deleteById方法的返回类型改成void,需要同时修改接口和实现类。如:
  MyService 接口中的方法

 @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
    @WebResult(name = "deleteByIdResponse", targetNamespace = "http://test.cxf.com/", partName = "parameters")
    @WebMethod
    public void deleteById(
        @WebParam(partName = "parameters", name = "deleteByIdRequest", targetNamespace = "http://test.cxf.com/")
        IdType parameters
    );

  MyServiceImplPortImpl类中的方法

 public void deleteById(IdType parameters) { 
        LOG.info("Executing operation deleteById");
        System.out.println(parameters);
        try {
            
            System.out.println(parameters.getId());
        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }

  3、返回枚举类型

  枚举为:enum{TEACHER, STUDENT, PRESIDENT} ;对应的方法为:enum getRoleById(int id),wsdl定义如下:

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

        <xsd:element name="getRoleByIdRequest" type="tns:IdType"></xsd:element>
        <xsd:element name="getRoleByIdResponse" type="tns:RoleType"></xsd:element>
        <xsd:complexType name="IdType">
            <xsd:sequence>
                <xsd:element name="id" type="xsd:int"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>
        <xsd:simpleType name="RoleType">
            <xsd:restriction base="xs:string">
                <xsd:enumeration value="STUDENT"></xsd:enumeration>
                <xsd:enumeration value="TEACHER"></xsd:enumeration>
                <xsd:enumeration value="PRESIDENT"></xsd:enumeration>
            </xsd:restriction>
        </xsd:simpleType>

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

<!-- message -->
<wsdl:message name="getRoleByIdRequest">
    <wsdl:part name="parameters" element="tns:getRoleByIdRequest"></wsdl:part>
</wsdl:message>
<wsdl:message name="getRoleByIdResponse">
    <wsdl:part name="paramters" element="tns:getRoleByIdResponse"></wsdl:part>
</wsdl:message>

<!-- operation -->
<wsdl:portType name="MyService">
    <wsdl:operation name="getRoleById">
        <wsdl:input message="tns:getRoleByIdRequest" name="getRoleByIdRequest"></wsdl:input>
        <wsdl:output message="tns:getRoleByIdResponse" name="getRoleByIdResponse"></wsdl:output>
    </wsdl:operation>
</wsdl:portType>

<!-- binding info -->
<wsdl:binding name="MyServiceImplServiceSoapBinding" type="tns:MyService">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getRoleById">
        <soap:operation soapAction="" style="document" />
        <wsdl:input name="getRoleByIdRequest">
            <soap:body use="literal" />
        </wsdl:input>
        <wsdl:output name="getRoleByIdResponse">
            <soap:body use="literal" />
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>

  在MyServiceImplPortImpl中的实现方法,可以做如下类似实现

 public com.cxf.test.RoleType getRoleById(IdType parameters) { 
        LOG.info("Executing operation getRoleById");
        System.out.println(parameters);
        try {
            System.out.println("id: " + parameters.getId());
            com.cxf.test.RoleType roleType = RoleType.PRESIDENT;
            return roleType;
        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }

  4、返回嵌套的对象类型

  嵌套对象结构如下

Student{
  int id;
  String name;
  Date date;
  Teacher teacher;
}
Teacher{
  String name;
  Boss boss;
}

Boss{
  String name;
  Parent parent;
}

Parent{
  String name;
}

  对于的方法为:Student getStudentById(int studentId),wsdl文件如下:

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

        <xsd:element name="getStudentByIdRequest" type="tns:StudentIdType"></xsd:element>
        <xsd:element name="getStudentByIdResponse" type="tns:StudentType"></xsd:element>

        <xsd:complexType name="StudentIdType">
            <xsd:sequence>
                <xsd:element name="id" type="xsd:int"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>

        <xsd:complexType name="StudentType">
            <xsd:sequence>
                <xsd:element name="id" type="xsd:int"></xsd:element>
                <xsd:element name="name" type="xsd:string"></xsd:element>
                <xsd:element name="date" type="xsd:date"></xsd:element>
                <xsd:element name="teacher" type="tns:TeacherType"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>

        <xsd:complexType name="TeacherType">
            <xsd:sequence>
                <xsd:element name="name" type="xsd:string"></xsd:element>
                <xsd:element name="boss" type="tns:BossType"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>

        <xsd:complexType name="BossType">
            <xsd:sequence>
                <xsd:element name="name" type="xsd:string"></xsd:element>
                <xsd:element name="parent" type="tns:ParentType"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>

        <xsd:complexType name="ParentType">
            <xsd:sequence>
                <xsd:element name="name" type="xsd:string"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>

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

<!-- message -->
<wsdl:message name="getStudentByIdRequest">
    <wsdl:part name="parameters" element="tns:getStudentByIdRequest"></wsdl:part>
</wsdl:message>
<wsdl:message name="getStudentByIdResponse">
    <wsdl:part name="parameters" element="tns:getStudentByIdResponse"></wsdl:part>
</wsdl:message>

<!-- operation -->
<wsdl:portType name="MyService">
    <wsdl:operation name="getStudentById">
        <wsdl:input message="tns:getStudentByIdRequest" name="getStudentByIdRequest"></wsdl:input>
        <wsdl:output message="tns:getStudentByIdResponse" name="getStudentByIdResponse"></wsdl:output>
    </wsdl:operation>
</wsdl:portType>

<!-- binding info -->
<wsdl:binding name="MyServiceImplServiceSoapBinding" type="tns:MyService">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getStudentById">
        <soap:operation soapAction="" style="document" />
        <wsdl:input name="getStudentByIdRequest">
            <soap:body use="literal" />
        </wsdl:input>
        <wsdl:output name="getStudentByIdResponse">
            <soap:body use="literal" />
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>

  在MyServiceImplPortImpl中的实现方法,可以做如下类似实现

public com.cxf.test.StudentType getStudentById(StudentIdType parameters) { 
        LOG.info("Executing operation getStudentById");
        System.out.println(parameters);
        try {
            ParentType parentType = new ParentType();
            parentType.setName("lisi");
            
            BossType bossType = new BossType();
            bossType.setName("boss");
            bossType.setParent(parentType);
            
            TeacherType teacherType = new TeacherType();
            teacherType.setName("teacher");
            teacherType.setBoss(bossType);
            
            com.cxf.test.StudentType student = new StudentType();
            student.setId(parameters.getId());
            student.setName("zhangsan");
            student.setDate(getGregorianCalendar(new Date()));
            student.setTeacher(teacherType);
            
            return student;
        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }

 private XMLGregorianCalendar getGregorianCalendar(Date date){
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        XMLGregorianCalendar calendar = new com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl(gc);
        return calendar;
    }

  客户端调用的时候

 com.cxf.test.StudentIdType id = new StudentIdType();
 id.setId(11111);
 com.cxf.test.StudentType student = port.getStudentById(id);
 System.out.println(student.getId());
 System.out.println(student.getName());
 System.out.println(student.getDate()); 
 System.out.println(student.getTeacher().getBoss().getParent().getName());

  5、文件上传

   boolean upload(File file ),wsdl文件如下:

<wsdl:types>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:tns="http://test.cxf.com/" elementFormDefault="unqualified"
        targetNamespace="http://test.cxf.com/" version="1.0">
        <xsd:element name="uploadRequest" type="tns:FileType"></xsd:element>
        <xsd:element name="uploadResponse" type="tns:booleanType"></xsd:element>
        <xsd:complexType name="booleanType">
            <xsd:sequence>
                <xsd:element name="result" type="xsd:boolean"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>
        <xsd:complexType name="FileType">
            <xsd:sequence>
                <xsd:element name="fileContent" type="xsd:base64Binary"></xsd:element> <!-- 文件类型 -->
            </xsd:sequence>
        </xsd:complexType>

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

<!-- message -->
<wsdl:message name="uploadRequest">
    <wsdl:part name="parameters" element="tns:uploadRequest"></wsdl:part>
</wsdl:message>
<wsdl:message name="uploadResponse">
    <wsdl:part name="parameters" element="tns:uploadResponse"></wsdl:part>
</wsdl:message>

<!-- operation -->
<wsdl:portType name="MyService">
    <wsdl:operation name="upload">
        <wsdl:input message="tns:uploadRequest" name="uploadRequest"></wsdl:input>
        <wsdl:output message="tns:uploadResponse" name="uploadResponse"></wsdl:output>
    </wsdl:operation>
</wsdl:portType>

<!-- binding info -->
<wsdl:binding name="MyServiceImplServiceSoapBinding" type="tns:MyService">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="upload">
        <soap:operation soapAction="" style="document" />
        <wsdl:input name="uploadRequest">
            <soap:body use="literal" />
        </wsdl:input>
        <wsdl:output name="uploadResponse">
            <soap:body use="literal" />
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>

  接口实现类如下:

 public com.cxf.test.BooleanType upload(FileType parameters) { 
        LOG.info("Executing operation upload");
        System.out.println(parameters);
        try {
            byte[] buffer = parameters.getFileContent();
            OutputStream os = new FileOutputStream(new File("test2.txt"));
            os.write(buffer);
            os.close();
            
            com.cxf.test.BooleanType result = new BooleanType();
            result.setFilename(true);
            return result;
        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }

  客户端调用如下:

 System.out.println("Invoking upload...");
 com.cxf.test.FileType data = new FileType();
 InputStream is = new FileInputStream(new File("c:/apache-cxf-3.0.3.zip"));
 byte[] buffer = new byte[is.available()];
 is.read(buffer);
 data.setFileContent(buffer);
 com.cxf.test.BooleanType result = port.upload(data);
 System.out.println(result.isResult());

  这种上传方式有些缺陷,当文件达到一定大小的时候,就会报java.lang.OutOfMemoryError: Java heap space异常。因为这种方式是一次性读取文件,将文件发送给服务器的。

6、使用MTOM文件上传

  这种方法可以解决普通上传遇到的问题。使用MTO上传需要在wsdl定义元素部分添加 xmlns:xmime="http://www.w3.org/2005/05/xmlmime"

命名空间,element添加属性xmime:expectedContentTypes="application/octet-stream"其他部分与普通上传一样。如下所示:

<wsdl:types>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:tns="http://test.cxf.com/" elementFormDefault="unqualified"
        xmlns:xmime="http://www.w3.org/2005/05/xmlmime" targetNamespace="http://test.cxf.com/"
        version="1.0"> <!--  添加xmlns:xmime 元素 -->

        <xsd:element name="uploadRequest" type="tns:FileType"></xsd:element>
        <xsd:element name="uploadResponse" type="tns:booleanType"></xsd:element>
        <xsd:complexType name="booleanType">
            <xsd:sequence>
                <xsd:element name="result" type="xsd:boolean"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>

        <xsd:complexType name="FileType">
            <xsd:sequence>
                <!-- 添加xmime:expectedContentTypes="application/octet- -->
                <xsd:element name="fileContent" type="xsd:base64Binary"
                    xmime:expectedContentTypes="application/octet-stream"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>

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

  使用MTOM需要服务端和客户端都需要开启MTOM

  服务端开启MTOM代码如下:

 protected MyService_MyServiceImplPort_Server() throws java.lang.Exception {
        System.out.println("Starting Server");
        Object implementor = new MyServiceImplPortImpl();
        String address = "http://localhost:9000/myservice";
        javax.xml.ws.Endpoint endPoint = javax.xml.ws.Endpoint.publish(address, implementor);
        
        //服务器端开启MTOM
        javax.xml.ws.soap.SOAPBinding binding = (javax.xml.ws.soap.SOAPBinding)endPoint.getBinding();
        binding.setMTOMEnabled(true);
    }

  接口的实现

public com.cxf.test.BooleanType upload(FileType parameters) { 
        LOG.info("Executing operation upload");
        System.out.println(parameters);
        try {
            
            javax.activation.DataHandler dataHandler = parameters.getFileContent();

            //获取文件输入流
            InputStream is = dataHandler.getInputStream();
            
            //获取输出流
            OutputStream os = new FileOutputStream(new File("c:/apache-cxf-3.0.3.zip.back"));
            
            //进行文件保存
            int length = 0;
            byte[] buffer = new byte[1024];
            while(-1 != (length = is.read(buffer))){
                os.write(buffer, 0, length);
            }
            
            os.close();
            is.close();
            
            com.cxf.test.BooleanType result = new BooleanType();
            result.setResult(true);
            return result;
        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }

  客户端的调用 

MyService port = ss.getMyServiceImplPort();

// 客户端开启MTOM
javax.xml.ws.Binding binding = ((javax.xml.ws.BindingProvider)
port).getBinding();
((javax.xml.ws.soap.SOAPBinding)
binding).setMTOMEnabled(true);
System.out.println("Invoking upload...");

//构造数据
DataSource ds = new FileDataSource(new File("c:/apache-cxf-3.0.3.zip"));

com.cxf.test.FileType data = new FileType();
data.setFileContent(new DataHandler(ds));

//调用接口
com.cxf.test.BooleanType result = port.upload(data);
System.out.println(result.isResult());

四、使用wsdl生成代码

  将的bin目录添加到系统环境变量path中,如(C:\apache-cxf-3.0.3\bin)。运行cmd,运行如下命令生成代码:

wsdl2java -all -impl -frontend jaxws21 -encoding utf8  c:/myservice.wsdl   #生成java服务器端和客户端代码,并生成实现类。

  表示使用wsdl生成java代码,-all表示同时生成客户端和服务器端代码; -frontend jaxws21表示 表示兼容jaxs 2.1版本;-encoding utf8 表示代码的编码格式为utf8;c:/myservice.wsdl 表示wsdl文件的地址,也可以是一个网络上的地址。其他命令如下:

wsdl2java -server -impl -frontend jaxws21 -encoding utf8  c:/myservice.wsdl   生成java服务器端代码,并生成实现类。
wsdl2java -client -frontend jaxws21 c:/myservice.xml 生成java客户端代码
目录
相关文章
|
5月前
【Azure 应用服务】Web App Service 中的 应用程序配置(Application Setting) 怎么获取key vault中的值
【Azure 应用服务】Web App Service 中的 应用程序配置(Application Setting) 怎么获取key vault中的值
|
2月前
【Azure App Service】PowerShell脚本批量添加IP地址到Web App允许访问IP列表中
Web App取消公网访问后,只允许特定IP能访问Web App。需要写一下段PowerShell脚本,批量添加IP到Web App的允许访问IP列表里!
|
5月前
|
关系型数据库 MySQL Linux
【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App
【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App
【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App
|
5月前
|
Shell PHP Windows
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
|
5月前
|
Linux 应用服务中间件 网络安全
【Azure 应用服务】查看App Service for Linux上部署PHP 7.4 和 8.0时,所使用的WEB服务器是什么?
【Azure 应用服务】查看App Service for Linux上部署PHP 7.4 和 8.0时,所使用的WEB服务器是什么?
|
5月前
【Azure 应用服务】通过 Web.config 开启 dotnet 应用的 stdoutLog 日志,查看App Service 产生500错误的原因
【Azure 应用服务】通过 Web.config 开启 dotnet 应用的 stdoutLog 日志,查看App Service 产生500错误的原因
|
5月前
|
Linux Python
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
|
5月前
|
存储 安全 网络安全
【Azure 环境】使用Azure中的App Service部署Web应用,以Windows为主机系统是否可以启动防病毒,防恶意软件服务呢(Microsoft Antimalware)?
【Azure 环境】使用Azure中的App Service部署Web应用,以Windows为主机系统是否可以启动防病毒,防恶意软件服务呢(Microsoft Antimalware)?
|
5月前
|
存储 Linux 网络安全
【Azure 应用服务】App Service For Linux 如何在 Web 应用实例上住抓取网络日志
【Azure 应用服务】App Service For Linux 如何在 Web 应用实例上住抓取网络日志
|
5月前
【Azure 云服务】Azure Cloud Service 为 Web Role(IIS Host)增加自定义字段 (把HTTP Request Header中的User-Agent字段增加到IIS输出日志中)
【Azure 云服务】Azure Cloud Service 为 Web Role(IIS Host)增加自定义字段 (把HTTP Request Header中的User-Agent字段增加到IIS输出日志中)
下一篇
开通oss服务