構建一個RESTful Web Service(Building a RESTful Web Service)

jopen 8年前發布 | 17K 次閱讀 Java開發

本文詳細介紹了基于Spring創建一個“hello world” RESTful web service工程的步驟。

目標

構建一個service,接收如下HTTP GET請求:

http://localhost:8080/greeting

并返回如下JSON格式的問候語:

{"id":1,"content":"Hello, World!"}

你也可以通過指定查詢字符串中的可選參數name來定制問候語:

http://localhost:8080/greeting?name=User

參數name的值覆蓋了默認值“World”,得到的響應為:

{"id":1,"content":"Hello, User!"}

準備工作

  • 大約15分鐘
  • 一個文本編輯器或IDE
  • JDK1.6或更高
  • Gradle 1.8+或Maven 3.0+
  • 你也可以使用STS(Spring Tool Suite)直接import該工程

如何完成

如同所有的Spring入門教程,你可以選擇一步一步的自己實現,也可以跳過基本的設置步驟。最終,你都將得到一份可以正常運行的代碼。

如果選擇按步實現,繼續下一節。

如果選擇跳過基本的安裝部分,則執行以下命令從github獲取代碼:

git clone https://github.com/spring-guides/gs-rest-service.git

切換當前目錄到gs-rest-service/initial,跳到 Create a resource representation class步驟

完成后,可以與gs-rest-service/complete中的代碼對比一下,確保正確。

建立工程

首先建立一個基本的構建腳本。基于Spring構建應用時,可以用使用任何的構建系統。這里我們以Gradle和Maven為例。如果不熟悉它們,請參考Building Java Projects with Gradle或者Building Java Projects with Maven

建立目錄結構

在你選定的工程目錄下,建立如下子目錄結構;例如,在*nix系統中使用mkdir -p src/main/java/hello命令:

└── src
    └── main
        └── java
            └── hello

創建Gradle構建文件

下面是初始的gradle構建文件。你也可以使用Maven,Maven的配置文件pom.xml可以參考這里。如果你使用STS(Spring Tool Suite),可以直接導入該工程。

build.gradle

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-snapshot" }
        mavenLocal()
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'

jar {
    baseName = 'gs-rest-service'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
    maven { url "http://repo.spring.io/libs-snapshot" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:1.0.0.RC1")
    compile("com.fasterxml.jackson.core:jackson-databind")
    testCompile("junit:junit:4.11")
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.8'
}
注意:本文使用了Spring Boot

創建資源描述類(Create a resource representation class)

現在已經建立了工程和構建系統,下面創建你的web service。

首先考慮服務間的交互(service interactions)。

這個服務要處理/greeting的GET請求,其查詢字符串包含一個可選的name參數。這個GET請求應該一個200 OK的響應,以及JSON結構的描述問候語的內容。格式如下:

{
    "id": 1,
    "content": "Hello, World!"
}

id域是問候語的唯一標識,content域是問候語的文本描述。

為了對問候語的描述進行建模,創建了一個資源描述類。提供了一個包含域(id和content)、構造方法和訪問器(getter和setter)的pojo(pain old java object)類:

src/main/java/hello/Greeting.java

package hello;

public class Greeting {

    private final long id;
    private final String content;

    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }
}

注意:下面的步驟中,Spring使用了Jackson JSON庫將Greeting類型的實例編碼成JSON格式。

下面創建資源控制器(resource controller)來發送這些問候語。

創建資源控制器(Create a resource controller)

采用Spring構建RESTful web services時,采用控制器處理HTTP請求。控制器組件通過@Controller注解來標識,下面的GreetingController類處理/greeting的GET請求,并返回一個Greeting類的新的實例:

src/main/java/hello/GreetingController.java

package hello;

import java.util.concurrent.atomic.AtomicLong;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public @ResponseBody Greeting greeting(
            @RequestParam(value="name", required=false, defaultValue="World") String name) {
        return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
    }
}

這個controller很簡單,但是其內部做了大量工作,麻雀雖小,五臟俱全。我們一步一步的解釋。

@RequestMapping注解確保對/greeting的HTTP請求映射到greeting()方法。

注意:上述例子中沒有寫明GET、PUT、POST等等。這是因為@RequestMapping注解默認情況下映射所有的HTTP操作。使用@RequestMapping(method=GET)指定只映射GET請求。

@RequestParam把查詢字符串中name參數的值綁定到greeting()方法的name參數上。該查詢參數不是必須的(required=false);如果請求時沒有指定該參數,則使用其默認值“World”(defaultValue)。

方法體的實現創建并返回了一個新的Greeting對象,該對象的id屬性每次自增1,content屬性采用template和name組合而來。

