加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

简单的Jax-WS webservice实现

发布时间:2020-12-16 21:50:48 所属栏目:安全 来源:网络整理
导读:目录 ? 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????

目录

?

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操作。其对应的实现类如下:

?

  • public?class?HelloWorldImpl?implements?HelloWorld?{??
  • ???
  • ???@Override??
  • ???public?String?sayHi(String?who)?{??
  • ??????return"Hi,?"?+?who;??
  • ???}??
  • ???
  • }??
  • 2???????服务端发布Service

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

    第一种:

  • public?class?Server?{??
  • ???
  • ???private?final?static?String?ADDRESS?=?"http://localhost:8080/test/jaxws/services/HelloWorld";??
  • ?????
  • ???public?static?void?main(String?args[])?{??
  • ??????HelloWorld?hw?=?new?HelloWorldImpl();??
  • ??????Endpoint.publish(ADDRESS,?hw);??
  • ???}??
  • ?????
  • }??
  • 第二种:

  • public?class?Server?{??
  • ???
  • ???private?final?static?String?ADDRESS?=?"http://localhost:8080/test/jaxws/services/HelloWorld";??
  • ?????
  • ???public?static?void?main(String?args[])?{??
  • ??????HelloWorld?hw?=?new?HelloWorldImpl();??
  • ??????JaxWsServerFactoryBean?jwsFactory?=?new?JaxWsServerFactoryBean();??
  • ??????jwsFactory.setAddress(ADDRESS);???//指定WebService的发布地址??
  • ??????jwsFactory.setServiceClass(HelloWorld.class);//WebService对应的类型??
  • ??????jwsFactory.setServiceBean(hw);//WebService对应的实现对象??
  • ??????jwsFactory.create();??
  • ???}??
  • ?????
  • }??
  • ???????发布之后我们就可以通过发布地址?wsdl查看WebService的定义了(WSDL是Web Service Description Language的简称,即网络服务描述语言)。通过在浏览器输入http://localhost:8080/test/jaxws/services/HelloWorld?wsdl我们可以看到如下内容:

    Xml代码??
  • This?XML?file?does?not?appear?to?have?any?style?information?associated??
  • with?it.?The?document?tree?is?shown?below.??
  • <wsdl:definitions?xmlns:xsd="http://www.w3.org/2001/XMLSchema"??
  • ????xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"?xmlns:tns="http://jaxws.sample.cxftest.tiantian.com/"??
  • ????xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"?xmlns:ns1="http://schemas.xmlsoap.org/soap/http"??
  • ????name="HelloWorldImplService"?targetNamespace="http://jaxws.sample.cxftest.tiantian.com/">??
  • ????<wsdl:types>??
  • ????????<xs:schema?xmlns:xs="http://www.w3.org/2001/XMLSchema"??
  • ????????????xmlns:tns="http://jaxws.sample.cxftest.tiantian.com/"??
  • ????????????elementFormDefault="unqualified"?targetNamespace="http://jaxws.sample.cxftest.tiantian.com/"??
  • ????????????version="1.0">??
  • ????????????<xs:element?name="sayHi"?type="tns:sayHi"?/>??
  • ????????????<xs:element?name="sayHiResponse"?type="tns:sayHiResponse"?/>??
  • ????????????<xs:complexType?name="sayHi">??
  • ????????????????<xs:sequence>??
  • ????????????????????<xs:element?minOccurs="0"?name="arg0"?type="xs:string"?/>??
  • ????????????????</xs:sequence>??
  • ????????????</xs:complexType>??
  • ????????????<xs:complexType?name="sayHiResponse">??
  • ????????????????<xs:sequence>??
  • ????????????????????<xs:element?minOccurs="0"?name="return"?type="xs:string"?/>??
  • ????????????????</xs:sequence>??
  • ????????????</xs:complexType>??
  • ????????</xs:schema>??
  • ????</wsdl:types>??
  • ????<wsdl:message?name="sayHiResponse">??
  • ????????<wsdl:part?element="tns:sayHiResponse"?name="parameters"></wsdl:part>??
  • ????</wsdl:message>??
  • ????<wsdl:message?name="sayHi">??
  • ????????<wsdl:part?element="tns:sayHi"?name="parameters"></wsdl:part>??
  • ????</wsdl:message>??
  • ????<wsdl:portType?name="HelloWorld">??
  • ????????<wsdl:operation?name="sayHi">??
  • ????????????<wsdl:input?message="tns:sayHi"?name="sayHi"></wsdl:input>??
  • ????????????<wsdl:output?message="tns:sayHiResponse"?name="sayHiResponse"></wsdl:output>??
  • ????????</wsdl:operation>??
  • ????</wsdl:portType>??
  • ????<wsdl:binding?name="HelloWorldImplServiceSoapBinding"??
  • ????????type="tns:HelloWorld">??
  • ????????<soap:binding?style="document"??
  • ????????????transport="http://schemas.xmlsoap.org/soap/http"?/>??
  • ????????<wsdl:operation?name="sayHi">??
  • ????????????<soap:operation?soapAction=""?style="document"?/>??
  • ????????????<wsdl:input?name="sayHi">??
  • ????????????????<soap:body?use="literal"?/>??
  • ????????????</wsdl:input>??
  • ????????????<wsdl:output?name="sayHiResponse">??
  • ????????????????<soap:body?use="literal"?/>??
  • ????????????</wsdl:output>??
  • ????????</wsdl:operation>??
  • ????</wsdl:binding>??
  • ????<wsdl:service?name="HelloWorldImplService">??
  • ????????<wsdl:port?binding="tns:HelloWorldImplServiceSoapBinding"??
  • ????????????name="HelloWorldImplPort">??
  • ????????????<soap:address?location="http://localhost:8080/test/jaxws/services/HelloWorld"?/>??
  • ????????</wsdl:port>??
  • ????</wsdl:service>??
  • </wsdl:definitions>??
  • ???????我们可以看到在上面我们的sayHi操作的参数who变成了arg0,这是因为接口在被编译为class文件的时候不能保存参数名,有时候这会影响可读性。如果需要参数名显示的可读性强一些的话,我们可以使用@WebParam来指定,如:

  • @WebService(serviceName="!@#$%^",?name="123456")??
  • public?interface?HelloWorld?{??
  • ???
  • ???public?String?sayHi(@WebParam(name="who")?String?who);??
  • ?????
  • }??
  • ???

    @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。

  • @WebService??
  • public?interface?HelloWorld?{??
  • ???
  • ???public?String?sayHi(@WebParam(name="who")?String?who);??
  • ?????
  • ???public?String?sayHello(@WebParam(name="who")?String?who);??
  • ?????
  • }??
  • ???????对于有接口的WebService而言,@WebMethod的exclude定义必须指定在其实现类对应的需要排除的方法上,而其他属性则必须在接口方法上定义。所以我们的实现类定义如下:

    ?+?who;??

  • ???}??
  • ?????
  • ???@Override??
  • ???@WebMethod(exclude=true)??
  • ???public?String?sayHello(String?who)?{??
  • ??????return"Hello,?"?+?who;??
  • ???}??
  • ???
  • }??
  • ???????这样,在服务发布时就会把sayHello方法排除在外。有兴趣的朋友可以通过查看指定exclude前后的wsdl文件验证一下sayHello方法是否在exclude为true时被排除了。客户端在访问sayHello方法的时候也是不会成功的。

    3???????客户端访问Service

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

  • public?class?Client?{??
  • ???
  • ???private?final?static?String?ADDRESS?=?"http://localhost:8080/test/jaxws/services/HelloWorld";??
  • ?????
  • ???public?static?void?main(String?args[])?{??
  • ??????JaxWsProxyFactoryBean?jwpFactory?=?new?JaxWsProxyFactoryBean();??
  • ??????jwpFactory.setAddress(ADDRESS);??
  • ??????jwpFactory.setServiceClass(HelloWorld.class);??
  • ??????HelloWorld?hw?=?(HelloWorld)jwpFactory.create();??
  • ??????String?response?=?hw.sayHi("world");??
  • ??????System.out.println(response);??
  • ???}??
  • ?????
  • }??
  • 除了上面的方式之外,我们还可以这样获取Service:

  • //第一个参数为服务发布的targetNameSpace,可以通过查看对应的wsdl文件获得,默认是发布Service所在包的包名倒过来的形式;第二个参数是serviceName??
  • private?final?static?QName?SERVICE_NAME?=?new?QName("http://jaxws.sample.cxftest.tiantian.com/",?"HelloWorldService");??
  • //第一个参数是服务发布的targetNameSpace,第二个参数是portName??
  • private?final?static?QName?PORT_NAME?=?new?QName("http://jaxws.sample.cxftest.tiantian.com/",?"HelloWorldPort");??
  • //服务发布的地址??
  • private?final?static?String?ADDRESS?=?"http://localhost:8080/test/jaxws/services/HelloWorld";??
  • ??
  • public?static?void?main(String?args[])?{??
  • ???Service?service?=?Service.create(SERVICE_NAME);??
  • ???//根据portName、服务发布地址、数据绑定类型创建一个Port。??
  • ???service.addPort(PORT_NAME,?SOAPBinding.SOAP11HTTP_BINDING,?ADDRESS);//默认是SOAP1.1Binding??
  • ???//获取服务??
  • ???HelloWorld?hw?=?service.getPort(HelloWorld.class);??
  • ???String?response?=?hw.sayHi("world");??
  • ???System.out.println(response);??
  • }??
  • ???????在上面的代码中我们只需要有一个Service实例,就能通过它来获取真正的WebService,所以,我们如果把上面的代码改成如下形式也是可以的。

    "HelloWorldPort");??

  • //服务发布的地址??
  • private?final?static?String?ADDRESS?=?"http://localhost:8080/test/jaxws/services/HelloWorld";??
  • ??
  • public?static?void?main(String?args[])?{??
  • ???Service?service?=?Service.create(null);??
  • ???//根据portName、服务发布地址、数据绑定类型创建一个Port。??
  • ???service.addPort(PORT_NAME,0)">???????

    上面这种通过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指令生成对应的代码。如:

  • <plugin>??
  • ???<groupId>org.apache.cxf</groupId>??
  • ???<artifactId>cxf-java2ws-plugin</artifactId>??
  • ???<version>${cxf.version}</version>??
  • ???<executions>??
  • ??????<execution>??
  • ?????????<id>process-classes</id>??
  • ?????????<phase>process-classes</phase>??
  • ?????????<configuration>??
  • ?????????????<className>com.tiantian.cxftest.sample.jaxws.HelloWorld</className>??
  • ?????????????<genWsdl>true</genWsdl>??
  • ?????????????<verbose>true</verbose>??
  • ?????????</configuration>??
  • ?????????<goals>??
  • ?????????????<goal>java2ws</goal>??
  • ?????????</goals>??
  • ??????</execution>??
  • ???</executions>??
  • </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请求。

  • <!--?Jax-ws实现?-->??
  • <servlet>??
  • ???<display-name>jaxws-cxf</display-name>??
  • ???<servlet-name>jaxws-cxf</servlet-name>??
  • ???<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>??
  • ???<load-on-startup>1</load-on-startup>??
  • ???<init-param>??
  • ??????<param-name>config-location</param-name>??
  • ??????<param-value>WEB-INF/jaxws-cxf-servlet.xml</param-value>??
  • ???</init-param>??
  • </servlet>??
  • ??
  • <servlet-mapping>??
  • ???<servlet-name>jaxws-cxf</servlet-name>??
  • ???<url-pattern>/jaxws/services/*</url-pattern>??
  • </servlet-mapping>??
  • ???????接下来在我们的WebService配置文件里面定义我们的WebService发布,即CXFServlet指定的jaxws-cxf-servlet.xml文件(默认是cxf-servlet.xml文件)。这里我们定义如下:

  • <beans?xmlns="http://www.springframework.org/schema/beans"??
  • ???xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?xmlns:jaxws="http://cxf.apache.org/jaxws"??
  • ???xsi:schemaLocation="??
  • http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans.xsd??
  • http://cxf.apache.org/jaxws?http://cxf.apache.org/schemas/jaxws.xsd">??
  • ???
  • ???<!--?相当于使用Endpoint.publish()进行服务发布?-->??
  • ???<jaxws:endpoint?address="/HelloWorld"?implementorClass="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>??
  • ???
  • ???<!--?相当于使用JaxWsServerFactoryBean进行服务发布?-->??
  • ???<jaxws:server?address="/HelloWorld2"?serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>??
  • ?????
  • ???<!--?JaxWsServerFactoryBean使用外部bean作为服务进行发布?-->??
  • ???<jaxws:server?address="/HelloWorld3"?serviceBean="#hw"/>??
  • ???<!--?普通bean对象?-->??
  • ???<bean?id="hw"?class="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>??
  • ?????
  • ???<!--?JaxWsServerFactoryBean使用内部bean作为服务进行发布?-->??
  • ???<jaxws:server?address="/HelloWorld4">??
  • ??????<jaxws:serviceBean>??
  • ?????????<bean?class="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>??
  • ??????</jaxws:serviceBean>??
  • ???</jaxws:server>??
  • ???
  • </beans>??
  • 5.3?????客户端获取Service

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

    第一种

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

  • <beans?xmlns="http://www.springframework.org/schema/beans"??
  • ???xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?xmlns:jaxws="http://cxf.apache.org/jaxws"??
  • ???xsi:schemaLocation="??
  • http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans.xsd??
  • http://cxf.apache.org/jaxws?http://cxf.apache.org/schemas/jaxws.xsd">??
  • ???
  • ???<jaxws:client?id="hw"??
  • ??????address="http://localhost:8080/test/jaxws/services/HelloWorld"??
  • ??????serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld"?/>??
  • ???
  • ???<jaxws:client?id="hw2"??
  • ??????address="http://localhost:8080/test/jaxws/services/HelloWorld2"??
  • ??????serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>??
  • ????????
  • ???<jaxws:client?id="hw3"??
  • ??????address="http://localhost:8080/test/jaxws/services/HelloWorld3"??
  • ??????serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>??
  • ????????
  • ???<jaxws:client?id="hw4"??
  • ??????address="http://localhost:8080/test/jaxws/services/HelloWorld4"??
  • ??????serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>??
  • ???
  • </beans>??
  • ??

    第二种

  • <bean?id="factoryBean"?class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">??
  • ???<property?name="address"?value="http://localhost:8080/test/jaxws/services/HelloWorld"/>??
  • ???<property?name="serviceClass"?value="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>??
  • </bean>??
  • ??
  • <bean?id="helloWorld"?factory-bean="factoryBean"?factory-method="create"/>??
  • ? ? ? ?之后我们就可以把这些定义好的WebService当做一个普通的bean对象来使用了,如:

  • public?class?SpringClient?{??
  • ??
  • ????public?static?void?main(String?args[])?{??
  • ????????ApplicationContext?context?=?new?ClassPathXmlApplicationContext("jaxws-cxf-client.xml");??
  • ????????accessService(context,?"hw");??
  • ????????accessService(context,?"hw2");??
  • ????????accessService(context,?"hw3");??
  • ????????accessService(context,?"hw4");??
  • ????????accessService(context,?"helloWorld");??
  • ????}??
  • ??????
  • ????private?static?void?accessService(ApplicationContext?context,?String?beanName)?{??
  • ????????HelloWorld?hw?=?context.getBean(beanName,?HelloWorld.class);??
  • ????????System.out.println(hw.sayHi("world"));??
  • ????}??
  • ??????
  • }??
  • 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,如:

  • <plugin>??
  • ???<groupId>org.apache.cxf</groupId>??
  • ???<artifactId>cxf-codegen-plugin</artifactId>??
  • ???<version>2.7.6</version>??
  • ???<executions>??
  • ???????<execution>??
  • ??????????<id>generate-sources</id>??
  • ??????????<phase>generate-sources</phase>??
  • ??????????<goals>??
  • ?????????????<goal>wsdl2java</goal>??
  • ??????????</goals>??
  • ??????????<configuration>??
  • ?????????????<sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>??
  • ?????????????<wsdlOptions>??
  • ????????????????<wsdlOption>??
  • ???????????????????<wsdl>${basedir}/src/main/resources/HelloWorld.wsdl</wsdl>??
  • ????????????????</wsdlOption>??
  • ?????????????</wsdlOptions>??
  • ??????????</configuration>??
  • ???????</execution>??
  • ???</executions>??
  • </plugin>??
  • 在上面例子中,当我们执行mvn generate-sources时就会运行wsdl2java这个指令。其配置信息是通过configuration元素来指定的。通过sourceRoot可以指定生成的Java代码的存放位置,上面我们指定了生成代码的存放位置为target目录下的generated-sources/cxf目录,该目录也是在没有指定sourceRoot时,cxf-codegen-plugin存放生成的Java代码的默认位置。每个wsdlOption元素对应于一个用来生成代码的WSDL定义。wsdl元素用于指定wsdl文件的存放位置。wsdl2java指令的其他参数可以通过wsdlOption元素下的extraargs元素来指定。如:

  • <plugin>??
  • ???<groupId>org.apache.cxf</groupId>??
  • ???<artifactId>cxf-codegen-plugin</artifactId>??
  • ???<version>2.7.6</version>??
  • ???<executions>??
  • ???????<execution>??
  • ??????????<id>generate-sources</id>??
  • ?????????<phase>generate-sources</phase>??
  • ??????????<goals>??
  • ?????????????<goal>wsdl2java</goal>??
  • ??????????</goals>??
  • ??????????<configuration>??
  • ?????????????<wsdlOptions>??
  • ????????????????<wsdlOption>??
  • ???????????????????<wsdl>${basedir}/src/main/resources/HelloWorld.wsdl</wsdl>??
  • ???????????????????<extraargs>??
  • ??????????????????????<extraarg>-impl</extraarg>??
  • ??????????????????????<extraarg>-server</extraarg>??
  • ???????????????????</extraargs>??
  • ????????????????</wsdlOption>??
  • ?????????????</wsdlOptions>??
  • ??????????</configuration>??
  • ???????</execution>??
  • ???</executions>??
  • </plugin>??
  • ???????每一个extraarg元素代表一个参数,如果使用extraarg元素指定wsdl2java参数后面还带有参数值时,参数值也用一个extraarg来表示。如我们需要指定生成代码的包名时,我们的cxf-codegen-plugin应该这样声明:

  • <plugin>??
  • ???<groupId>org.apache.cxf</groupId>??
  • ???<artifactId>cxf-codegen-plugin</artifactId>??
  • ???<version>2.7.6</version>??
  • ???<executions>??
  • ???????<execution>??
  • ??????????<id>generate-sources</id>??
  • ??????????<phase>generate-sources</phase>??
  • ??????????<goals>??
  • ?????????????<goal>wsdl2java</goal>??
  • ??????????</goals>??
  • ??????????<configuration>??
  • ?????????????<wsdlOptions>??
  • ????????????????<wsdlOption>??
  • ???????????????????<wsdl>${basedir}/src/main/resources/HelloWorld.wsdl</wsdl>??
  • ???????????????????<extraargs>??
  • ??????????????????????<extraarg>-impl</extraarg>??
  • ??????????????????????<extraarg>-server</extraarg>??
  • ??????????????????????<extraarg>-p</extraarg><!--?指定包名,后面紧跟着的extraarg为对应的值?-->??
  • ??????????????????????<extraarg>com.tiantian</extraarg>??
  • ???????????????????</extraargs>??
  • ????????????????</wsdlOption>??
  • ?????????????</wsdlOptions>??
  • ??????????</configuration>??
  • ???????</execution>??
  • ???</executions>??
  • </plugin>??
  • 使用serviceName元素指定要生成Java代码的service

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

  • <configuration>??
  • ???<wsdlOptions>??
  • ??????<wsdlOption>??
  • ?????????<wsdl>${basedir}/src/main/resources/HelloWorld.wsdl</wsdl>??
  • ?????????<!--?指定要生成代码的service名称?-->??
  • ?????????<serviceName>HelloWorldImplService</serviceName>??
  • ??????</wsdlOption>??
  • ???</wsdlOptions>??
  • </configuration>??
  • 使用wsdlRoot来指定wsdl文件存放的目录

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

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

  • <configuration>??
  • ???<wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>??
  • ???<includes>??
  • ??????<include>*.wsdl</include>??
  • ???</includes>??
  • </configuration>??
  • ???????或者这样做:

  • <configuration>??
  • ???<wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>??
  • ???<excludes>??
  • ??????<exclude>null</exclude>??
  • ???</excludes>??
  • </configuration>??
  • 使用defaultOptions来指定公共的选项

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

  • <configuration>??
  • ???<defaultOptions>??
  • ??????<extraargs>??
  • ?????????<extraarg>-all</extraarg>??
  • ??????</extraargs>??
  • ???</defaultOptions>??
  • ???<wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>??
  • ???<includes>??
  • ??????<include>helloWorld.wsdl</include>??
  • ???</includes>??
  • </configuration>??
  • ?(本文首次发布于本人的iteye博客,http://elim.iteye.com/blog/1985995)

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读