@RequestMapping用法详解

 

 

一、@RequestMapping 简介

在Spring MVC 中使用 @RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.xml中配置


   
   
  1. <servlet>
  2.      <servlet-name>servletName </servlet-name>
  3.      <servlet-class>ServletClass </servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6.      <servlet-name>servletName </servlet-name>
  7.      <url-pattern>url </url-pattern>
  8. </servlet-mapping>

的映射作用一致。让我们先看一下RequestMapping注解类的源码:


   
   
  1. @Target({ElementType.METHOD, ElementType.TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Mapping
  5. public @interface RequestMapping {
  6. String name() default "";
  7. String[] value() default {};
  8. String[] path() default {};
  9. RequestMethod[] method() default {};
  10. String[] params() default {};
  11. String[] headers() default {};
  12. String[] consumes() default {};
  13. String[] produces() default {};
  14. }

1)在@Target中有两个属性,分别为 ElementType.METHOD 和 ElementType.TYPE ,也就是说 @RequestMapping 可以在方法和类的声明中使用

2)可以看到注解中的属性除了 name() 返回的字符串,其它的方法均返回数组,也就是可以定义多个属性值,例如 value() 和 path() 都可以同时定义多个字符串值来接收多个URL请求

 

二、准备工作:(注:后面的示例都将基于准备工作)

1)新建一个 Web 工程,取名为 SpringMVC 

2)新建一个的控制器类:UserController


   
   
  1. package cn. kolbe. spring. mvc. controller;
  2. import org. springframework. stereotype. Controller;
  3. @Controller
  4. public  class  UserController {
  5. public  String  login( ) {
  6. return  "success";
  7. }
  8. }

3)新建和配置 web.xml 以及 spring-mvc.xml 文件

略(具体参见 前一章:Spring MVC 学习笔记(一):HelloWorld

4)新建一个测试的 JSP 页面 index.jsp


   
   
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Spring MVC </title>
  7. </head>
  8. <body>
  9. <p>  <a href="#">User Login </a>
  10. </body>
  11. </html>

5)新建一个成功跳转的页面 JSP 页面 welcome.jsp


   
   
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Spring MVC </title>
  7. </head>
  8. <body>
  9. <h1>Welcome </h1>
  10. </body>
  11. </html>

 

三、测试 @RequestMapping 中的 value 和 path 属性(这两个属性作用相同,可以互换,如果仅有这一个属性,则可以省略,下面两个例子均采用省略的方式)

1)将 @RequestMapping 注解在 login 方法上,而UserController上不添加 @RequestMapping 注解,这时的请求 URL 是相对于 Web 根目录


   
   
  1. @Controller
  2. public  class  UserController {
  3. @RequestMapping( "/login")
  4. public  String  login( ) {
  5. return  "success";
  6. }
  7. }

这时的方法 login() 能处理的 URL 请求路径是基于 Web 应用的,也就是 http://localhost/SpringMVC/login,也就是 index.jsp 页面中的 User Login 链接地址应该是:

<a href="login">User Login</a>
   
   

 

2)将 @RequestMapping 注解在 UserController 类上,这时类的注解是相对于 Web 根目录,而方法上的是相对于类上的路径


   
   
  1. @Controller
  2. @RequestMapping("/user")
  3. public  class UserController {
  4. @RequestMapping("/login")
  5. public String login() {
  6. return  "success";
  7. }
  8. }

这时的方法login()能处理的 URL 请求路径则是 http://localhost/SpringMVC/user/login,也就是 index.jsp 页面中的 User Login 链接地址应该是:

<a href="user/login">User Login</a>
   
   

 

四、测试 @RequestMapping 的 method 属性

1)简介:@RequestMapping 中的 method 主要用来定义接收浏览器发来的何种请求。在Spring中,使用枚举类

org.springframework.web.bind.annotation.RequestMethod来定义浏览器请求的方式。

Http规范定义了多种请求资源的方式,最基本的有四种,分别为:GET(查)、POST(增)、PUT(改)、DELETE(删),而URL则用于定位网络上的资源相当于地址的作用,配合四种请求方式,可以实现对URL对应的资源的增删改查操作。

在实际应用中,很多人并没有按照这个规范做,因为使用GET/POST同样可以完成PUT和DELETE操作,甚至GET也可以完成POST操作,因为GET不需要用到表单,而POST却需要通过表单来发送。

