SpringMVC @RequestMapping的使用演示和細節 詳解

目錄

一、@RequestMapping是什么?

二、@RequestMapping 的使用演示

? ? ? ? 1.@RequestMapping在方法上的使用:

? ? ? ? 2.@RequestMapping同時在類和方法上使用:

? ? ? ? 3.@RequestMapping指定請求參數:

? ? ? ? 4.@RequestMapping使用Ant風格URL:

? ? ? ? 5.@RequestMapping 配合 @PathVariable映射:

三、@RequestMapping的使用細節

四、@RequestMapping延伸——SpringMVC中,如何通過注解實現POJO類直接作為Controller,而不依賴Servlet或接口?

五、總結


一、@RequestMapping是什么?

? ? ? ? (1) @RequestMapping注解 用于將瀏覽器發來的 HTTP 請求映射到具體的 Controller類 或者 某個方法上
? ? ? ? (2) @RequestMapping 定義了請求的 URL 路徑、請求使用的 HTTP 方法(GET, POST 等)、請求的參數、請求頭等匹配條件。
? ? ? ? (3)?@RequestMapping 既可以在類級別使用,定義指定類的所有方法共享的基礎路徑;也可以在方法級別使用,定義具體處理請求的路徑;還可以同時在類和方法級別上使用,并且,當同時修飾類和方法時,請求的 url 就是它們的組合—— /類請求值/方法請求值,具體應該為——http://IP[域名]:port/WEB工程路徑/類請求值/方法請求值


二、@RequestMapping 的使用演示

? ? ? ? 1.@RequestMapping在方法上的使用:

? ? ? ? ? ? ? ? 我們在 “SpringMVC 執行流程分析” 一文中已經演示過 @RequestMapping 在方法上的使用了,具體請見鏈接文章的 “快速入門” 部分。如下圖所示:

? ? ? ? 2.@RequestMapping同時在類和方法上使用:

????????????????我們在 “SpringMVC 執行流程分析” 一文中已經配置過 applicationContext-mvc.xml 和 web.xml。
? ? ? ? ? ? ? ? 這里以 “購買商品并提示購買成功” 的小demo進行演示:先來準備一個 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 目標方法的請求方式必須是 post* 2. SpringMVC 控制器默認支持 GET 和 POST 兩種方式,(如果不指定默認就是這兩個)*/@RequestMapping(value = "/purchase", method = RequestMethod.POST)public String purchase() {System.out.println("make a purchase of goods~~~");return "purchase_OK";}
}

? ? ? ? ? ? ? ? 可以看到,OrderHandlerpurchase() 方法上面都用了 @RequestMapping 進行修飾,如果想訪問 purcahse方法,正確的 URL 就應該是 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>/* 給表格和所有單元格設置邊框 */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 頁面,對應 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 頁面效果圖如下:

? ? ? ? ? ? ? ? 最后進行運行測試,運行結果如下GIF圖所示:

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

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

? ? ? ? 3.@RequestMapping指定請求參數:

? ? ? ? ? ? ? ? @RequestMapping 中的 params 屬性可以用于指定請求參數,如下圖所示:

? ? ? ? ? ? ? ? params?具體的使用方式有下面幾種——
? ? ? ? ? ? ? ? ?params = "param1_name" : 表示請求必須包含名稱是 "param1_name" 的請求參數。
? ? ? ? ? ? ? ? params = "param1_name!=value1":表示請求必須包含名稱是 "param1_name" 的請求參數 并且 它的不可以是 value1(手動指定)。
? ? ? ? ? ? ? ? params = "!=param1_name":表示請求必須 不包含 參數名稱為 "param1_name" 的請求參數。
? ? ? ? ? ? ? ? params = { "param1_name=value1", "param2_name" } :表示請求必須同時包含名稱為 "param1_name" 和 "param2_name" 的請求參數 并且 param1_name 參數的必須是指定的 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 目標方法的請求方式必須是 post* 2. SpringMVC 控制器默認支持 GET 和 POST 兩種方式,(如果不指定默認就是這兩個)*/@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) {// 傳入的參數會傳遞到方法的形參列表System.out.println("orderId = " + orderId);return "order_OK";}
}

? ? ? ? ? ? ? ? 對應的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>/* 給表格和所有單元格設置邊框 */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>

