參考文章:https://spring.io/guides/gs/rest-service/
中文翻譯:https://blog.dubby.cn/detail.html?id=9040
1.目標是什么
構建一個web應用,我們可以請求:
http://localhost:8080/greeting
返回一個JSON
:
{"id":1,"content":"Hello, World!"}
還可以發起一個帶參數的請求:
http://localhost:8080/greeting?name=User
返回一個JSON
:
{"id":1,"content":"Hello, User!"}
2.開始創建
2.1.Maven依賴
新建一個Maven項目
pom.xml文件
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.niiam</groupId> 5 <artifactId>SpringBootRestfulTest</artifactId> 6 7 <version>0.0.1-SNAPSHOT</version> 8 <name>SpringBootRestfulTest Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 11 <parent> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-parent</artifactId> 14 <version>1.5.9.RELEASE</version> 15 </parent> 16 17 <dependencies> 18 <dependency> 19 <groupId>org.springframework.boot</groupId> 20 <artifactId>spring-boot-starter-web</artifactId> 21 </dependency> 22 <dependency> 23 <groupId>org.springframework.boot</groupId> 24 <artifactId>spring-boot-starter-test</artifactId> 25 <scope>test</scope> 26 </dependency> 27 <dependency> 28 <groupId>com.jayway.jsonpath</groupId> 29 <artifactId>json-path</artifactId> 30 <scope>test</scope> 31 </dependency> 32 </dependencies> 33 34 <properties> 35 <java.version>9.0.1</java.version> 36 </properties> 37 38 <build> 39 <finalName>SpringBootRestfulTest</finalName> 40 <plugins> 41 <plugin> 42 <groupId>org.springframework.boot</groupId> 43 <artifactId>spring-boot-maven-plugin</artifactId> 44 </plugin> 45 </plugins> 46 </build> 47 48 <repositories> 49 <repository> 50 <id>spring-releases</id> 51 <url>https://repo.spring.io/libs-release</url> 52 </repository> 53 </repositories> 54 <pluginRepositories> 55 <pluginRepository> 56 <id>spring-releases</id> 57 <url>https://repo.spring.io/libs-release</url> 58 </pluginRepository> 59 </pluginRepositories> 60 </project>
其中,spring-boot-maven-plugin
給我們提供了這么幾個功能:
- 他會把classpath下的jar統一打包成一個可直接運行的”über-jar”,方便我們運行。
- 他會自動搜索
public static void main()
作為程序執行的入口。 - 他內置一個依賴版本決定者。也就是他會指定依賴的版本。當然你也可以指定版本,如果你不指定,默認由他來決定版本。
2.2 實體類
根據
{
"id": 1,
"content": "Hello, World!"
}
來寫出一個表達這個json的bean src/main/java/hello/Greeting.java
1 package hello; 2 3 public class Greeting { 4 private final long id; 5 private final String content; 6 public Greeting(long id, String content) { 7 this.id = id; 8 this.content = content; 9 } 10 public long getId() { 11 return id; 12 } 13 public String getContent() { 14 return content; 15 } 16 }
Spring會使用Jackson JSON自動把Greeting
的實例序列化成JSON
。
2.3 controller
在Spring構建的restful應用中,HTTP請求是由controller接收並處理的。想要創建一個controller可以使用@RestController
修飾一個類,那么這個類就變成了一個controller。一個controller里的每個方法都可以接收一個特定的URI,需要使用@RequestMapping
來修飾每個方法,來制定URI的路徑,參數,方法等。
src/main/java/hello/GreetingController.java
1 package hello; 2 3 import java.util.concurrent.atomic.AtomicLong; 4 import org.springframework.web.bind.annotation.RequestMapping; 5 import org.springframework.web.bind.annotation.RequestParam; 6 import org.springframework.web.bind.annotation.RestController; 7 8 @RestController 9 public class GreetingController { 10 private static final String template = "Hello, %s!"; 11 private final AtomicLong counter = new AtomicLong(); 12 @RequestMapping("/greeting") 13 public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { 14 return new Greeting(counter.incrementAndGet(), 15 String.format(template, name)); 16 } 17 }
這個controller很簡潔明了,但是在背后隱藏了很多事先細節,我們一點點來分解。
@RequestMapping
這個注解確保/greeting
這個HTTP請求會被路由到greeting()
這個方法上來處理。
上面的例子沒有指明
GET
,PUST
或者是PUT
等HTTP方法,因為@RequestMapping
默認是映射所有的方法。如果你只希望某個方法被映射到這個方法,可以使用@RequestMapping(method=GET)
來縮小映射范圍。
@RequestParam
把請求參數中的name
的值綁定到greeting()
的參數name
上。這個參數被標記為可選的,也就是可傳可不傳的,(默認情況下,required=true
是必須要傳的),在這里,如果沒有傳name
,就會使用defaultValue
的值。
greeting()
方法里創建了一個Greeting
對象,然后返回,用一個自增的int作為id
,用name
的值拼接成content
。
傳統的MVC的controller和RESTful的controller的最大的區別就是返回的HTTP的response。傳統的controller返回的是一個由后端渲染的HTML
,而RESTful返回的是一個對象,然后被序列化成JSON
字符串。
@RestController
是Spring4新加的一個注解,用它修飾的controller返回的是一個對象(也就是JSON
),而不是一個視圖(也就是HTML
)。這個注解等同於同時使用@Controller
和@ResponseBody
。
上面提到Spring會自動把對象轉化成JSON
,我們還不需要手動來轉換,那么是誰幫我們做的呢?真相是,只要Jackson 2在classpath下,Spring就會使用MappingJackson2HttpMessageConverter
來自動轉換。
2.4 可執行Jar
雖然也可以打包成傳統的war包然后交給servlet容器來執行,但是更多的時候是打包成一個可以直接執行的Jar。
src/main/java/hello/Application.java
1 package hello; 2 import org.springframework.boot.SpringApplication; 3 import org.springframework.boot.autoconfigure.SpringBootApplication; 4 @SpringBootApplication 5 public class Application { 6 public static void main(String[] args) { 7 SpringApplication.run(Application.class, args); 8 } 9 }
@SpringBootApplication
注解等同於同時使用一下注解:
@Configuration
修飾的類會被作為定義context上下文的bean。@EnableAutoConfiguration
允許Spring從配置文件,其他bean,等各種方式來加載bean。- 一般來說,對於Spirng MVC項目,你需要使用
@EnableWebMvc
,不過對於Spring Boot來說,只要你的classpath里包含spring-webmvc,他就會自動幫你加上這個,比如,設置DispatcherServlet
。 @ComponentScan
告訴Spirng去掃描hello
包下的其他組件,包含controller,service等。
main()
就是這個應用的入口。發現了嗎,整個應用沒有一個XML文件,全部都是Java代碼,沒有任何配置,這就是Spring Boot想帶給你的禮物。
右鍵點擊Application.java,選擇run as->java application,即可啟動服務。
2.5 生成可執行Jar
右鍵點擊項目->run as->Maven Install生成jar包,可能需要在項目設置里將JRE換成JDK
在command line輸入:
java -jar SpringBootRestfulTest.jar
啟動
在瀏覽器中輸入:
http://localhost:8080/greeting?name=wangle
http://localhost:8080/greeting
需注意的是,此處啟動的jar是包含了Tomcat服務器的
如需終止,可參考:如何優雅地停止運行中的內嵌Tomcat的Spring Boot應用 http://jaskey.github.io/blog/2016/04/05/shutdown-spring-boot-application-gracefully/