2)通过 @RequestMapping(value="/login",method=RequestMethod.GET) 来指定 login()方法 仅处理通过 GET 方式发来的请求


   
   
  1. @Controller
  2. @RequestMapping(path = "/user")
  3. public  class UserController {
  4. @RequestMapping(path = "/login", method=RequestMethod.GET)
  5. public String login() {
  6. return  "success";
  7. }
  8. }

这时,如果浏览器发来的请求不是GET的话,将收到浏览器返回的错误提示,也就是得通过链接的方式而不是表单的方式:

<a href="user/login>User Login</a>
   
   

3)通过 @RequestMapping(value="/login",method=RequestMethod.POST) 来指定 login()方法 仅处理通过 POST 方式发来的请求


   
   
  1. @Controller
  2. @RequestMapping(path = "/user")
  3. public  class UserController {
  4. @RequestMapping(path = "/login", method=RequestMethod.POST)
  5. public String login() {
  6. return  "success";
  7. }
  8. }

这时,必须通过表单的方式发送请求,否则将收到浏览器返回的错误提示


   
   
  1. <form action="user/login" method="post">
  2.      <input type="submit" value="使用Post发送请求"/>
  3. </form>

4)由于在 RequestMapping 注解类中 method() 方法返回的是 RequestMethod 数组,所以可以给 method 同时指定多个请求方式,例如:


   
   
  1. @Controller
  2. @RequestMapping(path = "/user")
  3. public  class UserController {
  4.          // 该方法将同时接收通过GET和POST方式发来的请求
  5. @RequestMapping(path = "/login", method={RequestMethod.POST,RequestMethod.GET})
  6. public String login() {
  7. return  "success";
  8. }
  9. }

 

五、测试 @RequestMapping 的 params 属性,该属性表示请求参数,也就是追加在URL上的键值对,多个请求参数以&隔开,例如:

http://localhost/SpringMVC/user/login?username=kolbe&password=123456
   
   

则这个请求的参数为username=kolbe以及password=123456,@RequestMapping 中可以使用 params 来限制请求参数,来实现进一步的过滤请求,举个例子:


   
   
  1. @Controller
  2. @RequestMapping(path = "/user")
  3. public  class UserController {
  4.         
  5.          // 该方法将接收 /user/login 发来的请求,且请求参数必须为 username=kolbe&password=123456
  6. @RequestMapping(path = "/login", params={"username=kolbe","password=123456"})
  7. public String login() {
  8. return  "success";
  9. }
  10. }

该例中则表示 UserController 中的 login() 方法仅处理 /user/login 发来的请求,且必须带有 username=kolbe&password=123456 的请求参数,否则浏览器将返回HTTP 404的错误, 对应 index.jsp 中的键接地址为:

<a href="user/login?username=kolbe&password=123456">User Login</a>
   
   

 

六、测试 @RequestMapping 的 headers 属性,该属性表示请求头

用于HTTP协义交互的信息被称为HTTP报文,客户端发送的HTTP报文被称为请求报文,服务器发回给客户端的HTTP报文称为响应报文,报文由报文头部和报文体组成。

请求头部(Request Headers):请求头包含许多有关客户端环境和请求正文的信息,例如浏览器支持的语言、请求的服务器地址、客户端的操作系统等。

响应头部(Rsponse Headers):响应头也包含许多有用的信息,包括服务器类型、日期、响应内容的类型及编码,响应内容的长度等等。

如果你安装的是Chrome浏览器,可以通过在网页中  右击鼠标---->审查元素---->Network---->Name中点击网页---->右侧查看Headers即可,如果Name中没有出现网页,可以刷新一下即可,下边是我电脑中的一个请求头部示例:


   
   
  1. Request Headers
  2.     Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  3.     Accept-Encoding:gzip, deflate, sdch
  4.     Accept-Language:zh-CN,zh;q=0.8
  5.     Cache-Control:max-age=0
  6.     Connection:keep-alive
  7.     Cookie:JSESSIONID=210075B5E521CWE3CDE938076295A57A
  8.     Host:localhost:8080
  9.     Upgrade-Insecure-Requests:1
  10.     User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93

