1. 程式人生 > >CXF 教程(一)

CXF 教程(一)

build 引入 -o rgs lsp specified cat 啟動服務 .class

CXF Web Service 簡單示例


1 準備工作

2 第一個例子

3 客戶端

3.1 使用 WSDL 生成客戶端

4 RPC 風格

5 相關命令介紹

5.1 Java to WS


1 準備工作

  • 從 http://cxf.apache.org 下載 CXF
  • 在 Eclipse 中配置 Maven 插件

2 第一個例子

步驟如下

  1. 創建 Maven 項目, 使用 quickstart 模板

  2. 在 pom.xml 中引入依賴包,如下所示

    pom.xml

    <properties>
    	<cxf.version>3.1.0</cxf.version>
    	</properties>
    	<dependencies>
    		<dependency>
    			<groupId>org.apache.cxf</groupId>
    			<artifactId>cxf-rt-frontend-jaxws</artifactId>
    			<version>${cxf.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.cxf</groupId>
    			<artifactId>cxf-rt-transports-http</artifactId>
    			<version>${cxf.version}</version>
    		</dependency>
        		<dependency>
    			<groupId>org.apache.cxf</groupId>
    			<artifactId>cxf-rt-transports-http-jetty</artifactId>
    			<version>${cxf.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>javax.xml</groupId>
    			<artifactId>webservices-api</artifactId>
    			<version>2.0.1</version>
    		</dependency>
    </project>
    
  3. 寫一個簡單的 Service 類,如下所示

    HelloService.java

    package lld.cxf.service;
    import javax.jws.WebService;
    @WebService
    public interface HelloService {
    	String sayHi(String name);
    }
    

    HelloServiceImpl.java

    package lld.cxf.service;
    public class HelloServiceImpl implements HelloService {
    	public String sayHi(String name) {
    		return "Hello " + name;
    	}
    }
  4. 創建 Server 如下所示, 這就是為什麽需引入 cxf-rt-transports-http-jetty 包的原因,CXF 內嵌了 Jetty server。

    HelloServer.java

    package lld.cxf.service;
    import org.apache.cxf.frontend.ServerFactoryBean;
    public class HelloServer {
    	public static void main(String[] args) {
    		// Create our service implementation
    		HelloService helloWorldImpl = new HelloServiceImpl();
    		// Create our Server
    		ServerFactoryBean svrFactory = new ServerFactoryBean();
    		svrFactory.setServiceClass(HelloService.class);
    		svrFactory.setAddress("http://localhost:9000/Hello");
    		svrFactory.setServiceBean(helloWorldImpl);
    		svrFactory.create();
    	}
    }
    
  5. 運行 Server 後可在瀏覽器中輸入 http://localhost:9000/Hello?wsdl 驗證

  6. 創建 Client 端如下所示

    HelloServer.java

3 客戶端

3.1 使用 WSDL 生成客戶端

上例中我們直接把客戶端和服務端放在了一個項目中,實際情況一般不會這樣。通常是服務端發布 WSDL 的 URL,客戶端使用 WSDL 來生成本地 Proxy 代碼並訪問 Web Service。

  1. 首先我們得生成 WSDL 文件,最省事的辦法是直接在瀏覽器中訪問上例中的 WSDL 鏈接並把瀏覽器中的文本結果另存為本地文件並以 wsdl 作為擴展名

    或者我們也可以根據編譯結果生成 wsdl 文件。在下載的 CXF 中,在 bin 目錄下找到 java2ws 命令,進入結果文件根目錄(classes 目錄),運行命令如下所示:

    java2ws -wsdl -o HelloService.wsdl lld.cxf.service.HelloService

    將會在當前目錄生成 HelloService.wsdl

  2. 根據 wsdl 文件生成客戶端 stub,同樣是使用 CXF 下載包中的 wsdl2java 命令,如下所示

    wsdl2java -client -d ClientDir ../resources/HelloService.wsdl

    將把 Stub 生成在當前目錄的 ClientDir 目錄下

  3. 上一步生成的 Stub 中裏面包含了很多文件,細節先不用管,把這些文件復制到當前源代碼目錄中,其中有一個文件 HelloServicePortType_HelloServicePort_Client.java 是一個客戶端的調用示例文件,可參考裏面的內容寫出如下的客戶端調用

    我將生成的 HelloService.wsdl 文件放在了 resources 目錄下,也就是會自動復制到 classes 根目錄下。

    HelloService.java

    package lld.cxf.client.test;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    import javax.xml.namespace.QName;
    import lld.cxf.service.HelloService;
    import lld.cxf.service.HelloServicePortType;
    
    public class HelloClientTest {
    	private static final QName SERVICE_NAME = new QName("http://service.cxf.lld/", "HelloService");
    
    	public static void main(String[] args) throws MalformedURLException {
    		String wsdlFileName = "HelloService.wsdl";
    		URL wsdlURL = HelloClientTest.class.getClassLoader().getResource(wsdlFileName);
    		
    		HelloService ss = new HelloService(wsdlURL, SERVICE_NAME);
    		HelloServicePortType port = ss.getHelloServicePort();
    		System.out.println("Invoking sayHi...");
    		String result = port.sayHi("Lindong");
    		System.out.println("sayHi.result=" + result);
    	}
    }
    
  4. 另外也可以不必將 wsdl 存放在本地而是直接從遠端獲取,將上面獲取 URL 的代碼進行如下替換即可:

    String wsdlUrl = "http://localhost:9000/Hello?wsdl";
    URL wsdlURL = new URL(wsdlUrl);
    

通常情況下,如果公司不是按代碼量算薪水,我們一般會將 Stub 類打成 jar 包放在引用路徑裏,以使代碼更加清晰。如果使用 Eclipse,可直接使用 Export 功能將選中的 Stub package 導出為jar 包。

4 RPC 風格

將上面的 Service 類修改如下,將生成 RPC 風格的 Web Service

HelloService.java

package lld.cxf.service;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
@WebService
@SOAPBinding(style = Style.RPC)
public class HelloService {
	public String sayHi(String name) {
		return "Hello " + name;
	}
}

5 相關命令介紹

5.1 Java to WS

5.1.1 Overview

官方幫助:Java to WS

在 2.1 以前的版本中命令為 java2wsdl,在新的版本中為 java2ws

java2ws 用於生成 Web service endpoint‘s implementation (SEI) 類並根據這些類生成 WSDL 文件, Bean 封裝類, 用於啟動服務的服務端代碼和客戶端方問代碼。

5.1.2 語法

語法如下所示:

java2ws -databinding  -frontend  
        -wsdl -wrapperbean -client -server -ant -o 
        -d  -classdir  
        -cp  -soap12 -t  
        -beans * 
        -address  -servicename  
        -portname  -createxsdimports -h -v -verbose 
        -quiet {classname}

5.1.3 參數說明

各參數說明如下:

Option

Interpretation

-?,-h,-help

Displays the online help for this utility and exits.

-o

Specifies the name of the generated WSDL file.

--databinding

Specify the data binding (aegis or jaxb). Default is jaxb for jaxws frontend, and aegis for simple frontend.

-frontend

Specify the frontend to use. jaxws and the simple frontend are supported.

-wsdl

Specify to generate the WSDL file.

-wrapperbean

Specify to generate the wrapper and fault bean

-client

Specify to generate client side code

-server

Specify to generate server side code

-ant

Specify to generate an Ant build.xml script

-cp

Specify the SEI and types class search path of directories and zip/jar files.

-soap12

Specifies that the generated WSDL is to include a SOAP 1.2 binding.

-t

Specifies the target namespace to use in the generated WSDL file.

-servicename

Specifies the value of the generated service element‘s name attribute.

-v

Displays the version number for the tool.

-verbose

Displays comments during the code generation process.

-quiet

Suppresses comments during the code generation process.

-s

The directory in which the generated source files(wrapper bean ,fault bean ,client side or server side code) are placed.

-classdir

The directory in which the generated sources are compiled into. If not specified, the files are not compiled.

-portname

Specify the port name to use in the generated wsdl.

-address

Specify the port address.

-beans

Specify the pathname of a file defining additional Spring beans to customize databinding configuration.

-createxsdimports

Output schemas to separate files and use imports to load them instead of inlining them into the wsdl.

-d

The directory in which the resource files are placed, wsdl file will be placed into this directory by default

classname

Specifies the name of the SEI class.

5.1.4 示例

java2ws -wsdl -d ./resources lld.cxf.service.HelloService
java2wsdl -cp ./tmp org.apache.hello_world_soap_http.Greeter
java2wsdl -o hello.wsdl org.apache.hello_world_soap_http.Greeter
java2wsdl -o hello.wsdl -t http://cxf.apache.org org.apache.hello_world_soap_http.Greeter

5.1.5 與 Ant 集成

<?xml version="1.0"?>
<project name="cxf java2ws" basedir=".">   
   <property name="cxf.home" location ="/usr/myapps/cxf-trunk"/>
   <property name="build.classes.dir" location ="${basedir}/build/classes"/>
   <path id="cxf.classpath">
      <pathelement location="${build.classes.dir}"/>
      <fileset dir="${cxf.home}/lib">
         <include name="*.jar"/>
      </fileset>
   </path>
      
   <target name="cxfJavaToWS">
      <java classname="org.apache.cxf.tools.java2ws.JavaToWS" fork="true">
         <arg value="-wsdl"/>
         <arg value="-o"/>
         <arg value="hello.wsdl"/>
         <arg value="service.Greeter"/>
         <classpath>
            <path refid="cxf.classpath"/>
         </classpath>
      </java>
   </target>
</project>

CXF 教程(一)