搭建基於CXF的WebService服務器及其應用

因爲即將在項目中使用到web service,所以,我提前學習了下這個東西。

不看不知道,一看嚇一跳。

好久以前學習並使用過的XFire竟然已經和Celtix合併成了CXF,還出了幾個版本。

看來,人還是需要經常關注技術發展的,否則,還真是要掉隊了。

(廢話太多了?那好吧,我開始演示我的小實驗。)

 

首先,下載CXF,官網(http://cxf.apache.org/ ),解壓後,得到以下目錄。

         其中,lib爲jar包,在接下來的工作中需要用到。

 

下面,我們開始建立工程。

一、組建提供WebService的服務器端項目。

     1. 在eclipse/myEclipse中建立web工程cxf2,將CXF_HOME/lib下的所有jar複製到工程的lib中,並添加到buildpath中。

     2. 新建一個新POJO,爲User.Java

package server;

public class User {
    String first;
    String last;
    public String getFirst() {
    return first;
    }
    public void setFirst(String first) {
    this.first = first;
    }
    public String getLast() {
    return last;
    }
    public void setLast(String last) {
    this.last = last;
    }
}

 

     3. 因爲CXF提供的所有webservice都基於接口,所以,新建一個接口UserService。如下:

package server;

import javax.jws.WebService;

@WebService
public interface UserService {
    
    void add(User user);
    
    User[] findAllUsers();
}

其中,@WebService註解是CXF必須的,照搬吧。

 

    4. 新建一個類UserServiceImpl.java,並實現接口UserService。如下:

package server;

import java.util.List;
import java.util.Vector;

import javax.jws.WebService;

import org.apache.log4j.Logger;

@WebService(endpointInterface = "server.UserService",serviceName = "UserService",portName="UserServicePort")
public class UserServiceImpl implements UserService {
    static List<User> UserRepository= new Vector<User>();
    private static Logger log = Logger.getLogger(UserServiceImpl.class);
    {
        log.info("CXF正在初始化 UserServiceImpl.");
    }
    public void add(User user) {
        log.info("CXF正在添加一個用戶: "+user.getFirst()+"."+user.getLast());
        UserRepository.add(user);
    }
    
    public User[] findAllUsers() {
        User[] users= new User[UserRepository.size()];
        UserRepository.toArray(users);
        return users;
    }
}

這裏,註解@WebService(endpointInterface = "server.UserService",serviceName = "UserService",portName="UserServicePort")與上面不一樣,可以省略。

但在複雜的應用中,不能省略,如指定哪些方法可供遠程調用時,需要用到註解。(個人愚見)

 

5.配置web.xml。

(1)在web.xml中添加CXF的配置文件定義。

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/beans.xml</param-value>
 </context-param>

(2)在web.xml中添加如下監聽器和servlet。

<!-- 因爲CXF3.0依賴於spring,需要添加這個listener-->
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>
            org.apache.cxf.transport.servlet.CXFServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/webServices/*</url-pattern>
    </servlet-mapping>

6.建立CXF的配置文件,存放路徑要與web.xml中定義的一致。

<?xml version="1.0" encoding="UTF-8"?>

<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">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <jaxws:endpoint id="userService" implementor="server.UserServiceImpl" address="/userService" />

</beans>

 

經過上面步驟,我們已經完成配置了一個提供webservice的服務器。

啓動tomcat,在瀏覽器中輸入地址:http://localhost:8880/cxf2/webServices/userService,將返回一個wsdl文件(xml)。

(如果是IE,需要查看源文件來查看。如果是firefox,可以直接看到xml代碼。)

更詳細的訪問地址爲:http://localhost:8880/cxf2/webServices/userService?wsdl。

 

工程目錄如圖:

 

二、上面,我們已經成功配置了一個webservice服務器。接下來,我們建立另一個工程來模擬遠程調用webservice。

1.新建一個工程testCxf,將上面服務器工程中的User.java和UserService.java複製到工程testCxf中。

2.新建一個類Client.java,代碼如下:

package server;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

public class Client {
    public static void main(String[] arg){

        JaxWsProxyFactoryBean soapFactoryBean = new JaxWsProxyFactoryBean();
        soapFactoryBean.setAddress("http://localhost:8880/cxf2/webServices/userService");    // 這個就是第一個工程完成後所測試的地址。
        soapFactoryBean.setServiceClass(UserService.class);
        Object o = soapFactoryBean.create();
        UserService userService = (UserService) o;
        User user= new User();
        user.setFirst("James");
        user.setLast("Bond");
        userService.add(user);
        User[] users= userService.findAllUsers();
        for(User u : users){
            System.out.println(u.getFirst()+"."+u.getLast());
        }
    }
}

 

執行這個java類,我們會看到控制檯輸出了相應信息。

CXF正在添加一個用戶: James.Bond                (這個信息爲第一個工程輸出)

James.Bond                                                  (這個信息爲第二個工程輸出)

如果運行多次,在最後一次運行後,將會看到有多個“James.Bond ”被輸出。

由此,我們可以看到,服務器所提供的webservice已經被成功調用。

到此,兩者的通信已經建立,你想做什麼就做什麼吧,盡情發揮你天馬行空的創意。

 

工程目錄如圖:

 

 

需要兩個工程的朋友,可以從這裏下載。

http://download.csdn.net/source/2775877 (服務器端)

http://download.csdn.net/source/2775884 (客戶端)

 

 

後記:

三、由於我們通常不知道提供Web Service的服務器接口及其相關類的代碼,我們也不可能從他人那裏獲得。

對此,CXF提供了一些命令行工具,在CXF_HOME/bin下。

使用wsdl2java,可以根據從服務器返回的wsdl文件生成我們所需要的java接口和相關類。

在上面的工程中,我們可以用以下命令生成JAVA代碼,而不是從第一個工程中複製過來。

wsdl2java -p client http://localhost:8880/cxf2/webServices/userService?wsdl         (需要在cmd窗口中將路徑切換至CXF_HOME/bin下)

(解釋:wsdljava    –p    包路徑    –d    目標文件夾   wsdl 的url地址)


四、需要注意的是,對於接口類和相關類的包路徑,一定要和服務器的一樣,(可以通過第三個步驟知道包路徑)

否則,會出現Unexpected wrapper element {****}addResponse found.……錯誤。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章