傳統的MVC控制器和上述RESTful web service控制器的一個關鍵區別在于:HTTP響應體的創建方式。前者采用視圖層技術(view technology)實現把服務器端的數據渲染為HTML,后者則返回一個Greeting對象。對象數據將會直接以JSON格式寫到HTTP響應中。

通過以下方式實現上述功能,greeting()方法的@ResponseBody注解告訴Spring MVC不需要使用服務器端視圖層渲染問候語對象(the greeting object),取而代之的是,返回的問候語對象時一個response body,而且應該直接寫出。

Greeting對象必須轉換成JSON格式。由于Spring支持HTTP報文轉換,你不需要手工進行轉換。由于Jackson 2在classpath中,因而Spring的MappingJackson2HttpMessageConverter會自動將Greeting實例轉換為JSON格式。

Make the application executable

雖然可以將這個service打包成傳統的WAR文件,并部署到一個外部的應用服務器上,但是我們采用了一個更簡單的方式:創建一個獨立的(standalone)應用程序。把所有文件打包到一個可執行的JAR文件中,由古老的main()方法驅動。采用Spring提供的嵌入的Tomcat Servlet容器作為HTTP運行時環境,不需要部署一個外部的運行時環境實例。

src/main/java/hello/Application.java

package hello;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

main()方法調用了SpringApplication幫助類,把Application.class傳遞給它的run()方法作為參數。這樣Spring就會去從Application讀取注解,并作為Spring application context的一個組件進行管理。

@ComponentScan注解告訴Spring遞歸地搜索hello包和其子包中直接或間接標記為@Component的類。這確保Spring發現并注冊GreetingController,由于它被標記為@Controller,而@Controller是一類@Component注解。

@EnableAutoConfiguration注解基于你的classpath的內容打開合理的默認行為。例如,由于應用程序依賴于嵌入版的Tomcat(tomcat-embed-core.jar),一個Tomcat服務器會自動建立并進行合理的默認配置。應用程序也依賴于Spring MVC(spring-webmvc.jar),一個Spring MVC DispatcherServlet會為你配置和注冊--不需要web.xml!自動配置(Auto-configuration)是一種強大的靈活的機制。詳請參考API文檔

構建可執行JAR(Build an executable JAR)

目前位置,Application類已經寫完,下面通過構建系統把所有文件打包為一個可執行jar文件。這將便于對這個service在多種不同環境中進行發布、版本控制和部署。

下面是采用Gradle的步驟,如果采用Maven,可以在這里找到pom.xml文件,執行mvn clean package構建工程。

更新build.gradle文件的buildscript部分,如下:

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-snapshot" }
        mavenLocal()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC1")
    }
}

再在build.gradle中添加如下語句:

apply plugin: 'spring-boot'

可以在這里看到最終版本的build.gradle文件。

Spring Boot gradle plugin收集classpath中的所有jar包,并構建一個單獨的uber-jar,這使得更加便于執行和傳輸你的service。它也搜索public static void main()方法標志為一個可執行類。

下面執行如下命令生成一個單獨的可執行JAR文件,該JAR文件包含所有必需的依賴的類和資源:

./gradlew build

如果你使用Gradle,可以使用如下語句執行生成的JAR文件:

java -jar build/libs/gs-rest-service-0.1.0.jar

如果使用Maven,使用如下語句:

java -jar target/gs-rest-service-0.1.0.jar

注意:上述過程將生成一個可執行JAR。你也可以選擇構建一個WAR文件

執行(Run the service)

如果采用Gradle,可以在命令行中執行如下命令來運行你的service:

./gradlew clean build && java -jar build/libs/gs-rest-service-0.1.0.jar

注意:如果采用Maven,可以執行如下語句mvn clean package && java -jar target/gs-rest-service-0.1.0.jar

日志輸出。service將會啟動并在數秒鐘內運行。

測試(Test the service)

現在service已經啟動,訪問http://localhost:8080/greeting,你會看到:

{"id":1,"content":"Hello, World!"}

查詢字符串中指定一個name參數,如http://localhost:8080/greeting?name=User。content的值從“Hello, World!”變為“Hello, User!”:

{"id":2,"content":"Hello, User!"}

這說明GreetingController類中的@RequestParam注解起作用了。name參數給定的默認值為“World”,但是可以通過在查詢字符串中設定值覆蓋它。

注意id屬性從1變為2。這表明你在多次請求中訪問了同一個GreetingController實例,它的counter域每次訪問時會自增1。

小結(Summary)

恭喜!你已經開發出了一個基于Spring的RESTful web service。


英文原文:Building a RESTful Web Service

來自: http://blog.csdn.net//kingzone_2008/article/details/18793237

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!