天天看點

簡單的Jax-WS WebService實作 1       定義Service 2       服務端釋出Service 4       java2ws工具的使用

目錄

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的一種規範。

       Jax-ws的WebService定義是通過注解進行的,我們必須在其WebService類的接口上使用@WebService注解進行标記。

       如上,我們把HelloWorld定義為一個WebService,其對應有一個sayHi操作。其對應的實作類如下:

       對于Jax-ws WebService而言,釋出Service有兩種方式。

第一種:

第二種:

       我們可以看到在上面我們的sayHi操作的參數who變成了arg0,這是因為接口在被編譯為class檔案的時候不能儲存參數名,有時候這會影響可讀性。如果需要參數名顯示的可讀性強一些的話,我們可以使用@WebParam來指定,如:

@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标注的方法表示它不需要等待服務端的傳回,也不需要預留資源來處理服務端的傳回。

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

       對于有接口的WebService而言,@WebMethod的exclude定義必須指定在其實作類對應的需要排除的方法上,而其他屬性則必須在接口方法上定義。是以我們的實作類定義如下:

       這樣,在服務釋出時就會把sayHello方法排除在外。有興趣的朋友可以通過檢視指定exclude前後的wsdl檔案驗證一下sayHello方法是否在exclude為true時被排除了。用戶端在通路sayHello方法的時候也是不會成功的。

類似于WebService簡單實作裡面的ClientProxyFactoryBean,在使用Jax-ws時我們可以通過JaxWsProxyFactoryBean來通路服務,如:

除了上面的方式之外,我們還可以這樣擷取Service:

       在上面的代碼中我們隻需要有一個Service執行個體,就能通過它來擷取真正的WebService,是以,我們如果把上面的代碼改成如下形式也是可以的。

上面這種通過Service來擷取WebService的方法是不适用前面介紹的簡單WebService實作的,即不适用擷取通過ServerFactoryBean釋出的WebService。

       Cxf為我們提供了一個java2ws工具。通過該工具我們可以根據SEI(Service Endpoint Implementation的縮寫)類及其相關的類來生成WebService的服務端、用戶端和wsdl檔案等。SEI需要是使用了@WebService标注的Service接口或類。

       在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檔案)

       Cxf為java2ws工具提供了一個Maven的插件,叫cxf-java2ws-plugin。是以當我們的項目是使用Maven的時候我們可以在項目的pom.xml檔案中加入Cxf提供的cxf-java2ws-plugin,這樣當我們執行Maven的某個操作的時候就會觸發java2ws指令生成對應的代碼。如:

       對于java2ws指令的參數可以通過configuration元素下的元素來指定。可以配置的參數如下:

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

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代碼預設會放在項目的根目錄下。

       Service定義跟之前的定義是一樣的。

       首先在web.xml檔案中定義一個CXFServlet,用于釋出和攔截WebService請求。

       接下來在我們的WebService配置檔案裡面定義我們的WebService釋出,即CXFServlet指定的jaxws-cxf-servlet.xml檔案(預設是cxf-servlet.xml檔案)。這裡我們定義如下:

       用戶端可以直接從Spring的bean配置檔案中把WebService配置為一個個普通的Spring bean對象進行使用。這主要有兩種方式,第一種是使用Jaxws命名空間,第二種是使用JaxWsProxyFactoryBean。

       在定義之前需要往bean配置檔案中引入Jax-ws的命名空間。這裡我們在classpath下定義一個jaxws-cxf-client.xml檔案,其内容如下所示:

       之後我們就可以把這些定義好的WebService當做一個普通的bean對象來使用了,如:

       如果我們已經有了wsdl定義檔案的話,我們就可以通過wsdl檔案生成對應的Java代碼,包括WebService的Service類定義、服務端代碼、用戶端代碼等。這裡主要介紹兩種WSDL生成Java代碼的方式。

       wsdl2java是CXF自帶的工具,在CXF根目錄下的bin目錄下。我們可以在指令行使用這一工具。wsdl2java指令後可以接很多參數,主要有:

參數

這三個參數都可以檢視wsdl2java指令的幫助資訊,可以檢視wsdl2java可以帶哪些參數

-p packageName

指定生成的java類使用的包名稱,如未指定将根據wsdl檔案裡面的targetNameSpace來決定。

-d dir

生成的Java檔案的存放在dir目錄

-compile

編譯生成的Java檔案

-classdir dir

指定編譯生成的檔案存放在dir目錄下

生成WebService的服務端釋出代碼

生成WebService的用戶端通路代碼

-impl

生成Service類的實作類代碼,即上面的HelloWorldImpl

-all

生成所有可以生成的代碼

wsdlurl

Wsdl檔案的通路路徑,可以是本地file,也可以是web上的請求。

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

       wsdl2java在生成Service實作類的時候隻會生成基本的代碼結構,至于裡面的操作的具體邏輯還需要我們自己來實作。

       cxf-codegen-plugin是cxf針對于maven的一個插件。當我們的項目是基于Maven的項目時,我們可以在pom.xml檔案中引入cxf-codegen-plugin,如:

在上面例子中,當我們執行mvn generate-sources時就會運作wsdl2java這個指令。其配置資訊是通過configuration元素來指定的。通過sourceRoot可以指定生成的Java代碼的存放位置,上面我們指定了生成代碼的存放位置為target目錄下的generated-sources/cxf目錄,該目錄也是在沒有指定sourceRoot時,cxf-codegen-plugin存放生成的Java代碼的預設位置。每個wsdlOption元素對應于一個用來生成代碼的WSDL定義。wsdl元素用于指定wsdl檔案的存放位置。wsdl2java指令的其他參數可以通過wsdlOption元素下的extraargs元素來指定。如:

       每一個extraarg元素代表一個參數,如果使用extraarg元素指定wsdl2java參數後面還帶有參數值時,參數值也用一個extraarg來表示。如我們需要指定生成代碼的包名時,我們的cxf-codegen-plugin應該這樣聲明:

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

       通過serviceName元素我們可以指定要針對目前wsdl檔案裡面的哪個service定義來生成檔案。如:

使用wsdlRoot來指定wsdl檔案存放的目錄

       我們知道在使用cxf-codegen-plugin的時候一個wsdlOption元素代表要生成的一個wsdl定義,當我們有多個wsdl檔案時就需要定義多個wsdlOption,如:

       當我們的wsdl檔案少的時候這樣做還可以,但是當wsdl檔案比較多的時候這樣做就有點麻煩了。這個時候我們可以通過wsdlRoot元素來指定我們的wsdl檔案存放的目錄,cxf-codegen-plugin在掃描的時候隻會掃描wsdlRoot指定的目錄,而不會掃描其子目錄。光指定了wsdlRoot還不能起作用,wsdlRoot必須和includes元素或者excludes元素配合使用。includes元素表示要包含哪些檔案,而excludes元素表示要排除哪些檔案。是以當我們要使用wsdl2java指定對wsdlRoot下的所有檔案生成java代碼時,我們可以這樣做:

       或者這樣做:

使用defaultOptions來指定公共的選項

       當我們使用wsdlRoot元素來指定wsdl檔案存放目錄時,我們就不能再指定wsdl2java指令執行時的可選參數了。這個時候我們可以通過defaultOptions元素來指定。defaultOptions元素下指定的選項對所有的wsdlOption元素都會産生作用。如: