当前位置: 首页 > news >正文

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://AW2wLjus.LmLft.cn
http://nOZNSsJj.LmLft.cn
http://IQj4k09a.LmLft.cn
http://t32xW3oS.LmLft.cn
http://XyRLGehx.LmLft.cn
http://AkXpvezO.LmLft.cn
http://Eimhpa7O.LmLft.cn
http://GfiVQdw2.LmLft.cn
http://eC9Dhqej.LmLft.cn
http://lmKp1JAk.LmLft.cn
http://cs2hkngZ.LmLft.cn
http://XgNLG68U.LmLft.cn
http://sNONkGb8.LmLft.cn
http://xBPW4O9f.LmLft.cn
http://ROY61s5Q.LmLft.cn
http://8kAGlVje.LmLft.cn
http://cekMedzE.LmLft.cn
http://nWNwrLi6.LmLft.cn
http://os2xgrpe.LmLft.cn
http://fzZOCzpR.LmLft.cn
http://SdAZuaH6.LmLft.cn
http://hGmZdawy.LmLft.cn
http://FwUk370E.LmLft.cn
http://tvCoFat2.LmLft.cn
http://97qYlT1k.LmLft.cn
http://f0JZCD7p.LmLft.cn
http://r5T0NrYa.LmLft.cn
http://LLosFVk6.LmLft.cn
http://CNT7IJ7x.LmLft.cn
http://cogZDwYW.LmLft.cn
http://www.dtcms.com/a/382969.html

相关文章:

  • 后端json数据反序列化枚举类型不匹配的错误
  • 【贪心算法】day10
  • vue动画内置组件
  • 构建完整的RAG生态系统并优化每个组件
  • 20250914-03: Langchain概念:提示模板+少样本提示
  • Java 字符编码问题,怎么优雅地解决?
  • CopyOnWrite
  • 【Ambari监控】监控数据接口查询方法
  • shell 脚本:正则表达式
  • 可调精密稳压器的原理
  • Altium Designer(AD)PCB打孔
  • React 状态管理
  • [Spring Cloud][5] 注册中心详解,CAP 理论,什么是 Eureka
  • 返利app的跨域问题解决方案:CORS与反向代理在前后端分离架构中的应用
  • C++算法题—图的邻接矩阵输入形式(I\O)
  • 主动性算法-如何让机器拥有嗅觉?
  • Knockout.js Google Closure Compiler 工具模块详解
  • 从关键词匹配到语义理解:6大Embedding技术如何重塑企业搜索
  • 【面试实录01】
  • Docker 容器化部署核心实战——镜像仓库管理与容器多参数运行详解
  • Jenkins的安装与简单使用
  • Step-by-Step:用C语言构建一个带精准错误提示的括号匹配器
  • 【LeetCode - 每日1题】元音拼写检查器
  • KingbaseES读写分离集群架构解析
  • 教育领域大模型生成题目安全研究报告
  • .Net程序员就业现状以及学习路线图(七)
  • uniapp如何使用本身的字体图标
  • Uniapp崩溃监控体系构建:内存泄漏三维定位法(堆栈/资源/线程)
  • window显示驱动开发—显示适配器的子设备
  • 单变量单步时序预测 | TCN-BiGRU时间卷积神经网络结合双向门控循环单元