一、@RequestMapping 简介

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

servletName

ServletClass

servletName

url

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

@Target({ElementType.METHOD, ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Mapping

public @interface RequestMapping {

String name() default "";

String[] value() default {};

String[] path() default {};

RequestMethod[] method() default {};

String[] params() default {};

String[] headers() default {};

String[] consumes() default {};

String[] produces() default {};

}

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

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

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

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

package cn.kolbe.spring.mvc.controller;

import org.springframework.stereotype.Controller;

@Controller

public class UserController {

public String login() {

return "success";

}

}

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

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

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

html>

Spring MVC

User Login

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

html>

Spring MVC

Welcome

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

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

@Controller

public class UserController {

@RequestMapping("/login")

public String login() {

return "success";

}

}

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

User Login

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

@Controller

@RequestMapping("/user")

public class UserController {

@RequestMapping("/login")

public String login() {

return "success";

}

}

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

User Login

四、测试 @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 方式发来的请求

@Controller

@RequestMapping(path = "/user")

public class UserController {

@RequestMapping(path = "/login", method=RequestMethod.GET)

public String login() {

return "success";

}

}

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

User Login

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

@Controller

@RequestMapping(path = "/user")

public class UserController {

@RequestMapping(path = "/login", method=RequestMethod.POST)

public String login() {

return "success";

}

}

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

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

@Controller

@RequestMapping(path = "/user")

public class UserController {

// 该方法将同时接收通过GET和POST方式发来的请求

@RequestMapping(path = "/login", method={RequestMethod.POST,RequestMethod.GET})

public String login() {

return "success";

}

}

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

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

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

@Controller

@RequestMapping(path = "/user")

public class UserController {

// 该方法将接收 /user/login 发来的请求,且请求参数必须为 username=kolbe&password=123456

@RequestMapping(path = "/login", params={"username=kolbe","password=123456"})

public String login() {

return "success";

}

}

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

User Login

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

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

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

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

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

Request Headers

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Accept-Encoding:gzip, deflate, sdch

Accept-Language:zh-CN,zh;q=0.8

Cache-Control:max-age=0

Connection:keep-alive

Cookie:JSESSIONID=210075B5E521CWE3CDE938076295A57A

Host:localhost:8080

Upgrade-Insecure-Requests:1

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 属性,可以限制客户端发来的请求

@Controller

@RequestMapping(path = "/user")

public class UserController {

// 表示只接收本机发来的请求

@RequestMapping(path = "/login", headers="Host=localhost:8080")

public String login() {

return "success";

}

}

七、带占位符的URL

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

(二)使用方法:

1)带占位符的URL示例:

@Controller

@RequestMapping(path = "/user")

public class UserController {

@RequestMapping(value="/{id}", method=RequestMethod.GET)

public String show(@PathVariable("id") Integer id) {

return "success";

}

}

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

八、采用 REST 风格的 URL 请求

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

2)REST 风格的 URL 请求

请求路径        请求方法           作用

-/user/1        HTTP GET        得到id为1的user

-/user/1        HTTP DELETE     删除id为1的user

-/user/1        HTTP PUT        更新id为1的user

-/user          HTTP POST       新增user

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

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

hiddenHttpMethodFilter

org.springframework.web.filter.HiddenHttpMethodFilter

hiddenHttpMethodFilter