? ? ? ? ? ? ? ? 頁面效果如下圖所示:

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

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

? ? ? ? 4.@RequestMapping使用Ant風格URL:

? ? ? ? ? ? ? ? @RequestMapping 支持下面三種 Ant 風格 URL——
? ? ? ? ? ? ? ? "?" :匹配文件名中的任意一個字符;
? ? ? ? ? ? ? ? "*" :匹配文件名中的任意1到多個字符(不能匹配空字符串);
? ? ? ? ? ? ? ? "**":匹配多層路徑(0到多個路徑段)

? ? ? ? ? ? ? ? 這里up在之前用過的UserSerlvet上做做手腳,來測試 Ant風格 URL,UserServlet代碼如下:

package com.cyan.web;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller //@Controller注解,標識當前類是一個控制器,有時也稱為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">login_test1</a> <br/><a href="user/2/login">login_test2</a> <br/><a href="user/3/login">login_test3</a> <br/> <br/><a href="user/abc/sign">sign_test1</a> <br/><a href="user/fff/sign">sign_test2</a> <br/><a href="user/Cyan-RA9/sign">sign_test3</a> <br/> <br/><a href="user/register">register_test1</a> <br/><a href="user/Pro/register">register_test2</a> <br/><a href="user/Pro/Max/Ultra/Plus/register">register_test3</a>
</body>
</html>

? ? ? ? ? ? ? ? 最后進行運行測試,測試情況如下?GIF圖?所示:

? ? ? ? ? ? ? ? IDEA 后臺的輸出結果如下圖所示:

? ? ? ? ? ? ? ? 正好對應了 UserServlet 中三個方法的輸出語句,符合預期。

? ? ? ? 5.@RequestMapping 配合 @PathVariable映射:

? ? ? ? ? ? ? ? 一般情況下,URL的參數形式是——action 屬性[+?+請求參數]。其中,請求參數的格式是:name=value&name=value。
? ? ? ? ? ? ? ?
但是,借助 @PathVariable 可以省略參數名,簡化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 中定義的參數名和 @PathVariable 中指定的參數名 必須保持一致。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">點我就完事兒!</a>
</body>
</html>

? ? ? ? ? ? ? ? 測試結果如下GIF圖所示:


三、@RequestMapping的使用細節

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

? ? ? ? 2.@RequestMapping(value = "/xxx",method = RequestMethod.POST) 就等價于 @PostMapping(value = "/xxx")?類似的寫法還有: @GetMapping,@PutMapping,@DeleteMapping。

? ? ? ? 3.如果已經確定 某個表單 或者 超鏈接 會提交字段數據, 那么要求提交的參數名目標方法的參數名保持一致.(也就是我們在上面演示3 和 演示5中做的那樣.)


四、@RequestMapping延伸——SpringMVC中,如何通過注解實現POJO類直接作為Controller,而不依賴Servlet或接口?

????????????????我們可以使用 @Controller 來把一個 POJO類 標記為SpringMVC的 控制器,@Controller 本身可以看作是 @Component 的一個特例,所以被 @Controller 標記的類也會被 Spring 容器作為組件進行管理。除了 @Controller 之外,我們還需要另一個核心注解——@RequestMapping(或者它的派生注解),這個注解可以把瀏覽器發來的 HTTP 請求映射到具體的 Controller 類 或者 某個方法上面;@RequestMapping 直接定義了 HTTP 請求的一些屬性,例如請求的URL,請求的方法類型,請求的參數等等。

????????????????那么上面說的這兩個注解,就是我們自己 能操作的部分,但是真正要想實現對 Servlet API 的解耦,背后靠的是 前端控制器(DispatcherServlet),處理器映射器(HandlerMapping),處理器適配器(HandlerAdapter) 這三大組件的協同工作,尤其是 HandlerAdapter(因為它直接實現了 適配器模式)。DispatcherServlet 拿到 HandlerMapping 找到的處理器(即 我們標記的 POJO Controller)后,并不會直接調用它。而是將處理器交給 HandlerAdapter,讓它去調用。HandlerAdapter 會從 HttpServletRequest 中提取信息(即參數解析),然后把提取到的有用信息 適配為 POJO 方法的參數,那么我們標記為控制器的 POJO,根本就不需要直接接觸 HttpServletRequest 或 HttpServletResponse。而且 HandlerAdapter 通過反射直接檢查 POJO 方法簽名,只要方法簽名符合 Spring MVC 的約定,就可以被調用,所以也不需要依賴接口。