回规正题,通过 @RequestMapping 中的 headers 属性,可以限制客户端发来的请求


   
   
  1. @Controller
  2. @RequestMapping(path = "/user")
  3. public  class UserController {
  4.          // 表示只接收本机发来的请求
  5. @RequestMapping(path = "/login", headers="Host=localhost:8080")
  6. public String login() {
  7. return  "success";
  8. }
  9. }

 

七、带占位符的URL

(一)带占位符的URL是Spring 3.0 新增的功能,可以通过 @PathVariable 将 URL 中的占位符绑定到控制器的处理方法的参数中,占位符使用{}括起来

(二)使用方法:

1)带占位符的URL示例:


   
   
  1. @Controller
  2. @RequestMapping(path = "/user")
  3. public  class UserController {
  4.         
  5. @RequestMapping(value="/{id}", method=RequestMethod.GET)
  6. public String show( @PathVariable("id") Integer id) {
  7. return  "success";
  8. }
  9. }

在这个控制器中 show() 方法将可以接收 user/1、user/2、user/3等等的路径请求,请求的方法必须为GET,使用 @PathVariable 为应用实现 REST 规范提供了具大的便利条件。

 

八、采用 REST 风格的 URL 请求

1)简介:REST(Representational State Transfer):(资源)表现层状态转化,它是目前最流行的一种软件架构,其结构清晰、易于理解、扩展方便且符合标准,正在越来越多的被实践到应用中。

2)REST 风格的 URL 请求


   
   
  1.  请求路径        请求方法           作用
  2. - / user / 1        HTTP  GET        得到id为 1user
  3. - / user / 1        HTTP  DELETE     删除id为 1user
  4. - / user / 1        HTTP PUT        更新id为 1user
  5. - / user          HTTP POST       新增 user

3)由于浏览器表单只支持 GET 和 POST 请求,为了实现 DELETE 和 PUT 请求,Spring 为我们提供了一个过滤器org.springframework.web.filter.HiddenHttpMethodFilter,可以为我们将 GET 和 POST 请求通过过滤器转化成 DELETE 和 PUT 请求。

