Apache CXF开发Web Service 理解CXF Frontends之Contract-First

Apache CXF开发Web Service 理解CXF FrontendsCode-First》一文提到Code-FirstContract-First两种不同的方式,这里将介绍Contract-First的使用。如果使用Contract-First的开发方式,开发者首先准备好WSDL文档,通过CXF提供的工具wsdl2java来生成代码。这个工具在%CXF-HOME%/bin目录中。Contract-First需要完成的工作有:

 

生成服务组件

实现服务方法

发布Web Service

开发客户端

 

使用《Apache CXF开发Web Service 理解CXF FrontendsCode-First》中生成的WSDL文档,即启动mvn test –Pserve后,访问http://localhost:8080/OrderProcess?wsdl所看到的内容。现在是要把操作倒过去,通过这个WSDL来生成SEI

 

xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions name="OrderProcessService" targetNamespace="http://order.demo/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://order.demo/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <wsdl:types>

       <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://order.demo/" xmlns:tns="http://order.demo/" xmlns:xs="http://www.w3.org/2001/XMLSchema">

           <xs:element name="processOrder" type="tns:processOrder" />

           <xs:element name="processOrderResponse" type="tns:processOrderResponse" />

           <xs:complexType name="processOrder">

              <xs:sequence>

                  <xs:element minOccurs="0" name="arg0" type="tns:order" />

              xs:sequence>

           xs:complexType>

           <xs:complexType name="order">

              <xs:sequence>

                  <xs:element minOccurs="0" name="customerID" type="xs:string" />

                  <xs:element minOccurs="0" name="itemID" type="xs:string" />

                  <xs:element name="price" type="xs:double" />

                  <xs:element name="qty" type="xs:int" />

              xs:sequence>

           xs:complexType>

           <xs:complexType name="processOrderResponse">

              <xs:sequence>

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

              xs:sequence>

           xs:complexType>

       xs:schema>

    wsdl:types>

    <wsdl:message name="processOrderResponse">

       <wsdl:part element="tns:processOrderResponse" name="parameters">

       wsdl:part>

    wsdl:message>

    <wsdl:message name="processOrder">

       <wsdl:part element="tns:processOrder" name="parameters">

       wsdl:part>

    wsdl:message>

    <wsdl:portType name="OrderProcess">

       <wsdl:operation name="processOrder">

           <wsdl:input message="tns:processOrder" name="processOrder">

           wsdl:input>

           <wsdl:output message="tns:processOrderResponse" name="processOrderResponse">

           wsdl:output>

       wsdl:operation>

    wsdl:portType>

    <wsdl:binding name="OrderProcessServiceSoapBinding" type="tns:OrderProcess">

       <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />

       <wsdl:operation name="processOrder">

           <soap:operation soapAction="" style="document" />

           <wsdl:input name="processOrder">

              <soap:body use="literal" />

           wsdl:input>

           <wsdl:output name="processOrderResponse">

              <soap:body use="literal" />

           wsdl:output>

       wsdl:operation>

    wsdl:binding>

    <wsdl:service name="OrderProcessService">

       <wsdl:port binding="tns:OrderProcessServiceSoapBinding" name="OrderProcessPort">

           <soap:address location="http://localhost:8080/OrderProcess" />

       wsdl:port>

    wsdl:service>

wsdl:definitions>

 

 

 

生成服务组件

 

将准备好的WSDL文档命名为OrderProcess.wsdl。文档的内容与使用JAX-WS规范的JAVA组件对应。

 

WSDL element

Java component

targetNamespace attribute of the   element

targetNamespace="http://order.demo/"

Java packagedemo.order

<wsdl:portType name="OrderProcess">

Java Service Endpoint Interface (SEI)

OrderProcess

child element of the  element

<wsdl:operation name="processOrder">

Java methods

processOrder

<wsdl:service name="OrderProcessService">

Service class

OrderProcessService

Service operation parameters

 

关于wsdl2java工具的使用请参考:

http://cxf.apache.org/docs/wsdl-to-java.html

http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html

 

