Spring 指南(構建RESTful Web服務)
構建RESTful Web服務
本指南將引導你完成使用Spring建立“hello world”RESTful Web服務的過程。
將要構建什麼
你將構建一個接受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
- JDK 1.8 或更高版本
- Gradle 4+ 或Maven 3.2+
-
你還可以將程式碼直接匯入IDE:
- Spring Tool Suite(STS)
- IntelliJ IDEA
如何完成本指南
請執行以下操作:
-
下載 並解壓縮本指南的源儲存庫,或使用Git克隆它:
git clone https://github.com/spring-guides/gs-rest-service.git
-
進入
gs-rest-service/initial
完成後,你可以根據gs-rest-service/complete
中的程式碼檢查結果。
建立資源表示類
現在你已經設定了專案和構建系統,你可以建立Web服務。
通過考慮服務互動來開始這個過程。
該服務將處理/greeting
的GET
請求,可選地在查詢字串中使用name
引數,GET
請求應返回200 OK
響應,其中JSON位於表示問候語的正文中,它應該看起來像這樣:
{ "id": 1, "content": "Hello, World!" }
id
欄位是問候語的唯一識別符號,content
是問候語的文字表示。
要為問候語表示建模,需要建立一個資源表示類,提供一個普通的java物件,其中包含id
和content
資料的欄位、建構函式和訪問器:
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。
接下來,你將建立將為這些問候語提供服務的資源控制器。
建立資源控制器
在Spring構建RESTful Web服務的方法中,HTTP請求由控制器處理,這些元件可以通過@RestController
註解輕鬆被識別,下面的GreetingController
通過返回Greeting
類的新例項來處理/greeting
的GET
請求:
src/main/java/hello/GreetingController.java
package hello; import java.util.concurrent.atomic.AtomicLong; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class GreetingController { private static final String template = "Hello, %s!"; private final AtomicLong counter = new AtomicLong(); @RequestMapping("/greeting") public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { return new Greeting(counter.incrementAndGet(), String.format(template, name)); } }
這個控制器簡潔並簡單,但它的內部有很多東西,讓我們一步一步地分解它。
@RequestMapping
註解確保對/greeting
的HTTP請求對映到greeting()
方法。
上面的示例未指定GET
與PUT
、POST
等,因為@RequestMapping
預設對映所有HTTP操作,使用@RequestMapping(method=GET)
縮小此對映範圍。
@RequestParam
將查詢字串引數name
的值繫結到greeting()
方法的name
引數中,如果請求中不存在name
引數,則使用“World”的defaultValue
。
方法體的實現基於counter
的下一個值和使用問候語template
格式化給定name
建立並返回具有id
和content
屬性的新Greeting
物件。
傳統MVC控制器和上面的RESTful Web服務控制器之間的關鍵區別在於建立HTTP響應體的方式,這個RESTful Web服務控制器只是填充並返回一個Greeting
物件,而不是依賴於檢視技術來執行問候資料到HTML的伺服器端渲染,物件資料將作為JSON直接寫入HTTP響應。
此程式碼使用Spring 4的新@RestController
註解,它將類標記為控制器,其中每個方法都返回一個域物件而不是一個檢視,這是@Controller
和@ResponseBody
彙總在一起的簡寫。
Greeting
物件必須轉換為JSON,由於Spring的HTTP訊息轉換器支援,你無需手動執行此轉換,因為Jackson 2
在類路徑上,所以會自動選擇Spring的
MappingJackson2HttpMessageConverter
將Greeting
例項轉換為JSON。
使應用程式可執行
雖然可以將此服務打包為傳統的WAR檔案以便部署到外部應用程式伺服器,但下面演示的更簡單的方法建立了一個獨立的應用程式,將所有內容打包在一個可執行的JAR檔案中,由Java的main()
方法驅動,在此過程中,你使用Spring的支援將Tomcat servlet容器嵌入為HTTP執行時,而不是部署到外部例項。
src/main/java/hello/Application.java
package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
@SpringBootApplication
是一個方便的註解,添加了以下所有內容:
-
@Configuration
將類標記為應用程式上下文的bean定義源。 -
@EnableAutoConfiguration
告訴Spring Boot根據類路徑設定、其他bean和各種屬性設定開始新增bean。 -
通常你會為Spring MVC應用新增
@EnableWebMvc
,但Spring Boot會在類路徑上看到spring-webmvc 時自動新增它,這會將應用程式標記為Web應用程式並激活關鍵行為,例如設定DispatcherServlet
。 -
@ComponentScan
告訴Spring在hello
包中查詢其他元件、配置和服務,允許它找到控制器。
main()
方法使用Spring Boot的SpringApplication.run()
方法來啟動應用程式,你是否注意到沒有一行XML?也沒有web.xml
檔案,此Web應用程式是100%純Java,你無需處理配置任何管道或基礎結構。
構建可執行的JAR
你可以使用Gradle或Maven從命令列執行該應用程式,或者,你可以構建一個包含所有必需依賴項、類和資源的可執行JAR檔案,並執行它,這使得在整個開發生命週期中、跨不同環境等將服務作為應用程式釋出、版本和部署變得容易。
如果你使用的是Gradle,則可以使用./gradlew bootRun
執行該應用程式,或者你可以使用./gradlew build
構建JAR檔案,然後你可以執行JAR檔案:
java -jar build/libs/gs-rest-service-0.1.0.jar
如果你使用的是Maven,則可以使用./mvnw spring-boot:run
執行該應用程式,或者你可以使用./mvnw clean package
構建JAR檔案,然後你可以執行JAR檔案:
java -jar target/gs-rest-service-0.1.0.jar
上面的過程將建立一個可執行的JAR,你也可以選擇構建經典WAR檔案。
顯示日誌輸出,該服務應在幾秒內啟動並執行。
測試服務
現在服務已啟動,請訪問http://localhost :8080/greeting,你將看到:
{"id":1,"content":"Hello, World!"}
使用http://localhost
:8080/greeting?name=User提供name
查詢字串引數,注意content
屬性的值是如何從“Hello, World!”改變為“Hello, User!”:
{"id":2,"content":"Hello, User!"}
此更改表明GreetingController
中的@RequestParam
正在按預期工作,name
引數的預設值為“World”,但始終可以通過查詢字串顯式覆蓋。
另請注意id
屬性如何從1
更改為2
,這證明你正在針對相同的GreetingController例項跨多個請求,並且其counter
欄位在每次呼叫時按預期遞增。