4)在 web.xml 中配置过滤器


   
   
  1. <!-- 配置 org.springframework.web.filter.HiddenHttpMethodFilter 过滤器 -->
  2. <filter>
  3.      <filter-name>hiddenHttpMethodFilter </filter-name>
  4.      <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter </filter-class>
  5. </filter>    
  6. <filter-mapping>
  7.      <filter-name>hiddenHttpMethodFilter </filter-name>
  8.      <!-- 拦截所有请求 -->
  9.      <url-pattern>/* </url-pattern>
  10. </filter-mapping>

5)由于浏览器表单无法发送 DELETE 和 PUT 请求,所以为了让 HiddenHttpMethodFilter 识别请求的方法,需要在表单中添加一个隐藏域,名字为 _method 值为 DELETE 或 POST 或PUT,修改后 index.jsp 页面代码如下:


   
   
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Spring MVC </title>
  7. </head>
  8. <body>
  9. <p>
  10.   <!-- 得到id为1的user -->
  11. <a href="user/1">Test Rest GET </a>
  12. <!-- 新建id为1的user -->
  13. <form action="user" method="post">
  14.          <input type="hidden" name="_method" value="POST"/>
  15. <input type="submit" value="Test Rest POST"/>
  16. </form>
  17. <!-- 删除id为1的user -->
  18. <form action="user/1" method="post">
  19. <input type="hidden" name="_method" value="DELETE"/>
  20. <input type="submit" value="Test Rest DELETE"/>
  21. </form>
  22. <!-- 更新id为1的user -->
  23. <form action="user/1" method="post">
  24. <input type="hidden" name="_method" value="PUT"/>
  25. <input type="submit" value="Test Rest PUT"/>
  26. </form>
  27. </body>
  28. </html>

6)修改后的UserController代码


   
   
  1. package cn.kolbe.spring.mvc.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind. annotation.PathVariable;
  4. import org.springframework.web.bind. annotation.RequestMapping;
  5. import org.springframework.web.bind. annotation.RequestMethod;
  6. @Controller
  7. @RequestMapping(path = "/user")
  8. public  class UserController {
  9. @RequestMapping(value="/{id}", method=RequestMethod.GET)
  10. public String show( @PathVariable("id") Integer id) {
  11. System. out.println( "查看id为:" + id +  "的user");
  12. return  "success";
  13. }
  14. @RequestMapping(value="/{id}", method=RequestMethod.PUT)
  15. public String update( @PathVariable("id") Integer id) {
  16. System. out.println( "更新id为:" + id +  "的user");
  17. return  "success";
  18. }
  19. @RequestMapping(value="/{id}", method=RequestMethod.DELETE)
  20. public String destroy( @PathVariable("id") Integer id) {
  21. System. out.println( "删除id为:" + id +  "的user");
  22. return  "success";
  23. }
  24. @RequestMapping(value="", method=RequestMethod.POST)
  25. public String create() {
  26. System. out.println( "新建user");
  27. return  "success";
  28. }
  29. }

 

注:如果你的web项目是运行在Tomcat 8下,你会发现被过滤成DELETE和PUT请求,到达控制器后,返回时(forward)会报HTTP 405的错误提示


   
   
  1. HTTP Status  405  - Request  method  'DELETE'  not supported
  2. HTTP Status  405  - JSPs  only permit  GET POST  or HEAD

有三种解决方案:

(一)将 Tomcat 8 改为 Tomcat 7,在Tomcat 7 下运行是正常的

(二)将请求转发(forward)改为请求重定向(redirect)

(三)自己手动写一个Filter来包装HttpRequest中的getMethod()方法

下面介绍一下第(三)种做法,也就是自己写一个Filter来包装从服务器发回来的HttpRequest请求:

 

 

 

大致说一下流程,

1. 在第1步中,客户端发送请求至服务器,这时如果发送的是POST请求且带有以_method为名的参数会被Spring的HiddenHttpMethodFilter给拦截。

2. HiddenHttpMethodFilter内有一个静态内部类通过继承HttpServletRequestWrapper类并重写getMethod()方法,将该方法返回值设为_method隐藏域的值。

3. HiddenHttpMethodFilter在包装好Request后,将请求发往服务器的控制器中对应的方法处理器,这时的请求变成了图中的 3、WrapperRequest by SpringFilter

4. 服务器处理完请求后,产生了一个forward请求,产生相应的请求处理信息发往客户端,注意这时的request的getMethod()方法仍然是HiddenHttpMethodFilter包装过的

5. 我们需要在服务器的响应请求到达客户端前进行拦截,这也是最关键的一步,通过自定义过滤器MyHttpMethodFilter进一步包装请求,将getMethod()方法返回值改成POST或GET即可

6. 在web.xml中配置该filter,注意dispatcher结点值必须为FORWARD。由于字数超限,暂时说到这。。。


   
   
  1. <filter-mapping>
  2. <filter-name>myFilter </filter-name>
  3. <url-pattern>/* </url-pattern>
  4. <dispatcher>FORWARD </dispatcher>
  5. </filter-mapping>

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中提到,@RequestMapping注解用于将请求映射到特定的方法上,而@GetMapping注解则相当于@RequestMapping(method=RequestMethod.GET),用于将GET请求映射到特定的方法上。 引用中介绍了如何将多个请求映射到同一个方法上。只需要在@RequestMapping注解中添加一个请求路径值列表即可实现。例如,在类上添加@RestController和@RequestMapping("/home")注解,然后在方法上添加@RequestMapping注解并指定多个请求路径值,例如"", "/page", "page*", "view/*,**/msg",这样这个方法就能够处理这些请求路径的请求。 引用提供了一个同时在类和方法上应用@RequestMapping注解的示例。通过在类上添加@RequestMapping("/home")注解,可以将类中的所有方法的请求映射到"/home"路径下。然后,在方法上添加@RequestMapping注解并指定具体的请求路径,例如"/"和"/index",这样这两个方法就能够分别处理"/home/"和"/home/index/"的请求。 所以,@RequestMapping注解是用于将请求映射到方法上的注解。它可以根据请求的不同路径进行映射,并支持在类和方法上同时使用。同时,@GetMapping注解是一种简化形式,用于将GET请求映射到方法上。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [@RequestMapping详解](https://blog.csdn.net/m0_67401055/article/details/125057030)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [@RequestMapping](https://blog.csdn.net/weixin_44471080/article/details/108518255)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值