歡迎大家回到《Java教程之Spring30天快速入門》,本教程所有示例均基于Maven實現(xiàn),如果您對Maven還很陌生,請移步本人的博文《如何在windows11下安裝Maven并配置以及 IDEA配置Maven環(huán)境》,本文的上一篇為《SpringMVC 之 服務器響應》
1 REST簡介
REST(Representational State Transfer),表現(xiàn)形式狀態(tài)轉(zhuǎn)換,它是一種軟件架構風格當我們想表示一個網(wǎng)絡資源的時候,可以使用兩種方式:
- 傳統(tǒng)風格資源描述形式
- http://localhost/user/getById?id=1 查詢id為1的用戶信息
- http://localhost/user/saveUser 保存用戶信息
- REST風格描述形式
- http://localhost/user/1
- http://localhost/user
傳統(tǒng)方式一般是一個請求url對應一種操作,這樣做不僅麻煩,也不安全,因為會程序的人讀取了你的請求url地址,就大概知道該url實現(xiàn)的是一個什么樣的操作。
查看REST風格的描述,你會發(fā)現(xiàn)請求地址變的簡單了,并且光看請求URL并不是很能猜出來該URL的具體功能
所以REST的優(yōu)點有:
- 隱藏資源的訪問行為,無法通過地址得知對資源是何種操作
- 書寫簡化
但是我們的問題也隨之而來了,一個相同的url地址即可以是新增也可以是修改或者查詢,那么到底我們該如何區(qū)分該請求到底是什么操作呢?
- 按照REST風格訪問資源時使用行為動作區(qū)分對資源進行了何種操作
- http://localhost/users 查詢?nèi)坑脩粜畔?GET(查詢)
- http://localhost/users/1 查詢指定用戶信息 GET(查詢)
- http://localhost/users 添加用戶信息 POST(新增/保存)
- http://localhost/users 修改用戶信息 PUT(修改/更新)
- http://localhost/users/1 刪除用戶信息 DELETE(刪除)
請求的方式比較多,但是比較常用的就4種,分別是GET , POST , PUT , DELETE。
按照不同的請求方式代表不同的操作類型。
- 發(fā)送GET請求是用來做查詢
- 發(fā)送POST請求是用來做新增
- 發(fā)送PUT請求是用來做修改
- 發(fā)送DELETE請求是用來做刪除
但是注意:
- 上述行為是約定方式,約定不是規(guī)范,可以打破,所以稱REST風格,而不是REST規(guī)范
- REST提供了對應的架構方式,按照這種架構設計項目可以降低開發(fā)的復雜性,提高系統(tǒng)的可伸縮性
- REST中規(guī)定GET/POST/PUT/DELETE針對的是查詢/新增/修改/刪除,但是我們?nèi)绻且肎ET請求做刪除,這點在程序上運行是可以實現(xiàn)的
- 但是如果絕大多數(shù)人都遵循這種風格,你寫的代碼讓別人讀起來就有點莫名其妙了。描述模塊的名稱通常使用復數(shù),也就是加s的格式描述,表示此類資源,而非單個資源,例如:users、books、accounts…
清楚了什么是REST風格后,我們后期會經(jīng)常提到一個概念叫RESTful,那什么又是RESTful呢?
- 根據(jù)REST風格對資源進行訪問稱為RESTful。
后期我們在進行開發(fā)的過程中,大多是都是遵從REST風格來訪問我們的后臺服務,所以可以說咱們以后都是基于RESTful來進行開發(fā)的。
2 RESTful入門案例
2.1 環(huán)境準備
- 創(chuàng)建一個Web的Maven項目
- pom.xml添加Spring依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>springmvc_06_rest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 創(chuàng)建對應的配置類
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
//亂碼處理
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
@Configuration
@ComponentScan("com.itheima.controller")
//開啟json數(shù)據(jù)類型自動轉(zhuǎn)換
@EnableWebMvc
public class SpringMvcConfig {
}
- 編寫模型類User和Book
public class User {
private String name;
private int age;
//getter...setter...toString省略
}
public class Book {
private String name;
private double price;
//getter...setter...toString省略
}
- 編寫UserController和BookController
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(@RequestBody User user) {
System.out.println("user save..."+user);
return "{'module':'user save'}";
}
@RequestMapping("/delete")
@ResponseBody
public String delete(Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
@RequestMapping("/update")
@ResponseBody
public String update(@RequestBody User user) {
System.out.println("user update..." + user);
return "{'module':'user update'}";
}
@RequestMapping("/getById")
@ResponseBody
public String getById(Integer id) {
System.out.println("user getById..." + id);
return "{'module':'user getById'}";
}
@RequestMapping("/findAll")
@ResponseBody
public String getAll() {
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
@Controller
public class BookController {
@RequestMapping(value = "/books",method = RequestMethod.POST)
@ResponseBody
public String save(@RequestBody Book book){
System.out.println("book save..." + book);
return "{'module':'book save'}";
}
@RequestMapping(value = "/books/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("book delete..." + id);
return "{'module':'book delete'}";
}
@RequestMapping(value = "/books",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody Book book){
System.out.println("book update..." + book);
return "{'module':'book update'}";
}
@RequestMapping(value = "/books/{id}",method = RequestMethod.GET)
@ResponseBody
public String getById(@PathVariable Integer id){
System.out.println("book getById..." + id);
return "{'module':'book getById'}";
}
@RequestMapping(value = "/books",method = RequestMethod.GET)
@ResponseBody
public String getAll(){
System.out.println("book getAll...");
return "{'module':'book getAll'}";
}
}
最終創(chuàng)建好的項目結構如下:
2.2 思路分析
需求:將之前的增刪改查替換成RESTful的開發(fā)方式。
1.之前不同的請求有不同的路徑,現(xiàn)在要將其修改為統(tǒng)一的請求路徑
修改前: 新增: /save ,修改: /update,刪除 /delete…
修改后: 增刪改查: /users
2.根據(jù)GET查詢、POST新增、PUT修改、DELETE刪除對方法的請求方式進行限定
3.發(fā)送請求的過程中如何設置請求參數(shù)?
2.3 修改RESTful風格
新增
@Controller
public class UserController {
//設置當前請求方法為POST,表示REST風格中的添加操作
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save() {
System.out.println("user save...");
return "{'module':'user save'}";
}
}
- 將請求路徑更改為/users
- 訪問該方法使用 POST: http://localhost/users
- 使用method屬性限定該方法的訪問方式為POST
- 如果發(fā)送的不是POST請求,比如發(fā)送GET請求,則會報錯
刪除
- 如果發(fā)送的不是POST請求,比如發(fā)送GET請求,則會報錯
@Controller
public class UserController {
//設置當前請求方法為DELETE,表示REST風格中的刪除操作
@RequestMapping(value = "/users",method = RequestMethod.DELETE)
@ResponseBody
public String delete(Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
}
- 將請求路徑更改為/users
- 訪問該方法使用 DELETE: http://localhost/users
訪問成功,但是刪除方法沒有攜帶所要刪除數(shù)據(jù)的id,所以針對RESTful的開發(fā),如何攜帶數(shù)據(jù)參數(shù)?
傳遞路徑參數(shù)
前端發(fā)送請求的時候使用: http://localhost/users/1 ,路徑中的1就是我們想要傳遞的參數(shù)。
后端獲取參數(shù),需要做如下修改:
- 修改@RequestMapping的value屬性,將其中修改為/users/{id},目的是和路徑匹配
- 在方法的形參前添加@PathVariable注解
@Controller
public class UserController {
//設置當前請求方法為DELETE,表示REST風格中的刪除操作
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
}
思考如下兩個問題:
(1)如果方法形參的名稱和路徑{}中的值不一致,該怎么辦?
(2)如果有多個參數(shù)需要傳遞該如何編寫?
前端發(fā)送請求的時候使用: http://localhost/users/1/tom ,路徑中的1和tom就是我們想要傳遞的
兩個參數(shù)。
后端獲取參數(shù),需要做如下修改:
@Controller
public class UserController {
//設置當前請求方法為DELETE,表示REST風格中的刪除操作
@RequestMapping(value = "/users/{id}/{name}",method =
RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id,@PathVariable String name)
{
System.out.println("user delete..." + id+","+name);
return "{'module':'user delete'}";
}
}
修改
@Controller
public class UserController {
//設置當前請求方法為PUT,表示REST風格中的修改操作
@RequestMapping(value = "/users",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user) {
System.out.println("user update..." + user);
return "{'module':'user update'}";
}
}
- 將請求路徑更改為/users
- 訪問該方法使用 PUT: http://localhost/users
- 訪問并攜帶參數(shù):
根據(jù)ID查詢
@Controller
public class UserController {
//設置當前請求方法為GET,表示REST風格中的查詢操作
@RequestMapping(value = "/users/{id}" ,method = RequestMethod.GET)
@ResponseBody
public String getById(@PathVariable Integer id){
System.out.println("user getById..."+id);
return "{'module':'user getById'}";
}
}
將請求路徑更改為/users
- 訪問該方法使用 GET: http://localhost/users/666
查詢所有
@Controller
public class UserController {
//設置當前請求方法為GET,表示REST風格中的查詢操作
@RequestMapping(value = "/users" ,method = RequestMethod.GET)
@ResponseBody
public String getAll() {
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
將請求路徑更改為/users
- 訪問該方法使用 GET: http://localhost/users
小結
RESTful入門案例,我們需要學習的內(nèi)容如下:
(1)設定Http請求動作(動詞)
@RequestMapping(value=“”,method = RequestMethod.POST|GET|PUT|DELETE)
(2)設定請求參數(shù)(路徑變量)
@RequestMapping(value=“/users/{id}”,method = RequestMethod.DELETE)
@ReponseBody
public String delete(@PathVariable Integer id){
}文章來源:http://www.zghlxwxcb.cn/news/detail-762240.html
3 知識點總結
知識點1:@PathVariable
關于接收參數(shù),我們學過三個注解@RequestBody、@RequestParam、@PathVariable ,這三個注解之間的區(qū)別和應用分別是什么?文章來源地址http://www.zghlxwxcb.cn/news/detail-762240.html
- 區(qū)別
- @RequestParam用于接收url地址傳參或表單傳參
- @RequestBody用于接收json數(shù)據(jù)
- @PathVariable用于接收路徑參數(shù),使用{參數(shù)名稱}描述路徑參數(shù)
- 應用
- 后期開發(fā)中,發(fā)送請求參數(shù)超過1個時,以json格式為主,@RequestBody應用較廣
- 如果發(fā)送非json格式數(shù)據(jù),選用@RequestParam接收請求參數(shù)
- 采用RESTful進行開發(fā),當參數(shù)數(shù)量較少時,例如1個,可以采用@PathVariable接收請求路徑變量,通常用于傳遞id值
到了這里,關于【Spring教程30】Spring框架實戰(zhàn):從零開始學習SpringMVC 之 Rest風格簡介與RESTful入門案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!