SpringMVC @RequestMapping的使用演示和細(xì)節(jié)展示
一、@RequestMapping是什么?
(1) @RequestMapping注解 用于將瀏覽器發(fā)來的 HTTP 請求映射到具體的 Controller類 或者 某個方法上。
(2) @RequestMapping 定義了請求的 URL 路徑、請求使用的 HTTP 方法(GET, POST 等)、請求的參數(shù)、請求頭等匹配條件。
(3)@RequestMapping 既可以在類級別使用,定義指定類的所有方法共享的基礎(chǔ)路徑;也可以在方法級別使用,定義具體處理請求的路徑;還可以同時在類和方法級別上使用,并且,當(dāng)同時修飾類和方法時,請求的 url 就是它們的組合—— /類請求值/方法請求值,具體應(yīng)該為——http://IP[域名]:port/WEB工程路徑/類請求值/方法請求值。
二、@RequestMapping 的使用演示
1.@RequestMapping在方法上的使用:
我們在 “SpringMVC 執(zhí)行流程分析” 一文中已經(jīng)演示過 @RequestMapping 在方法上的使用了,具體請見鏈接文章的 “快速入門” 部分。如下圖所示:

2.@RequestMapping同時在類和方法上使用:
我們在 “SpringMVC 執(zhí)行流程分析” 一文中已經(jīng)配置過 applicationContext-mvc.xml 和 web.xml。
這里以 “購買商品并提示購買成功” 的小demo進(jìn)行演示:先來準(zhǔn)備一個 Controller 或者說是 Handler,OrderHandler代碼如下:
package com.cyan.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @author : Cyan_RA9
* @version : 22.0
*/
@RequestMapping(value = "/order")
@Controller
public class OrderHandler {
/**
* 1. method=RequestMethod.POST: 表示請求 purchase 目標(biāo)方法的請求方式必須是 post
* 2. SpringMVC 控制器默認(rèn)支持 GET 和 POST 兩種方式,(如果不指定默認(rèn)就是這兩個)
*/
@RequestMapping(value = "/purchase", method = RequestMethod.POST)
public String purchase() {
System.out.println("make a purchase of goods~~~");
return "purchase_OK";
}
}可以看到,OrderHandler 和 purchase() 方法上面都用了 @RequestMapping 進(jìn)行修飾,如果想訪問 purcahse方法,正確的 URL 就應(yīng)該是 http://localhost:8080/SpringMVC/order/purchase。
注意,此處我們將 @RequestMapping的method屬性指定為了 POST,其實一共有八種類型(常用的有GET,POST,PUT,DELETE,HEAD這些),如下圖所示:

通過一個 form 表單來訪問這個URL,并且指定為 post 類型,testPurchase.jsp代碼如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>BUY_GOODS</title>
<style>
/* 給表格和所有單元格設(shè)置邊框 */
table, th, td {
border: 1px solid black;
}
table {
border-collapse: collapse;
padding: 2px;
}
th {
font-weight: bold;
border: 2px solid blue;
}
</style>
</head>
<body>
<form action="order/purchase" method="post"> <!-- order前面不帶/ -->
<table class="my-table">
<tr>
<th colspan="2">Buy Goods</th>
</tr>
<tr>
<td>buyerName: </td>
<td><input type="text" name="buyerName"/></td>
</tr>
<tr>
<td>amount: </td>
<td><input type="text" name="amount"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Purchase"/></td>
</tr>
</table>
</form>
</body>
</html>表單效果圖如下:

再來一個 purchase_OK 頁面,對應(yīng) OrderHandler 的purchase()方法的 return "purchase_OK"。purchase_OK.jsp代碼如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Successfully</title>
</head>
<body>
<h3>Purchase Successfully!</h3>
</body>
</html>purchase_OK 頁面效果圖如下:

最后進(jìn)行運行測試,運行結(jié)果如下GIF圖所示:

注意,由于我們在OrderHandler中指定了請求方式為 POST類型,所以如果我們將 form表單 的method屬性改為 get,如下圖所示:

此時form表單的請求類型和要訪問的purchase()方法指定的請求類型不一致,將會報錯405,如下圖所示:

3.@RequestMapping指定請求參數(shù):
@RequestMapping 中的 params 屬性可以用于指定請求參數(shù),如下圖所示:

