• Jax-WS WebService实现


    注:(转载地址:http://elim.iteye.com/blog/1985995

    目录

    1       定义Service

    2       服务端发布Service

    2.1      排除WebService中的某个方法

    3       客户端访问Service

    4       java2ws工具的使用

    4.1      命令行使用java2ws

    4.2      Maven使用java2ws

    5       基于Spring的Jax-ws WebService

    5.1      Service定义

    5.2      服务端发布Service

    5.3      客户端获取Service

    6       WSDL生成Java代码

    6.1      wsdl2java工具

    6.2      cxf-codegen-plugin

           Jax-ws是WebService的一种规范。

    1       定义Service

           Jax-ws的WebService定义是通过注解进行的,我们必须在其WebService类的接口上使用@WebService注解进行标记。

    Java代码  
    1. @WebService  
    2. public interface HelloWorld {  
    3.    
    4.    public String sayHi(String who);  
    5.      
    6. }  

           如上,我们把HelloWorld定义为一个WebService,其对应有一个sayHi操作。其对应的实现类如下:

    Java代码  
    1. public class HelloWorldImpl implements HelloWorld {  
    2.    
    3.    @Override  
    4.    public String sayHi(String who) {  
    5.       return"Hi, " + who;  
    6.    }  
    7.    
    8. }  

    2       服务端发布Service

           对于Jax-ws WebService而言,发布Service有两种方式。

    第一种:

    Java代码  
    1. public class Server {  
    2.    
    3.    private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";  
    4.      
    5.    public static void main(String args[]) {  
    6.       HelloWorld hw = new HelloWorldImpl();  
    7.       Endpoint.publish(ADDRESS, hw);  
    8.    }  
    9.      
    10. }  

    第二种:

    Java代码  
    1. public class Server {  
    2.    
    3.    private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";  
    4.      
    5.    public static void main(String args[]) {  
    6.       HelloWorld hw = new HelloWorldImpl();  
    7.       JaxWsServerFactoryBean jwsFactory = new JaxWsServerFactoryBean();  
    8.       jwsFactory.setAddress(ADDRESS);   //指定WebService的发布地址  
    9.       jwsFactory.setServiceClass(HelloWorld.class);//WebService对应的类型  
    10.       jwsFactory.setServiceBean(hw);//WebService对应的实现对象  
    11.       jwsFactory.create();  
    12.    }  
    13.      
    14. }  

           发布之后我们就可以通过发布地址?wsdl查看WebService的定义了(WSDL是Web Service Description Language的简称,即网络服务描述语言)。通过在浏览器输入http://localhost:8080/test/jaxws/services/HelloWorld?wsdl我们可以看到如下内容:

    Xml代码  
    1. This XML file does not appear to have any style information associated  
    2. with it. The document tree is shown below.  
    3. <wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
    4.     xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://jaxws.sample.cxftest.tiantian.com/"  
    5.     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http"  
    6.     name="HelloWorldImplService" targetNamespace="http://jaxws.sample.cxftest.tiantian.com/">  
    7.     <wsdl:types>  
    8.         <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  
    9.             xmlns:tns="http://jaxws.sample.cxftest.tiantian.com/"  
    10.             elementFormDefault="unqualified" targetNamespace="http://jaxws.sample.cxftest.tiantian.com/"  
    11.             version="1.0">  
    12.             <xs:element name="sayHi" type="tns:sayHi" />  
    13.             <xs:element name="sayHiResponse" type="tns:sayHiResponse" />  
    14.             <xs:complexType name="sayHi">  
    15.                 <xs:sequence>  
    16.                     <xs:element minOccurs="0" name="arg0" type="xs:string" />  
    17.                 </xs:sequence>  
    18.             </xs:complexType>  
    19.             <xs:complexType name="sayHiResponse">  
    20.                 <xs:sequence>  
    21.                     <xs:element minOccurs="0" name="return" type="xs:string" />  
    22.                 </xs:sequence>  
    23.             </xs:complexType>  
    24.         </xs:schema>  
    25.     </wsdl:types>  
    26.     <wsdl:message name="sayHiResponse">  
    27.         <wsdl:part element="tns:sayHiResponse" name="parameters"></wsdl:part>  
    28.     </wsdl:message>  
    29.     <wsdl:message name="sayHi">  
    30.         <wsdl:part element="tns:sayHi" name="parameters"></wsdl:part>  
    31.     </wsdl:message>  
    32.     <wsdl:portType name="HelloWorld">  
    33.         <wsdl:operation name="sayHi">  
    34.             <wsdl:input message="tns:sayHi" name="sayHi"></wsdl:input>  
    35.             <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"></wsdl:output>  
    36.         </wsdl:operation>  
    37.     </wsdl:portType>  
    38.     <wsdl:binding name="HelloWorldImplServiceSoapBinding"  
    39.         type="tns:HelloWorld">  
    40.         <soap:binding style="document"  
    41.             transport="http://schemas.xmlsoap.org/soap/http" />  
    42.         <wsdl:operation name="sayHi">  
    43.             <soap:operation soapAction="" style="document" />  
    44.             <wsdl:input name="sayHi">  
    45.                 <soap:body use="literal" />  
    46.             </wsdl:input>  
    47.             <wsdl:output name="sayHiResponse">  
    48.                 <soap:body use="literal" />  
    49.             </wsdl:output>  
    50.         </wsdl:operation>  
    51.     </wsdl:binding>  
    52.     <wsdl:service name="HelloWorldImplService">  
    53.         <wsdl:port binding="tns:HelloWorldImplServiceSoapBinding"  
    54.             name="HelloWorldImplPort">  
    55.             <soap:address location="http://localhost:8080/test/jaxws/services/HelloWorld" />  
    56.         </wsdl:port>  
    57.     </wsdl:service>  
    58. </wsdl:definitions>  

           我们可以看到在上面我们的sayHi操作的参数who变成了arg0,这是因为接口在被编译为class文件的时候不能保存参数名,有时候这会影响可读性。如果需要参数名显示的可读性强一些的话,我们可以使用@WebParam来指定,如:

    Java代码  
    1. @WebService(serviceName="!@#$%^", name="123456")  
    2. public interface HelloWorld {  
    3.    
    4.    public String sayHi(@WebParam(name="who") String who);  
    5.      
    6. }  

       

    @WebService的serviceName可以用来指定service的名称,默认情况下如果Service是通过Endpoint.publish()方法发布的则serviceName为实现类的简单名称+Service(如HelloWorldImplService),如果是通过JaxWsServerFactoryBean的create方法发布的则为接口的简单名称+Service(如HelloWorldService)。name属性可以用来指定service对应的portName,默认情况下如果Service是通过Endpoint.publish()方法发布的则portName为实现类的简单名称+Port(如HelloWorldImplPort),如果是通过JaxWsServerFactoryBean的create方法发布的则为接口的简单名称+Port(如HelloWorldPort)。

           除了@WebService、@WebParam之外,Jax-ws还为我们提供了一系列的注解,如@WebMethod、@OneWay。

           @WebMethod是用来标注在WebService的方法即操作上的,通过它我们可以指定某一个操作的操作名、使用SOAP绑定时的Action名称,以及该方法是否允许发布为WebService。@WebMethod有三个属性:operationName、action和exclude。@WebMethod还是挺有用的,当你发布的WebService中有方法不希望WebService访问的时候就可以通过@WebMethod来指定将其排除在外。下面我们来介绍一下使用WebMethod排除WebService中的一个方法。

           @Oneway是标注在Service接口的操作方法上的。使用@Oneway标注的方法表示它不需要等待服务端的返回,也不需要预留资源来处理服务端的返回。

    2.1     排除WebService中的某个方法

           首先我们往我们的HelloWorld接口中新增一个方法sayHello。

    Java代码  
    1. @WebService  
    2. public interface HelloWorld {  
    3.    
    4.    public String sayHi(@WebParam(name="who") String who);  
    5.      
    6.    public String sayHello(@WebParam(name="who") String who);  
    7.      
    8. }  

           对于有接口的WebService而言,@WebMethod的exclude定义必须指定在其实现类对应的需要排除的方法上,而其他属性则必须在接口方法上定义。所以我们的实现类定义如下:

    Java代码  
    1. public class HelloWorldImpl implements HelloWorld {  
    2.    
    3.    @Override  
    4.    public String sayHi(String who) {  
    5.       return"Hi, " + who;  
    6.    }  
    7.      
    8.    @Override  
    9.    @WebMethod(exclude=true)  
    10.    public String sayHello(String who) {  
    11.       return"Hello, " + who;  
    12.    }  
    13.    
    14. }  

           这样,在服务发布时就会把sayHello方法排除在外。有兴趣的朋友可以通过查看指定exclude前后的wsdl文件验证一下sayHello方法是否在exclude为true时被排除了。客户端在访问sayHello方法的时候也是不会成功的。

    3       客户端访问Service

    类似于WebService简单实现里面的ClientProxyFactoryBean,在使用Jax-ws时我们可以通过JaxWsProxyFactoryBean来访问服务,如:

    Java代码  
    1. public class Client {  
    2.    
    3.    private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";  
    4.      
    5.    public static void main(String args[]) {  
    6.       JaxWsProxyFactoryBean jwpFactory = new JaxWsProxyFactoryBean();  
    7.       jwpFactory.setAddress(ADDRESS);  
    8.       jwpFactory.setServiceClass(HelloWorld.class);  
    9.       HelloWorld hw = (HelloWorld)jwpFactory.create();  
    10.       String response = hw.sayHi("world");  
    11.       System.out.println(response);  
    12.    }  
    13.      
    14. }  

       

    除了上面的方式之外,我们还可以这样获取Service:

    Java代码  
    1. //第一个参数为服务发布的targetNameSpace,可以通过查看对应的wsdl文件获得,默认是发布Service所在包的包名倒过来的形式;第二个参数是serviceName  
    2. private final static QName SERVICE_NAME = new QName("http://jaxws.sample.cxftest.tiantian.com/", "HelloWorldService");  
    3. //第一个参数是服务发布的targetNameSpace,第二个参数是portName  
    4. private final static QName PORT_NAME = new QName("http://jaxws.sample.cxftest.tiantian.com/", "HelloWorldPort");  
    5. //服务发布的地址  
    6. private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";  
    7.   
    8. public static void main(String args[]) {  
    9.    Service service = Service.create(SERVICE_NAME);  
    10.    //根据portName、服务发布地址、数据绑定类型创建一个Port。  
    11.    service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, ADDRESS);//默认是SOAP1.1Binding  
    12.    //获取服务  
    13.    HelloWorld hw = service.getPort(HelloWorld.class);  
    14.    String response = hw.sayHi("world");  
    15.    System.out.println(response);  
    16. }  

           在上面的代码中我们只需要有一个Service实例,就能通过它来获取真正的WebService,所以,我们如果把上面的代码改成如下形式也是可以的。

    Java代码  
    1. //第一个参数为服务发布的targetNameSpace,可以通过查看对应的wsdl文件获得,默认是发布Service所在包的包名倒过来的形式;第二个参数是serviceName  
    2. private final static QName SERVICE_NAME = new QName("http://jaxws.sample.cxftest.tiantian.com/", "HelloWorldService");  
    3. //第一个参数是服务发布的targetNameSpace,第二个参数是portName  
    4. private final static QName PORT_NAME = new QName("http://jaxws.sample.cxftest.tiantian.com/", "HelloWorldPort");  
    5. //服务发布的地址  
    6. private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";  
    7.   
    8. public static void main(String args[]) {  
    9.    Service service = Service.create(null);  
    10.    //根据portName、服务发布地址、数据绑定类型创建一个Port。  
    11.    service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, ADDRESS);//默认是SOAP1.1Binding  
    12.    //获取服务  
    13.    HelloWorld hw = service.getPort(HelloWorld.class);  
    14.    String response = hw.sayHi("world");  
    15.    System.out.println(response);  
    16. }  

           

    上面这种通过Service来获取WebService的方法是不适用前面介绍的简单WebService实现的,即不适用获取通过ServerFactoryBean发布的WebService。

    4       java2ws工具的使用

           Cxf为我们提供了一个java2ws工具。通过该工具我们可以根据SEI(Service Endpoint Implementation的缩写)类及其相关的类来生成WebService的服务端、客户端和wsdl文件等。SEI需要是使用了@WebService标注的Service接口或类。

    4.1     命令行使用java2ws

           在Cxf根目录下的bin目录下有一个java2ws工具,我们可以在命令行下使用该指令生成相应代码。Java2ws指令后面可以接很多参数,主要有:

    参数名

    作用

    -?|-h|-help

    这三个参数都可输出java2ws指令的帮助信息

    -wsdl

    生成wsdl文件

    -o fileName

    指定生成的wsdl文件的名称

    -d resourceDir

    指定资源文件存放的目录,生成的wsdl文件也会放在该目录下

    -server

    指定生成服务端代码

    -client

    指定生成客户端代码

    -wrapperbean

    指定生成wrapper和fault bean

    -cp classpath

    指定java2ws搜寻SEI和相关类型类的路径

    -t targetNameSpace

    指定targetNameSpace

    -servicename serviceName

    指定serviceName

    -verbose

    在生成代码的时候显示注释信息

    -quiet

    在生成代码的时候不显示注释信息

    -s sourceDir

    指定生成的java代码存放的目录

    -classdir classdir

    指定生成的java代码编译后的class类存放的目录

    className

    指定SEI类的名称

           在使用java2ws指令时className是必须给定的,其他的参数都可选。java2ws将会到classpath路径下或使用-cp参数指定的classpath路径下寻找SEI类及其相关类型。

           示例:

           java2ws –server com.tiantian.cxftest.sample.jaxws.HelloWorld(生成服务端代码)

           java2ws –wsdl –cp . com.tiantian.cxftest.sample.jaxws.HelloWorld(在当前目录下寻找HelloWorld类生成wsdl文件)

    4.2     Maven使用java2ws

           Cxf为java2ws工具提供了一个Maven的插件,叫cxf-java2ws-plugin。所以当我们的项目是使用Maven的时候我们可以在项目的pom.xml文件中加入Cxf提供的cxf-java2ws-plugin,这样当我们执行Maven的某个操作的时候就会触发java2ws指令生成对应的代码。如:

    Xml代码  
    1. <plugin>  
    2.    <groupId>org.apache.cxf</groupId>  
    3.    <artifactId>cxf-java2ws-plugin</artifactId>  
    4.    <version>${cxf.version}</version>  
    5.    <executions>  
    6.       <execution>  
    7.          <id>process-classes</id>  
    8.          <phase>process-classes</phase>  
    9.          <configuration>  
    10.              <className>com.tiantian.cxftest.sample.jaxws.HelloWorld</className>  
    11.              <genWsdl>true</genWsdl>  
    12.              <verbose>true</verbose>  
    13.          </configuration>  
    14.          <goals>  
    15.              <goal>java2ws</goal>  
    16.          </goals>  
    17.       </execution>  
    18.    </executions>  
    19. </plugin>  

           对于java2ws指令的参数可以通过configuration元素下的元素来指定。可以配置的参数如下:

    参数名

    作用

    className

    指定SEI类的名称

    classpath

    搜选SEI类等相关类的类路径,默认情况下会到当前项目的类路径下寻找

    outputFile

    生成的wsdl文件存放的位置,默认是${project.build.directory}/generated/wsdl/${className}.wsdl

    genWsdl

    默认为true。是否生成wsdl文件。

    genServer

    默认false。是否生成Server端代码。

    genClient

    默认为false。是否生成Client端代码。

    genWrapperbean

    默认为false。是否生成wrapper bean

    frontend

    表明使用的frontend。支持jaxws和simple,默认是jaxws。

    databinding

    指定数据绑定。默认frontend为jaxws时用jaxb,simple用aegis

    serviceName

    指定serviceName

    soap12

    指定生成的wsdl文件包含soap1.2绑定

    targetNameSpace

    指定用来生成wsdl文件时的target namespace

    verbose

    生成代码的过程中显示注释信息

    quiet

    在生成代码的时候不显示注释信息

    attachWsdl

    当为true时,在对当前项目进行Maven的install操作时会把生成的wsdl文件以当前项目的groupId、artifactId和version,以type为wsdl一起安装到Maven的repository中去。默认为true

    address

    指定port的address

           使用cxf-java2ws-plugin插件生成的Java代码默认会放在项目的根目录下。

    5       基于Spring的Jax-ws WebService

    5.1     Service定义 

           Service定义跟之前的定义是一样的。

    5.2     服务端发布Service

           首先在web.xml文件中定义一个CXFServlet,用于发布和拦截WebService请求。

    Xml代码  
    1. <!-- Jax-ws实现 -->  
    2. <servlet>  
    3.    <display-name>jaxws-cxf</display-name>  
    4.    <servlet-name>jaxws-cxf</servlet-name>  
    5.    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>  
    6.    <load-on-startup>1</load-on-startup>  
    7.    <init-param>  
    8.       <param-name>config-location</param-name>  
    9.       <param-value>WEB-INF/jaxws-cxf-servlet.xml</param-value>  
    10.    </init-param>  
    11. </servlet>  
    12.   
    13. <servlet-mapping>  
    14.    <servlet-name>jaxws-cxf</servlet-name>  
    15.    <url-pattern>/jaxws/services/*</url-pattern>  
    16. </servlet-mapping>  

           接下来在我们的WebService配置文件里面定义我们的WebService发布,即CXFServlet指定的jaxws-cxf-servlet.xml文件(默认是cxf-servlet.xml文件)。这里我们定义如下:

    Xml代码  
    1. <beans xmlns="http://www.springframework.org/schema/beans"  
    2.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"  
    3.    xsi:schemaLocation="  
    4. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
    5. http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">  
    6.    
    7.    <!-- 相当于使用Endpoint.publish()进行服务发布 -->  
    8.    <jaxws:endpoint address="/HelloWorld" implementorClass="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>  
    9.    
    10.    <!-- 相当于使用JaxWsServerFactoryBean进行服务发布 -->  
    11.    <jaxws:server address="/HelloWorld2" serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>  
    12.      
    13.    <!-- JaxWsServerFactoryBean使用外部bean作为服务进行发布 -->  
    14.    <jaxws:server address="/HelloWorld3" serviceBean="#hw"/>  
    15.    <!-- 普通bean对象 -->  
    16.    <bean id="hw" class="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>  
    17.      
    18.    <!-- JaxWsServerFactoryBean使用内部bean作为服务进行发布 -->  
    19.    <jaxws:server address="/HelloWorld4">  
    20.       <jaxws:serviceBean>  
    21.          <bean class="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>  
    22.       </jaxws:serviceBean>  
    23.    </jaxws:server>  
    24.    
    25. </beans>  

    5.3     客户端获取Service

           客户端可以直接从Spring的bean配置文件中把WebService配置为一个个普通的Spring bean对象进行使用。这主要有两种方式,第一种是使用Jaxws命名空间,第二种是使用JaxWsProxyFactoryBean。

    第一种

           在定义之前需要往bean配置文件中引入Jax-ws的命名空间。这里我们在classpath下定义一个jaxws-cxf-client.xml文件,其内容如下所示:

    Xml代码  
    1. <beans xmlns="http://www.springframework.org/schema/beans"  
    2.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"  
    3.    xsi:schemaLocation="  
    4. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
    5. http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">  
    6.    
    7.    <jaxws:client id="hw"  
    8.       address="http://localhost:8080/test/jaxws/services/HelloWorld"  
    9.       serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld" />  
    10.    
    11.    <jaxws:client id="hw2"  
    12.       address="http://localhost:8080/test/jaxws/services/HelloWorld2"  
    13.       serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>  
    14.         
    15.    <jaxws:client id="hw3"  
    16.       address="http://localhost:8080/test/jaxws/services/HelloWorld3"  
    17.       serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>  
    18.         
    19.    <jaxws:client id="hw4"  
    20.       address="http://localhost:8080/test/jaxws/services/HelloWorld4"  
    21.       serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>  
    22.    
    23. </beans>  

      

    第二种

    Xml代码  
    1. <bean id="factoryBean" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">  
    2.    <property name="address" value="http://localhost:8080/test/jaxws/services/HelloWorld"/>  
    3.    <property name="serviceClass" value="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>  
    4. </bean>  
    5.   
    6. <bean id="helloWorld" factory-bean="factoryBean" factory-method="create"/>  

           之后我们就可以把这些定义好的WebService当做一个普通的bean对象来使用了,如:

    Java代码  
    1. public class SpringClient {  
    2.   
    3.     public static void main(String args[]) {  
    4.         ApplicationContext context = new ClassPathXmlApplicationContext("jaxws-cxf-client.xml");  
    5.         accessService(context, "hw");  
    6.         accessService(context, "hw2");  
    7.         accessService(context, "hw3");  
    8.         accessService(context, "hw4");  
    9.         accessService(context, "helloWorld");  
    10.     }  
    11.       
    12.     private static void accessService(ApplicationContext context, String beanName) {  
    13.         HelloWorld hw = context.getBean(beanName, HelloWorld.class);  
    14.         System.out.println(hw.sayHi("world"));  
    15.     }  
    16.       
    17. }  

    6       WSDL生成Java代码

           如果我们已经有了wsdl定义文件的话,我们就可以通过wsdl文件生成对应的Java代码,包括WebService的Service类定义、服务端代码、客户端代码等。这里主要介绍两种WSDL生成Java代码的方式。

    6.1     wsdl2java工具

           wsdl2java是CXF自带的工具,在CXF根目录下的bin目录下。我们可以在命令行使用这一工具。wsdl2java命令后可以接很多参数,主要有:

    参数

    作用

    -?|-h|-help

    这三个参数都可以查看wsdl2java指令的帮助信息,可以查看wsdl2java可以带哪些参数

    -p packageName

    指定生成的java类使用的包名称,如未指定将根据wsdl文件里面的targetNameSpace来决定。

    -d dir

    生成的Java文件的存放在dir目录

    -compile

    编译生成的Java文件

    -classdir dir

    指定编译生成的文件存放在dir目录下

    -server

    生成WebService的服务端发布代码

    -client

    生成WebService的客户端访问代码

    -impl

    生成Service类的实现类代码,即上面的HelloWorldImpl

    -all

    生成所有可以生成的代码

    wsdlurl

    Wsdl文件的访问路径,可以是本地file,也可以是web上的请求。

           如:wsdl2java –all http://localhost:8080/test/services/HelloWorld?wsdl

           wsdl2java在生成Service实现类的时候只会生成基本的代码结构,至于里面的操作的具体逻辑还需要我们自己来实现。

    6.2     cxf-codegen-plugin

           cxf-codegen-plugin是cxf针对于maven的一个插件。当我们的项目是基于Maven的项目时,我们可以在pom.xml文件中引入cxf-codegen-plugin,如:

    Xml代码  
    1. <plugin>  
    2.    <groupId>org.apache.cxf</groupId>  
    3.    <artifactId>cxf-codegen-plugin</artifactId>  
    4.    <version>2.7.6</version>  
    5.    <executions>  
    6.        <execution>  
    7.           <id>generate-sources</id>  
    8.           <phase>generate-sources</phase>  
    9.           <goals>  
    10.              <goal>wsdl2java</goal>  
    11.           </goals>  
    12.           <configuration>  
    13.              <sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>  
    14.              <wsdlOptions>  
    15.                 <wsdlOption>  
    16.                    <wsdl>${basedir}/src/main/resources/HelloWorld.wsdl</wsdl>  
    17.                 </wsdlOption>  
    18.              </wsdlOptions>  
    19.           </configuration>  
    20.        </execution>  
    21.    </executions>  
    22. </plugin>  

           

    在上面例子中,当我们执行mvn generate-sources时就会运行wsdl2java这个指令。其配置信息是通过configuration元素来指定的。通过sourceRoot可以指定生成的Java代码的存放位置,上面我们指定了生成代码的存放位置为target目录下的generated-sources/cxf目录,该目录也是在没有指定sourceRoot时,cxf-codegen-plugin存放生成的Java代码的默认位置。每个wsdlOption元素对应于一个用来生成代码的WSDL定义。wsdl元素用于指定wsdl文件的存放位置。wsdl2java指令的其他参数可以通过wsdlOption元素下的extraargs元素来指定。如:

    Xml代码  
    1. <plugin>  
    2.    <groupId>org.apache.cxf</groupId>  
    3.    <artifactId>cxf-codegen-plugin</artifactId>  
    4.    <version>2.7.6</version>  
    5.    <executions>  
    6.        <execution>  
    7.           <id>generate-sources</id>  
    8.          <phase>generate-sources</phase>  
    9.           <goals>  
    10.              <goal>wsdl2java</goal>  
    11.           </goals>  
    12.           <configuration>  
    13.              <wsdlOptions>  
    14.                 <wsdlOption>  
    15.                    <wsdl>${basedir}/src/main/resources/HelloWorld.wsdl</wsdl>  
    16.                    <extraargs>  
    17.                       <extraarg>-impl</extraarg>  
    18.                       <extraarg>-server</extraarg>  
    19.                    </extraargs>  
    20.                 </wsdlOption>  
    21.              </wsdlOptions>  
    22.           </configuration>  
    23.        </execution>  
    24.    </executions>  
    25. </plugin>  

           每一个extraarg元素代表一个参数,如果使用extraarg元素指定wsdl2java参数后面还带有参数值时,参数值也用一个extraarg来表示。如我们需要指定生成代码的包名时,我们的cxf-codegen-plugin应该这样声明:

    Xml代码  
    1. <plugin>  
    2.    <groupId>org.apache.cxf</groupId>  
    3.    <artifactId>cxf-codegen-plugin</artifactId>  
    4.    <version>2.7.6</version>  
    5.    <executions>  
    6.        <execution>  
    7.           <id>generate-sources</id>  
    8.           <phase>generate-sources</phase>  
    9.           <goals>  
    10.              <goal>wsdl2java</goal>  
    11.           </goals>  
    12.           <configuration>  
    13.              <wsdlOptions>  
    14.                 <wsdlOption>  
    15.                    <wsdl>${basedir}/src/main/resources/HelloWorld.wsdl</wsdl>  
    16.                    <extraargs>  
    17.                       <extraarg>-impl</extraarg>  
    18.                       <extraarg>-server</extraarg>  
    19.                       <extraarg>-p</extraarg><!-- 指定包名,后面紧跟着的extraarg为对应的值 -->  
    20.                       <extraarg>com.tiantian</extraarg>  
    21.                    </extraargs>  
    22.                 </wsdlOption>  
    23.              </wsdlOptions>  
    24.           </configuration>  
    25.        </execution>  
    26.    </executions>  
    27. </plugin>  

    使用serviceName元素指定要生成Java代码的service

           通过serviceName元素我们可以指定要针对当前wsdl文件里面的哪个service定义来生成文件。如:

    Xml代码  
    1. <configuration>  
    2.    <wsdlOptions>  
    3.       <wsdlOption>  
    4.          <wsdl>${basedir}/src/main/resources/HelloWorld.wsdl</wsdl>  
    5.          <!-- 指定要生成代码的service名称 -->  
    6.          <serviceName>HelloWorldImplService</serviceName>  
    7.       </wsdlOption>  
    8.    </wsdlOptions>  
    9. </configuration>  

    使用wsdlRoot来指定wsdl文件存放的目录

           我们知道在使用cxf-codegen-plugin的时候一个wsdlOption元素代表要生成的一个wsdl定义,当我们有多个wsdl文件时就需要定义多个wsdlOption,如:

    Xml代码  
    1. <configuration>  
    2.    <wsdlOptions>  
    3.       <wsdlOption>  
    4.          <wsdl>${basedir}/src/main/resources/wsdl/HelloWorld.wsdl</wsdl>  
    5.       </wsdlOption>  
    6.       <wsdlOption>  
    7.          <wsdl>${basedir}/src/main/resources/wsdl/HelloWorld2.wsdl</wsdl>  
    8.       </wsdlOption>  
    9.    </wsdlOptions>  
    10. </configuration>  

           当我们的wsdl文件少的时候这样做还可以,但是当wsdl文件比较多的时候这样做就有点麻烦了。这个时候我们可以通过wsdlRoot元素来指定我们的wsdl文件存放的目录,cxf-codegen-plugin在扫描的时候只会扫描wsdlRoot指定的目录,而不会扫描其子目录。光指定了wsdlRoot还不能起作用,wsdlRoot必须和includes元素或者excludes元素配合使用。includes元素表示要包含哪些文件,而excludes元素表示要排除哪些文件。所以当我们要使用wsdl2java指定对wsdlRoot下的所有文件生成java代码时,我们可以这样做:

    Java代码  
    1. <configuration>  
    2.    <wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>  
    3.    <includes>  
    4.       <include>*.wsdl</include>  
    5.    </includes>  
    6. </configuration>  

           或者这样做:

    Xml代码  
    1. <configuration>  
    2.    <wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>  
    3.    <excludes>  
    4.       <exclude>null</exclude>  
    5.    </excludes>  
    6. </configuration>  

    使用defaultOptions来指定公共的选项

           当我们使用wsdlRoot元素来指定wsdl文件存放目录时,我们就不能再指定wsdl2java指令执行时的可选参数了。这个时候我们可以通过defaultOptions元素来指定。defaultOptions元素下指定的选项对所有的wsdlOption元素都会产生作用。如:

    Xml代码  
    1. <configuration>  
    2.    <defaultOptions>  
    3.       <extraargs>  
    4.          <extraarg>-all</extraarg>  
    5.       </extraargs>  
    6.    </defaultOptions>  
    7.    <wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>  
    8.    <includes>  
    9.       <include>helloWorld.wsdl</include>  
    10.    </includes>  
    11. </configuration>  
  • 相关阅读:
    2019暑假中山纪中集训游记
    pytest入门学习(1)
    学习makefile与autoconfig笔记,持续更新
    新手安装 hadoop、hive和hbase 笔记
    新装ubuntu 12.04 , 使用技巧
    JDK1.7 和 jetty配置教程
    python成长之路一
    IDM下载神器
    测试
    Hadoop命令
  • 原文地址:https://www.cnblogs.com/sunlibincn/p/5974281.html
Copyright © 2020-2023  润新知