? ? ? ? ? ? ? ? SpringMVC的執行流程回顧——如下圖所示:


五、總結

  • 🆗,以上就是 SpringMVC --- @RequestMapping 的全部內容了😀。
  • 這篇文章沒什么難度,主要就是演示了一下 @RequestMapping 的各種使用方式和技巧,大家只要知道 @RequestMapping 在整個 Spring MVC 中很重要并且把它用熟練就可以了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/99176.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/99176.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/99176.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

flutter項目 -- 換logo、名稱 、簽名、打包

1、換logo, 透明底&#xff0c;下面5個尺寸&#xff0c;需要UI設計2、換名沒配置型的改名方式如下 打開app/src/main/AndroidManifest.xml3、簽名 運行 flutter doctor -vD:\project\Apk\keystore 自己建立的keystore文件夾&#xff0c; 注意命令后是 megoai-release-key(自…

【貪心算法】day9

&#x1f4dd;前言說明&#xff1a; 本專欄主要記錄本人的貪心算法學習以及LeetCode刷題記錄&#xff0c;按專題劃分每題主要記錄&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代碼&#xff1b;&#xff08;2&#xff09;優質解法 優質代碼&#xff1b;&#xff…

linux C 語言開發 (八) 進程基礎

文章的目的為了記錄使用C語言進行linux 開發學習的經歷。開發流程和要點有些記憶模糊&#xff0c;趕緊記錄&#xff0c;防止忘記。 相關鏈接&#xff1a; linux C 語言開發 (一) Window下用gcc編譯和gdb調試 linux C 語言開發 (二) VsCode遠程開發 linux linux C 語言開發 (…

從零學算法1094

1094.拼車 車上最初有 capacity 個空座位。車 只能 向一個方向行駛&#xff08;也就是說&#xff0c;不允許掉頭或改變方向&#xff09; 給定整數 capacity 和一個數組 trips , trips[i] [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi 乘客&#xff0c;接他…

B2B企業營銷型AI Agent服務商推薦:誰更專業?如何選型?

一、引言&#xff1a;為什么B2B企業需要營銷型AI Agent&#xff1f;在當前競爭激烈的B2B市場中&#xff0c;企業普遍面臨幾大挑戰&#xff1a;線索獲取難&#xff1a;獲客成本持續上升&#xff0c;高質量線索難以篩選。銷售周期長&#xff1a;從初步接觸到簽單&#xff0c;往往…

算法-雙指針5.6

目錄 &#x1f33f;力扣611-有效三角形得個數 &#x1f9ca;題目鏈接&#xff1a;https://leetcode.cn/problems/valid-triangle-number/description/ &#x1f9ca;題目描述&#xff1a;?編輯 &#x1f9ca;解題思路&#xff1a; &#x1f9ca;解題代碼&#xff1a; &a…

超參數自動化調優指南:Optuna vs. Ray Tune 對比評測

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;注冊即送-H卡級別算力&#xff0c;80G大顯存&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生更享專屬優惠。 引言&#xff1a;從"手動煉丹"到"自動化…

軟考-局域網基礎考點總結

這篇文章用于整理軟考網絡相關的知識點&#xff0c;囊括了詳細的局域網基礎的考點&#xff0c;能夠讓你認真備考&#xff0c;基礎知識一網打盡&#xff0c;讓后續的學習更加通暢~ 第一部分&#xff1a;OSI七層參考模型 OSI(Open System Interconnection)模型是一個理論框架&am…

Node.js核心模塊介紹

1. fs 模塊fs&#xff08;File System&#xff09;模塊允許對文件系統進行操作&#xff0c;提供了文件讀寫、文件夾操作等功能。fs 支持同步和異步兩種 API。1.1. 常用方法讀取文件&#xff1a;異步: fs.readFile()同步: fs.readFileSync()寫入文件&#xff1a;異步: fs.writeF…

緩存三大劫攻防戰:穿透、擊穿、雪崩的Java實戰防御體系(二)

第二部分&#xff1a;緩存擊穿——熱點key過期引發的“DB瞬間高壓” 緩存擊穿的本質是“某個熱點key&#xff08;高并發訪問&#xff09;突然過期”&#xff0c;導致大量請求在同一時間穿透緩存&#xff0c;集中沖擊DB&#xff0c;形成“瞬間高壓”。 案例3&#xff1a;電商秒殺…