这里将介绍Maven 的插件 cxf-codegen-plugin 来生成代码的方式。Apache CXF开发Web Service 理解CXF FrontendsCode-First》文中提到的pom.xml添加cxf-codegen-plugin

 

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0modelVersion>

 

    <groupId>org.dcb.cxfbook.ch03groupId>

    <artifactId>contractfirstartifactId>

    <version>1.0version>

    <packaging>jarpackaging>

 

    <name>contractfirstname>

    <url>http://maven.apache.orgurl>

 

    <properties>

        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>

        <cxf.version>2.2.3cxf.version>

    properties>

 

    <dependencies>

        <dependency>

            <groupId>junitgroupId>

            <artifactId>junitartifactId>

            <version>3.8.1version>

            <scope>testscope>

        dependency>

        <dependency>

            <groupId>org.apache.cxfgroupId>

            <artifactId>cxf-rt-frontend-jaxwsartifactId>

            <version>${cxf.version}version>

        dependency>

        <dependency>

            <groupId>org.apache.cxfgroupId>

            <artifactId>cxf-rt-transports-httpartifactId>

            <version>${cxf.version}version>

        dependency>

        <dependency>

            <groupId>org.apache.cxfgroupId>

            <artifactId>cxf-rt-transports-http-jettyartifactId>

            <version>${cxf.version}version>

        dependency>

    dependencies>

   

    <build>

        <finalName>contractfirstfinalName>

        <plugins>

            <plugin>

                <artifactId>maven-compiler-pluginartifactId>

                <configuration>

                    <source>1.5source>

                    <target>1.5target>

                configuration>

            plugin>

            <plugin>

                <groupId>org.apache.cxfgroupId>

                <artifactId>cxf-codegen-pluginartifactId>

                <version>${cxf.version}version>

                <executions>

                    <execution>

                        <id>generate-sourcesid>

                        <phase>generate-sourcesphase>

                        <configuration>

                            <wsdlOptions>

                                <wsdlOption>

                                    <wsdl>src/main/resources/OrderProcess.wsdlwsdl>

                                wsdlOption>

                            wsdlOptions>

                        configuration>

                        <goals>

                            <goal>wsdl2javagoal>

                        goals>

                    execution>

                executions>

            plugin>

        plugins>

    build>

   

    <profiles>

        <profile>

            <id>serverid>

            <build>

                <defaultGoal>testdefaultGoal>

                <plugins>

                    <plugin>

                        <groupId>org.codehaus.mojogroupId>

                        <artifactId>exec-maven-pluginartifactId>

                        <executions>

                            <execution>

                                <phase>testphase>

                                <goals>

                                    <goal>javagoal>

                                goals>

                                <configuration>

                                    <mainClass>demo.order.OrderProcessServermainClass>

                                configuration>

                            execution>

                        executions>

                    plugin>

                plugins>

            build>

        profile>

        <profile>

            <id>clientid>

            <build>

                <defaultGoal>testdefaultGoal>

                <plugins>

                    <plugin>

                        <groupId>org.codehaus.mojogroupId>

                        <artifactId>exec-maven-pluginartifactId>

                        <executions>

                            <execution>

                                <phase>testphase>

                                <goals>

                                    <goal>javagoal>

                                goals>

                                <configuration>

                                    <mainClass>demo.order.client.ClientmainClass>

                                configuration>

                            execution>

                        executions>

                    plugin>

                plugins>

            build>

        profile>

    profiles>

project>

 

 

执行命令:

 

cd contractfirst

mvn generate-sources

 

Maven cxf-codegen-plugin会为你自动调用CXF wsdl2java工具。可能初学Maven的朋友不大理解,这里简单介绍cxf-codegen-plugin的使用。在build.plugins.plugin中添加cxf-codegen-plugin<wsdl>src/main/resources/OrderProcess.wsdlwsdl>指明要转换的WSDL文档。<phase>generate-sourcesphase>指明执行的命令。<goal>wsdl2javagoal>指明执行命令所包含的工作。

 

对于GoalPhase的关系,在《Maven中的几个重要概念()lifecycle, phase and goal》一文中有详细的介绍。这里摘选GoalPhase的内容:

 

