使用CXF與Spring整合實現RESTFul WebService

qingyezhu發表於2015-03-12
以下引用與網路中!!!
   
一種軟體架構風格,設計風格而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端和伺服器互動類的軟體。基於這個風格設計的軟體可以更簡潔,更有層次,更易於實現快取等機制。
    REST(英文:Representational State Transfer,簡稱REST)描述了一個架構樣式的網路系統,比如 web 應用程式。它首次出現在 2000 年 Roy Fielding 的博士論文中,他是 HTTP 規範的主要編寫者之一。在目前主流的三種Web服務互動方案中,REST相比於SOAP(Simple Object Access protocol,簡單物件訪問協議)以及XML-RPC更加簡單明瞭,無論是對URL的處理還是對Payload的編碼,REST都傾向於用更加簡單輕量的方法設計和實現。值得注意的是REST並沒有一個明確的標準,而更像是一種設計的風格。
REST是REST之父Roy Thomas創造的,當時提出來了REST的6個特點:客戶端-伺服器的、無狀態的、可快取的、統一介面、分層系統和按需編碼。其具有跨語言和跨平臺的優勢。
    對於資源的具體操作型別,由HTTP動詞表示。
    常用的HTTP動詞有下面五個(括號裡是對應的SQL命令)
 
 
        GET(SELECT):從伺服器取出資源(一項或多項)。
        POST(CREATE):在伺服器新建一個資源。
        PUT(UPDATE):在伺服器更新資源(客戶端提供改變後的完整資源)。
        PATCH(UPDATE):在伺服器更新資源(客戶端提供改變的屬性)。
        DELETE(DELETE):從伺服器刪除資源。
 
      下面是一些例子
        GET /zoos:列出所有動物園
        POST /zoos:新建一個動物園
        GET /zoos/ID:獲取某個指定動物園的資訊
        PUT /zoos/ID:更新某個指定動物園的資訊(提供該動物園的全部資訊)
        PATCH /zoos/ID:更新某個指定動物園的資訊(提供該動物園的部分資訊)
        DELETE /zoos/ID:刪除某個動物園
        GET /zoos/ID/animals:列出某個指定動物園的所有動物
        DELETE /zoos/ID/animals/ID:刪除某個指定動物園的指定動物
 
通過 REST 風格體系架構,請求和響應都是基於資源表示的傳輸來構建的。資源是通過全域性 ID 來標識的,這些 ID 一般使用的是一個統一資源識別符號(URI)。客戶端應用使用 HTTP 方法(如,GET、POST、PUT 或 DELETE)來操作一個或多個資源。通常,GET 是用於獲取或列出一個或多個資源,POST 用於建立,PUT 用於更新或替換,而 DELETE 則用於刪除資源。

例如,GET http://host/context/employees/12345 將獲取 ID 為 12345 的員工的表示。這個響應表示可以是包含詳細的員工資訊的 XML 或 ATOM,或者是具有更好 UI 的 JSP/HTML 頁面。您看到哪種表示方式取決於伺服器端實現和您的客戶端請求的 MIME 型別。

RESTful Web Service 是一個使用 HTTP 和 REST 原理實現的 Web Service。通常,一個 RESTful Web Service 將定義基本資源 URI、它所支援的表示/響應 MIME,以及它所支援的操作。 
參考資料:
1)、使用 Spring 3 來建立 RESTful Web Services(http://www.ibm.com/developerworks/cn/web/wa-spring3webserv/)
2)、Apache CXF與Spring整合實現Soap Webservice與RESTFul WebService(http://blog.csdn.net/javacloudfei/article/details/38555803)
 
本人的例項:
配置pom.xml
 
<properties>
        <spring.version>4.0.5.RELEASE</spring.version>
        <jackson.version>1.9.2</jackson.version>
        <cxf.version>3.0.3</cxf.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    
        <!--spring核心包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    
        <!--JSTL標籤類-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <!--cxf-->
        <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-frontend-jaxrs</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        
        <!--json-->
        <dependency>  
            <groupId>org.codehaus.jackson</groupId>  
            <artifactId>jackson-core-asl</artifactId>  
            <version>${jackson.version}</version>  
        </dependency>  
        <dependency>  
            <groupId>org.codehaus.jackson</groupId>  
            <artifactId>jackson-mapper-asl</artifactId>  
            <version>${jackson.version}</version>  
        </dependency> 
        <dependency>  
            <groupId>org.codehaus.jackson</groupId>  
            <artifactId>jackson-jaxrs</artifactId>  
            <version>${jackson.version}</version>  
        </dependency>  
        <dependency>  
            <groupId>org.codehaus.jackson</groupId>  
            <artifactId>jackson-xc</artifactId>  
            <version>${jackson.version}</version>  
        </dependency>
    </dependencies>

配置application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"   
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd   
    http://www.springframework.org/schema/context   
    http://www.springframework.org/schema/context/spring-context-4.0.xsd ">  

    <!--掃描器-->
    <context:component-scan base-package="com.wangzhu"/>
    
</beans>

 

配置applicationWebService.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"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd   
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.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-extension-jaxrs-binding.xml"/>
        <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>-->
    <jaxrs:server id="webService" address="/">
        <!--輸入攔截器設定-->
        <jaxrs:inInterceptors>
            
        </jaxrs:inInterceptors>

        <!--輸出攔截器設定-->
        <jaxrs:outInterceptors>
            
        </jaxrs:outInterceptors>
        
        <!--serviceBeans:暴露的WebService服務類-->
        <jaxrs:serviceBeans>
            <ref bean="studentService"/>
        </jaxrs:serviceBeans>
            
        <!--支援的協議-->
        <jaxrs:extensionMappings>
            <entry key="json" value="application/json"/>
            <entry key="xml" value="application/xml"/>
        </jaxrs:extensionMappings>
        <!--編碼格式-->
        <jaxrs:languageMappings>
            
        </jaxrs:languageMappings>
        <!--物件轉換-->
        <jaxrs:providers>
            <bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
        </jaxrs:providers>
        
    </jaxrs:server>
</beans>

備註:注意以上檔案中的標記的地方!其中address可以用於指定Web Service的版本!


配置web.xml

<!--全域性配置檔案-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext*.xml</param-value>
    </context-param>
    
    <!--spring的監聽器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!--cxf的Servlet-->
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

    

 

實體類StudentVo .java

package com.wangzhu.vo;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class StudentVo implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -5481609827444603990L;
    private Integer id;
    private String name;
    private Integer age;
    private String desc;
    private Boolean status;

    public StudentVo() {
    }

    public StudentVo(Integer id, String name, Integer age, String desc,
            Boolean status) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.desc = desc;
        this.status = status;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public Boolean getStatus() {
        return status;
    }

    public void setStatus(Boolean status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "{id=" + id + ", name=" + name + ", age=" + age + ", desc="
                + desc + ", status=" + status + "}";
    }

}

 

