本指南將引導你完成使用Spring建立「hello world」 RESTful Web服務的過程。html
你將構建一個接受HTTP GET請求的服務:java
http://localhost:8080/greeting
並使用JSON響應表示問候語:git
{"id":1,"content":"Hello, World!"}
你可使用查詢字符串中的可選name
參數自定義問候語:github
http://localhost:8080/greeting?name=User
name
參數值將覆蓋默認值「World」並反映在響應中:web
{"id":1,"content":"Hello, User!"}
請執行如下操做:spring
下載並解壓縮本指南的源存儲庫,或使用Git克隆它:apache
git clone https://github.com/spring-guides/gs-rest-service.git
gs-rest-service/initial
完成後,你能夠根據gs-rest-service/complete
中的代碼檢查結果。json
如今你已經設置了項目和構建系統,你能夠建立Web服務。segmentfault
經過考慮服務交互來開始這個過程。api
該服務將處理/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。@EnableWebMvc
,但Spring Boot會在類路徑上看到spring-webmvc時自動添加它,這會將應用程序標記爲Web應用程序並激活關鍵行爲,例如設置DispatcherServlet
。@ComponentScan
告訴Spring在hello
包中查找其餘組件、配置和服務,容許它找到控制器。main()
方法使用Spring Boot的SpringApplication.run()
方法來啓動應用程序,你是否注意到沒有一行XML?也沒有web.xml文件,此Web應用程序是100%純Java,你無需處理配置任何管道或基礎結構。
你可使用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
字段在每次調用時按預期遞增。