構建一個RESTful Web Service(Building a RESTful Web Service)
本文詳細介紹了基于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