/*

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

html>

Spring MVC

Test Rest GET

6)修改后的UserController代码

package cn.kolbe.spring.mvc.controller;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

@Controller

@RequestMapping(path = "/user")

public class UserController {

@RequestMapping(value="/{id}", method=RequestMethod.GET)

public String show(@PathVariable("id") Integer id) {

System.out.println("查看id为:" + id + "的user");

return "success";

}

@RequestMapping(value="/{id}", method=RequestMethod.PUT)

public String update(@PathVariable("id") Integer id) {

System.out.println("更新id为:" + id + "的user");

return "success";

}

@RequestMapping(value="/{id}", method=RequestMethod.DELETE)

public String destroy(@PathVariable("id") Integer id) {

System.out.println("删除id为:" + id + "的user");

return "success";

}

@RequestMapping(value="", method=RequestMethod.POST)

public String create() {

System.out.println("新建user");

return "success";

}

}

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

HTTP Status 405 - Request method 'DELETE' not supported

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。由于字数超限,暂时说到这。。。

myFilter

/*

FORWARD

requestmapping配置页面后_Spring MVC 入门指南(二):@RequestMapping用法详解相关推荐

  1. Spring Cloud Eureka 入门 (二)服务提供者详解

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! "优秀不是过 ...

  2. Unity快速入门之二 GUI Transform 详解

    Unity快速入门之一 3D基础概念.Camera.Canvas RenderMode的几种方式对比_翕翕堂 Unity快速入门之二 GUI Transform 详解_翕翕堂 Unity快速入门之三 ...

  3. 微信小程序云开发入门(二)-数据库详解

    微信小程序云开发入门(二)-数据库详解 接上一篇:微信小程序云开发入门(一) 摘要: 因为微信小程序云数据库有点类似传统的关系型数据库,但又有所不同.所以刚入手的时候会有点困扰,经过一段时间的学习和摸 ...

  4. requestmapping配置页面后_SpringBoot2.0 基础案例(03):配置系统全局异常映射处理

    一.异常分类 这里的异常分类从系统处理异常的角度看,主要分类两类:业务异常和系统异常. 1.业务异常 业务异常主要是一些可预见性异常,处理业务异常,用来提示用户的操作,提高系统的可操作性.常见的业务异 ...

  5. requestmapping配置页面后_@RequestMapping使用须知

    ----------------------siwuxie095 @RequestMapping 使用须知 使用 @RequestMapping 注解映射请求路径 即 你可以使用 @RequestMa ...

  6. requestmapping配置页面后_@RequestMapping接口及页面乱码问题

    老师 对接口及乱码问题请教 接口问题 @RequestMapping("upload.do") @ResponseBody public ServerResponse upload ...

  7. requestmapping配置页面后_第004课:Spring Boot 项目属性配置

    在项目中,很多时候需要用到一些配置的信息,这些信息可能在测试环境和生产环境下会有不同的配置,后面根据实际业务情况有可能还会做修改,针对这种情况,我们不能将这些配置在代码中写死,最好就是写到配置文件中. ...

  8. 「HTML和CSS入门指南」hr 标签详解

    HTML5 中的 hr 标签 HTML5 中的 <hr> 标签是用于插入水平分割线的标签,通常用于在页面中添加分隔线或者段落之间的分割线.<hr> 标签可以单独使用,也可以与其 ...

  9. 「HTML和CSS入门指南」footer 标签详解

    什么是 footer 标签? 在 HTML 中,footer 标签用于表示页面或区域的页脚部分.通常用于包含版权声明.联系信息和其他重要元素. footer 标签的基本语法 以下是 footer 标签 ...

最新文章

  1. R语言将dataframe宽表转化为长表实战:使用data.table、使用tidyr包gather函数、使用reshape2包
  2. [androd] android的在线源码网站,各个版本都有(目前已到俺android 4.2,但不包含kernel部分的代码)
  3. boost::gil模块计算直方图的测试程序
  4. python selenium_Python+selenium自动化测试
  5. java windows7 环境变量_Windows7环境变量中,系统变量与用户变量的优先级
  6. Slog57_玩转NPM之NPM_package的制作发布和使用
  7. Matlab读取TXT文本文件通用程序
  8. 绿坝花季护航,为何如此吸引眼球?
  9. SketchUp插件|ClothWorks布料模拟 免费下载!(草图大师制作窗帘张拉膜等)
  10. Java 编写一个类Letter,要求该类创建对象p,并调用方法printLetter输出英文字母表。
  11. 十则:程序员“笑话”据说只有真正的程序员才看得懂
  12. 【83行代码获奖代码】高中生@青藤木子 耗费一周给妈妈编写了一款语音识别APP
  13. CSR蓝牙遥控器OTA固件升级
  14. 【Vue实用功能】Vue实现tab页多页面切换
  15. Microsoft 365独家安全解决方案
  16. 怎样记账简单明白,实用记账技巧
  17. HTML之创建有序、无序和定义列表
  18. Locating Elements
  19. PHP内核源码阅读过程(四)
  20. 每日安全简讯20160722

热门文章

  1. 软件缺陷是什么以及缺陷的管理
  2. CentOS 防火墙操作
  3. 阿司匹林计算机音乐,阿司匹林
  4. 如何利用Kubernetes集群提升资源利用率?
  5. [软件测试]因果图例子
  6. 关于https的ssl加密技术
  7. RequestMapping中produces属性作用
  8. mysql查询余额变化,mysql-根据上一行余额更新总数
  9. C++ 多线程: WaitForSingleObject(m_hEvent,INFINITE) ;
  10. ”该硬盘处于脱机.因为他与另一个联机磁盘发生签名冲突“的解决方法,有图有真相