Maven定义了一系列Best Practice,将关联的Phase组合在一起,即执行一个phase会执行某个liefcycle所有的phaseGoal是独立的,可以绑定到多个phase中,也可以不绑定。从这方面讲,phase就是goal的容器,实际被执行的是goal

 

在本文中执行generate-sources这个phase,其实是执行cxf-codegen-plugin中的<goal>wsdl2javagoal>

 

对于Maven的生命周期,请看《Maven生命周期详解》。

 

跑题了半天,让我们看看这mvn generate-sources到底生成了什么内容:

JAXB输入/输出消息类。wsdl2java类会分别生成JAVA输入/输出消息组件。本例中将会生成ProcessOrder作为输入类,生成ProcessOrderResponse作为输出类,还会根据<xs:complexType name="order">生成Order类。

服务接口。本例中服务接口为OrderProcess

服务实现类。本例中提供了继承自Service接口的实现类OrderProcessService。我们可以修改这个类来实现功能。

 

这些类都在包demo.order中。wsdl2java工具从targetNamespace="http://order.demo/"生成包名,也就是http://order.demo/除去http://后倒写。

 

如果修改pom.xml,添加如下内容,将会生成OrderProcessImpl.java(示例的实现服务类)和OrderProcess_OrderProcessPort_Server.javaCXF提供的独立的服务器)。

                            <wsdlOption>

                                <wsdl>src/main/resources/OrderProcess.wsdlwsdl>

                                <extraargs>

                                   <extraarg>-serverextraarg>

                                   <extraarg>-implextraarg>

                                   <extraarg>-verboseextraarg>

                                extraargs>

                            wsdlOption>

 

 

 

JAXB 输入/输出消息类

 

ProcessOrder, ProcessOrderResponseOrder这三个类代表Web Service操作类。这几个类有着各种JAXB注解。ProcessOrder ProcessOrderResponse用来表示RequestResponseRequest拥有出入参数引用,而Response着拥有输出参数引用。

 

为了理解RequestResponse的概念,来看看Web Service将会提交什么样的SOAP Request消息。

 

      processOrder xmlns:ns2="http://order.demo/">

         <arg0>

            C001

            I001

            200.0

            100

         arg0>

     

 

processOrder映射为Web Service中的方法processOrder。子元素arg0代表着SOAP payload,映射为输入参数OrderCXF会自动将arg0转换为Order对象,并执行processOrder方法。

 

 

 

服务接口

 

OrderProcessSEI,定义了processOrder方法。

 

@WebService(targetNamespace = "http://order.demo/", name = "OrderProcess")

@XmlSeeAlso({ObjectFactory.class})

public interface OrderProcess {

 

    @WebResult(name = "return", targetNamespace = "")

    @RequestWrapper(localName = "processOrder", targetNamespace = "http://order.demo/", className = "demo.order.ProcessOrder")

    @ResponseWrapper(localName = "processOrderResponse", targetNamespace = "http://order.demo/", className = "demo.order.ProcessOrderResponse")

    @WebMethod

    public java.lang.String processOrder(

        @WebParam(name = "arg0", targetNamespace = "")

        demo.order.Order arg0

    );

}

 

@WebService定义了这个接口是SEI

@Xml SeeAlso通知JAXB在执行数据绑定是包含ObjectFactory

@RequestWrapper包含了输入消息。

@ResponseWrapper包含了输出消息。

@WebResult指明返回的类型。

@WebMethod指明这是个服务方法。

@WebParam指明参数。

 

 

 

运行Web Service

 

Apache CXF开发Web Service 理解CXF FrontendsCode-First》一文执行过程类似。

 

cd contractfirst

#启动server,显示Server ready...消息

mvn test –Pserver

#执行client,显示The order ID is ORD1234

mvn test -Pclient

 

 

 

参考内容

 

Maven中的几个重要概念()lifecycle, phase and goal

Maven生命周期详解

http://cxf.apache.org/docs/wsdl-to-java.html

http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html

http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

你可能感兴趣的:(CXF)