Linux相關概念和易錯知識點(45)(網絡層、網段劃分)

目錄1.網絡層&#xff08;1&#xff09;IP協議頭格式&#xff08;2&#xff09;工作流程2.網段劃分&#xff08;1&#xff09;五類地址&#xff08;2&#xff09;回環地址&#xff08;3&#xff09;網段的特殊地址&#xff08;4&#xff09;網絡建設我們前面暫時跳過了網絡層&a…

transition(過渡)和animation(動畫)——CSS

1.transition過渡可以為一個元素在不同狀態之間進行切換時添加過渡效果&#xff0c;實現不同狀態間的變化效果。通過觸發事件(鼠標懸停、點擊等)&#xff0c;在兩個狀態間切換。1.1 使用語法&#xff1a;transition: [property] [duration] [timing-function] [delay];property…

Spring Cloud項目國產化改造MySQL遷移達夢數據庫,SQL變更

達夢數據庫下載地址&#xff1a;https://eco.dameng.com/download 達夢數據庫安裝文檔&#xff1a;https://eco.dameng.com/document/dm/zh-cn/start/dm-install-linux.html 數據遷移SQLark工具使用 首先&#xff0c;本次MySQL遷移使用了SQLark工具 1.下載安裝SQLark https…

Cesium---1.133版本不修改源碼支持arcgis MapServer 4490切片

參照了這篇博文&#xff1a;https://blog.csdn.net/qq_19689967/article/details/121449888https://blog.csdn.net/qq_19689967/article/details/121449888 利用新版本的源碼進行了修改&#xff0c;可以實現服務加載&#xff1a; Event.js import { Check,defined} from &qu…

迭代器和生成器的區別與聯系

目錄 1.可迭代對象 (Iterable) 2.迭代器 (Iterator) 3.生成器 (Generator) 3.1生成器函數 vs 生成器表達式 4.三者之間的聯系與區別 5.關系圖&#xff08;幫助你一眼看懂&#xff09; 6.核心結論&#xff08;記住這三句話&#xff09; 1.可迭代對象 (Iterable) 定義&…

Dropout:深度學習中的隨機丟棄正則化技術

本文由「大千AI助手」原創發布&#xff0c;專注用真話講AI&#xff0c;回歸技術本質。拒絕神話或妖魔化。搜索「大千AI助手」關注我&#xff0c;一起撕掉過度包裝&#xff0c;學習真實的AI技術&#xff01; 1 什么是Dropout&#xff1f; Dropout是深度學習中最廣泛使用的正則化…

vue2遷移到vite[保姆級教程]

vue2遷移到vite[保姆級教程]使用vue CLI創建項目進行vite遷移詳細步驟1. 安裝 Vite 和 Vue 2 支持插件2. 創建 vite.config.js3. 修改 package.json 腳本4. 創建 index.html5. 確保 main.js 正確引入6. 處理靜態資源7. 構建優化&#xff08;可選&#xff09;8. 啟動項目常見問題…

瀏覽器輸入URL回車

一&#xff0c;URL解析瀏覽器會對輸入的 URL&#xff08;統一資源定位符&#xff09; 進行拆解&#xff0c;搞清楚 “目標是誰、要獲取什么資源https://www.baidu.com/s?wdCDN 拆解后&#xff1a;協議&#xff08;Scheme&#xff09;&#xff1a;https&#xff08;加密通信協議…

leedcode 算法刷題第三十四天

198. 打家劫舍 class Solution { public:int rob(vector<int>& nums) {if(nums.size()0){return 0;}else if(nums.size()1){return nums[0];}else if(nums.size()2){return max(nums[0],nums[1]);}vector<int> dp(nums.size()1,0);dp[0] nums[0];dp[1] nums…

計算機網絡(二)物理層數據鏈路層

&#xff08;物理層、數據鏈路層... 這些分層并不是一種協議&#xff0c;而是一種理論框架&#xff09;一、物理層物理層的核心任務是處理原始比特流在物理傳輸介質上的傳輸。 主要任務物理層的主要任務可以概括為以下幾點&#xff0c;它們是確保數據能在網絡硬件間可靠傳輸的基…