params 具體的使用方式有下面幾種——
①params = "param1_name" : 表示請求必須包含名稱是 "param1_name" 的請求參數(shù)。
② params = "param1_name!=value1":表示請求必須包含名稱是 "param1_name" 的請求參數(shù) 并且 它的值不可以是 value1(手動指定)。
③ params = "!=param1_name":表示請求必須 不包含 參數(shù)名稱為 "param1_name" 的請求參數(shù)。
④ params = { "param1_name=value1", "param2_name" } :表示請求必須同時包含名稱為 "param1_name" 和 "param2_name" 的請求參數(shù) 并且 param1_name 參數(shù)的值必須是指定的 value1。
以 “保存訂單” 的demo來測試 params 的具體用法。在OrderHandler中新增一個saveOrder 方法,OrderHandler類代碼如下:
package com.cyan.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @author : Cyan_RA9
* @version : 22.0
*/
@RequestMapping(value = "/order")
@Controller
public class OrderHandler {
/**
* 1. method=RequestMethod.POST: 表示請求 purchase 目標(biāo)方法的請求方式必須是 post
* 2. SpringMVC 控制器默認(rèn)支持 GET 和 POST 兩種方式,(如果不指定默認(rèn)就是這兩個)
*/
@RequestMapping(value = "/purchase", method = RequestMethod.POST)
public String purchase() {
System.out.println("make a purchase of goods~~~");
return "purchase_OK";
}
@RequestMapping(value = "/save", params = "orderId!=0", method = RequestMethod.GET)
public String saveOrder(String orderId) {
// 傳入的參數(shù)會傳遞到方法的形參列表
System.out.println("orderId = " + orderId);
return "order_OK";
}
}對應(yīng)的order_OK.jsp代碼如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SuccessfullyEX</title>
</head>
<body>
<h3 style="color: cornflowerblue">Order Successfully!</h3>
</body>
</html>再來一個用于測試 /order/save 的form表單,testOrder.jsp代碼如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SAVE_ORDERS</title>
<style>
/* 給表格和所有單元格設(shè)置邊框 */
table, th, td {
border: 1px solid black;
}
table {
border-collapse: collapse;
padding: 2px;
}
th {
font-weight: bold;
border: 2px solid blue;
}
</style>
</head>
<body>
<form action="order/save" method="get">
<table class="my-table">
<tr>
<th colspan="2">Make an Order</th>
</tr>
<tr>
<td>orderId: </td>
<td><input type="text" name="orderId"/></td>
</tr>
<tr>
<td>orderType: </td>
<td><input type="text" name="orderType"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="ORDER"/></td>
</tr>
</table>
</form>
</body>
</html>頁面效果如下圖所示:

我們先輸入符合規(guī)則的orderId,測試效果如下GIF圖所示:

但是,如果我們將 orderId 改成 0,就會報錯400,如下GIF圖所示:

4.@RequestMapping使用Ant風(fēng)格URL:
@RequestMapping 支持下面三種 Ant 風(fēng)格 URL——
① "?" :匹配文件名中的任意一個字符;
② "*" :匹配文件名中的任意1到多個字符(不能匹配空字符串);
③ "**":匹配多層路徑(0到多個路徑段)。
這里up在之前用過的UserSerlvet上做做手腳,來測試 Ant風(fēng)格 URL,UserServlet代碼如下:
package com.cyan.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller //@Controller注解,標(biāo)識當(dāng)前類是一個控制器,有時也稱為Handler(處理器)
public class UserServlet {
@RequestMapping(value = "/user/?/login") //此處的value可以省略
public String login() {
System.out.println("This is login!");
return "login_OK";
}
@RequestMapping(value = "/user/*/sign") //此處的value可以省略
public String sign() {
System.out.println("This is sign~~~");
return "login_OK";
}
@RequestMapping(value = "/user/**/register") //此處的value可以省略
public String register() {
System.out.println("This is register+++");
return "login_OK";
}
}再來一個 testAnt.jsp 用于測試URL的匹配情況,testAnt.jsp代碼如下——
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>testAnt</title>
</head>
<body>
<a href="user/1/login" rel="external nofollow" >login_test1</a>
<a href="user/2/login" rel="external nofollow" >login_test2</a>
<a href="user/3/login" rel="external nofollow" >login_test3</a>
<a href="user/abc/sign" rel="external nofollow" >sign_test1</a>
<a href="user/fff/sign" rel="external nofollow" >sign_test2</a>
<a href="user/Cyan-RA9/sign" rel="external nofollow" >sign_test3</a>
<a href="user/register" rel="external nofollow" >register_test1</a>
<a href="user/Pro/register" rel="external nofollow" >register_test2</a>
<a href="user/Pro/Max/Ultra/Plus/register" rel="external nofollow" >register_test3</a>
</body>
</html>最后進(jìn)行運行測試,測試情況如下 GIF圖 所示:

IDEA 后臺的輸出結(jié)果如下圖所示:

正好對應(yīng)了 UserServlet 中三個方法的輸出語句,符合預(yù)期。
5.@RequestMapping 配合 @PathVariable映射:
一般情況下,URL的參數(shù)形式是——action 屬性[+?+請求參數(shù)]。其中,請求參數(shù)的格式是:name=value&name=value。
但是,借助 @PathVariable 可以省略參數(shù)名,簡化URL.
新建一個 UserHandler 用于演示,UserHandler類代碼如下:
package com.cyan.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author : Cyan_RA9
* @version : 22.0
*/
@Controller
@RequestMapping(value = "/user")
public class UserHandler {
/*
1. @RequestMapping 中定義的參數(shù)名和 @PathVariable 中指定的參數(shù)名 必須保持一致。
2. 使用了 @PathVariable 的方法的形參名,可以與上面兩者不一致,形參名無所謂。
*/
@RequestMapping(value = "/sign/up/{username}/{userid}")
public String sign_up(@PathVariable("username") String name, @PathVariable("userid") String id) {
System.out.println(("Parameters Received : " + "username = " + name + ", userid = " + id));
return "login_OK";
}
}再來一個 testPathVariable 頁面,用于測試 URL 的簡化效果,testPathVariable.jsp 代碼如下——
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>@PathVariable Test</title>
</head>
<body>
<h3>Click the reference to take a test</h3>
<a href="user/sign/up/Cyan_RA9/141" rel="external nofollow" >點我就完事兒!</a>
</body>
</html>測試結(jié)果如下GIF圖所示:

