構建一個基於 Spring 的 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。
相關文章
- 基於 Spring Boot 2.0 構建一個 RESTful WebServiceSpring BootRESTWeb
- 構建WCF RESTful service示例REST
- [beego新手入門]基於web框架-beego的RESTful API的構建之旅GoWeb框架RESTAPI
- 什麼是web service?- SOAP Web Service & Restful Web ServiceWebREST
- RESTful Web Service(續)RESTWeb
- Apache CXF實現Web Service(2)——不借助重量級Web容器和Spring實現一個純的JAX-RS(RESTful) web serviceApacheWebSpringREST
- 構建第一個基於 Gradle 的 Spring Boot 專案GradleSpring Boot
- 基於Grunt構建一個的專案
- spring boot構建restful服務Spring BootREST
- 基於Grunt構建一個JavaScript庫JavaScript
- Spring Boot實戰:Restful API的構建Spring BootRESTAPI
- 構建一個完整的基於Python3的Web開發環境PythonWeb開發環境
- 使用 Spring 3 MVC HttpMessageConverter 功能構建 RESTful web 服務SpringMVCHTTPRESTWeb
- 使用 Python 構建一個簡單的 RESTful APIPythonRESTAPI
- Apache CXF實現Web Service(4)——Tomcat容器和Spring實現JAX-RS(RESTful) web serviceApacheWebTomcatSpringREST
- 構建一個基於容器的開發環境開發環境
- SpringMVC+Json構建基於Restful風格的應用SpringMVCJSONREST
- 基於Spring的Restful介面生成工具SpringREST
- Spring系列:基於XML的方式構建IOCSpringXML
- 構建基於Spring4的Rest APISpringRESTAPI
- 使用ASP.NET Web API構建RESTful APIASP.NETWebAPIREST
- Spring Boot 構建 Restful API 和測試Spring BootRESTAPI
- 從零構建一個基於Docker的Laravel應用DockerLaravel
- Spring Cloud雲架構-Restful 基礎架構SpringCloud架構REST
- 基於 Stencil 構建 Web Components 元件庫Web元件
- Spring MVC之基於java config無xml配置的web應用構建SpringMVCJavaXMLWeb
- Apache CXF實現Web Service(3)——Tomcat容器和不借助Spring的普通Servlet實現JAX-RS(RESTful) web serviceApacheWebTomcatSpringServletREST
- 如何構建一個WEB同構應用Web
- Flask 系列 - 基於 Flask 提供 RESTful Web 服務FlaskRESTWeb
- 深入淺出Spring Web MVC:從零開始構建你的第一個Web應用SpringWebMVC
- Spring Web Service教程SpringWeb
- 使用 Jersey 和 Apache Tomcat 構建 RESTful Web 服務ApacheTomcatRESTWeb
- CXF+Spring+JAXB+Json構建Restful服務SpringJSONREST
- 使RESTful Web服務更加實用的10個建議RESTWeb
- 用 GIN 構建一個 WEB 服務Web
- 使用Beego構建一個web專案GoWeb
- Apache CXF實現Web Service(1)——不借助重量級Web容器和Spring實現一個純的JAX-WS web serviceApacheWebSpring
- 測試必須學spring RESTful Service(上)SpringREST