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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;它们是确保数据能在网络硬件间可靠传输的基…