三、@RequestMapping的使用細(xì)節(jié)
1. @RequestMapping(及其派生注解)映射的 URL 不能重復(fù),即同一個項目中不能有兩個方法去匹配完全相同的 URL,這時候 Tomcat 啟動時會報錯,如下圖所示:

2.@RequestMapping(value = "/xxx",method = RequestMethod.POST) 就等價于 @PostMapping(value = "/xxx")。類似的寫法還有: @GetMapping,@PutMapping,@DeleteMapping。
3.如果已經(jīng)確定 某個表單 或者 超鏈接 會提交字段數(shù)據(jù), 那么要求提交的參數(shù)名 和 目標(biāo)方法的參數(shù)名保持一致.(也就是我們在上面演示3 和 演示5中做的那樣.)
四、@RequestMapping延伸——SpringMVC中,如何通過注解實現(xiàn)POJO類直接作為Controller,而不依賴Servlet或接口?
我們可以使用 @Controller 來把一個 POJO類 標(biāo)記為SpringMVC的 控制器,@Controller 本身可以看作是 @Component 的一個特例,所以被 @Controller 標(biāo)記的類也會被 Spring 容器作為組件進(jìn)行管理。除了 @Controller 之外,我們還需要另一個核心注解——@RequestMapping(或者它的派生注解),這個注解可以把瀏覽器發(fā)來的 HTTP 請求映射到具體的 Controller 類 或者 某個方法上面;@RequestMapping 直接定義了 HTTP 請求的一些屬性,例如請求的URL,請求的方法類型,請求的參數(shù)等等。
那么上面說的這兩個注解,就是我們自己 能操作的部分,但是真正要想實現(xiàn)對 Servlet API 的解耦,背后靠的是 前端控制器(DispatcherServlet),處理器映射器(HandlerMapping),處理器適配器(HandlerAdapter) 這三大組件的協(xié)同工作,尤其是 HandlerAdapter(因為它直接實現(xiàn)了 適配器模式)。DispatcherServlet 拿到 HandlerMapping 找到的處理器(即 我們標(biāo)記的 POJO Controller)后,并不會直接調(diào)用它。而是將處理器交給 HandlerAdapter,讓它去調(diào)用。HandlerAdapter 會從 HttpServletRequest 中提取信息(即參數(shù)解析),然后把提取到的有用信息 適配為 POJO 方法的參數(shù),那么我們標(biāo)記為控制器的 POJO,根本就不需要直接接觸 HttpServletRequest 或 HttpServletResponse。而且 HandlerAdapter 通過反射直接檢查 POJO 方法簽名,只要方法簽名符合 Spring MVC 的約定,就可以被調(diào)用,所以也不需要依賴接口。
SpringMVC的執(zhí)行流程回顧——如下圖所示:

五、總結(jié)
??,以上就是 SpringMVC --- @RequestMapping 的全部內(nèi)容了??。
這篇文章沒什么難度,主要就是演示了一下 @RequestMapping 的各種使用方式和技巧,大家只要知道 @RequestMapping 在整個 Spring MVC 中很重要并且把它用熟練就可以了。
到此這篇關(guān)于SpringMVC @RequestMapping的使用演示和細(xì)節(jié)展示的文章就介紹到這了,更多相關(guān)SpringMVC @RequestMapping使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot FeignClient 如何捕獲業(yè)務(wù)異常信息
這篇文章主要介紹了Spring Boot FeignClient 如何捕獲業(yè)務(wù)異常信息的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
springboot+mybatis-plus 兩種方式打印sql語句的方法
這篇文章主要介紹了springboot+mybatis-plus 兩種方式打印sql語句的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
java警告:源發(fā)行版17 需要目標(biāo)發(fā)行版17問題及解決
文章介紹了如何解決項目JDK版本不一致的問題,包括修改Project Structure、Modules、Dependencies和Settings中的JDK版本,以及在pom.xml中指定JDK源版本2024-11-11
面試題:java中為什么foreach中不允許對元素進(jìn)行add和remove
讀者遇到了一個比較經(jīng)典的面試題,也就是標(biāo)題上說的,為什么 foreach 中不允許對元素進(jìn)行 add 和 remove,本文就詳細(xì)的介紹一下,感興趣的可以了解一下2021-10-10
關(guān)于MyBatis中映射對象關(guān)系的舉例
這篇文章主要介紹了關(guān)于MyBatis中映射對象關(guān)系的舉例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06