實體類StudentListVo.java

package com.wangzhu.vo;

import java.io.Serializable;
import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class StudentListVo implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -2200047544608641662L;
    private List<StudentVo> studentList;

    public StudentListVo() {
    }

    public StudentListVo(List<StudentVo> studentList) {
        this.studentList = studentList;
    }

    public List<StudentVo> getStudentList() {
        return studentList;
    }

    public void setStudentList(List<StudentVo> studentList) {
        this.studentList = studentList;
    }

    @Override
    public String toString() {
        return "{studentList=" + studentList + "}";
    }

}

 

資料生成器StudentDateSet.java

package com.wangzhu.dataset;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Component;

import com.wangzhu.vo.StudentVo;

@Component
public class StudentDateSet {
    private static List<StudentVo> list;

    static {
        StudentDateSet.list = new ArrayList<StudentVo>();

        for (int i = 0; i < 10; i++) {
            StudentVo vo = new StudentVo(i, "name" + i, Math.round(100.0f),
                    "desc" + i, (i & 1) == 0);
            StudentDateSet.list.add(vo);
        }
    }

    public static List<StudentVo> getList() {
        return StudentDateSet.list;
    }

}

 

Web Service的介面StudentService.java

package com.wangzhu.service;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.wangzhu.vo.StudentListVo;
import com.wangzhu.vo.StudentVo;

@Path("/studentService")
@Produces(MediaType.APPLICATION_JSON)
public interface StudentService {

	@GET
	@Path("/status")
	public String getStatus();

	@GET
	@Path("/students/{index}")
	public StudentVo getStudentById(@PathParam("index") Integer id);

	@GET
	@Path("/students")
	public StudentListVo getStudentList();
}

 

Web Service的實現類StudentServiceImpl.java

package com.wangzhu.service.impl;

import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.wangzhu.dataset.StudentDateSet;
import com.wangzhu.service.StudentService;
import com.wangzhu.vo.StudentListVo;
import com.wangzhu.vo.StudentVo;

@Component("studentService")
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentDateSet studentDateSet;

    /**
     * url:http://<host>:<port>/<appcontext>/services/studentService/status
     */
    @Override
    @GET
    @Path("/status")
    public String getStatus() {
        return "getStatus";
    }

    /**
     * url:http://<host>:<port>/<appcontext>/services/studentService/students/{
     * index}
     */
    @Override
    @GET
    @Path("/students/{index}")
    public StudentVo getStudentById(@PathParam("index") Integer id) {
        List<StudentVo> studentList = StudentDateSet.getList();
        StudentVo vo = null;
        if (studentList.size() > id) {
            vo = studentList.get(id - 1);
        }
        return vo;
    }

    /**
     * url:http://<host>:<port>/<appcontext>/services/studentService/students
     */
    @Override
    @GET
    @Path("/students")
    public StudentListVo getStudentList() {
        List<StudentVo> studentList = StudentDateSet.getList();
        StudentListVo listVo = new StudentListVo(studentList);
        return listVo;
    }

}


備註:注意以上有標記的studentServiceapplicationWebService.xml中有同名的標記。

 

測試:

在瀏覽器的位址列中輸入:

1、http://<host>:<port>/<appcontext>/services/studentService/students

2、http://<host>:<port>/<appcontext>/services/studentService/students/1

 

 

相關文章