一、概述

    

注解式控制器支持:

  • 请求的映射和限定
  • 参数的自动绑定
  • 参数的注解绑定

二、请求的映射和限定

http请求信息包含六部分信息:

①请求方法;
②URL;
③协议及版本;
④请求头信息(包括Cookie信息);
⑤回车换行(CRLF);
⑥请求内容区;

其中,①、②、④、⑥一般是可变的,可根据这些信息对处理方法进行映射,具体分为:

  • URL路径映射:使用URL映射请求到处理器的功能处理方法
  • 请求方法映射限定:如限定功能处理方法只处理GET请求
  • 请求参数映射限定:如限定只处理包含“abc”请求参数的请求
  • 请求头映射限定:如限定只处理“Accept=application/json”的请求

1、URL路径映射

i)普通URL路径映射

@RequestMapping(value="/user/create")
@RequestMapping(value={"/test1", "/user/create"})

ii)URI模板模式映射,可通过@PathVariable提取模板变量

@RequestMapping(value="/users/{userId}"):请求的URL可以是 “/users/123456”或“/users/abcd”
@RequestMapping(value="/users/{userId}/create"):请求的URL可以是“/users/123/create”。
@RequestMapping(value="/users/{userId}/topics/{topicId}"):请求的URL可以是“/users/123/topics/123”

iii)Ant风格的URL路径映射(最长匹配优先)

@RequestMapping(value="/users/**"):可以匹配“/users/abc/abc”,但“/users/123”将会被URI模板模式映射中的“/users/{userId}”模式优先映射到
@RequestMapping(value="/product?"):可匹配“/product1”或“/producta”,但不匹配“/product”或“/productaa”
@RequestMapping(value="/product*"):可匹配“/productabc”或“/product”,但不匹配“/productabc/abc”
@RequestMapping(value="/product/*"):可匹配“/product/abc”,但不匹配“/productabc”
@RequestMapping(value="/products/**/{productId}"):可匹配“/products/abc/abc/123”或“/products/123”,也就是Ant风格和URI模板变量风格可混用

iv)正则表达式风格的URL路径映射,可通过@PathVariable提取模板变量

@RequestMapping(value="/products/{categoryCode:\\d+}-{pageNumber:\\d+}"):格式为{变量名:正则表达式},可以匹配“/products/123-1”,但不能匹配“/products/abc-1”

2、请求方法映射限定

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

DispatcherServlet默认开启对 GET、POST、PUT、DELETE、HEAD的支持

3、请求参数映射限定

@RequestMapping(value = "/hello", params = "create"):表示请求中有“create”的参数名即可匹配,如可匹配的请求URL“http://×××/parameter1?create”
@RequestMapping(value = "/hello", params = "!create"):表示请求中没有“create”参数名即可匹配
@RequestMapping(value = "/hello", params = "submitFlag=create"):表示请求中有“submitFlag=create”请求参数即可匹配
@RequestMapping(value = "/hello", params = "submitFlag!=create"):表示请求中有submitFlag但不等于create即可匹配
@RequestMapping(value = "/hello", params = {"test1", "test2=create"}):表示请求中的有“test1”参数名 且 有“test2=create”参数即可匹配

4、请求头映射限定

@RequestMapping(value="/hello", headers = "Accept"):表示请求的URL必须为“/hello”且请求头中必须有Accept参数才能匹配
@RequestMapping(value="/hello", headers = "!abc"):表示请求的URL必须为“/hello”且请求头中必须没有abc参数才能匹配
@RequestMapping(value="/hello", headers = "Content-Type=application/json"):表示请求的URL必须为“/hello”且请求头中必须有“Content-Type=application/json”参数才能匹配
@RequestMapping(value="/hello", headers = "Accept!=text/vnd.wap.wml"):表示请求的URL必须为“/hello”且请求头中必须有Accept但不等于“text/vnd.wap.wml”才能匹配
@RequestMapping(value="/hello", headers = {"Accept!=text/vnd.wap.wml","abc=123"}):表示请求的URL必须为“/hello”且请求头中必须有Accept但不等于“text/vnd.wap.wml”且请求中必须有参数“abc=123”才能匹配

三、参数的自动绑定

当功能方法参数列表中包含特定类型的参数时,Spring Web MVC框架会自动帮助我们把相应的参数传递过来,如HttpServletRequest 或HttpServletResponse,从而可以获取输入参数或输出数据,但使用不方便,推荐使用注解方式

1、HttpServletRequest 和HttpServletResponse

public String requestOrResponse (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) { ... }

2、InputStream/OutputStream 和 Reader/Writer

public void inputOrOutBody(InputStream requestBodyIn, OutputStream responseBodyOut) throws IOException {
responseBodyOut.write("success".getBytes());
} public void readerOrWriteBody(Reader reader, Writer writer) throws IOException {
writer.write("hello");
}

InputStream、OutputStream:等价于request.getInputStream()与response.getOutputStream()

Reader、Writer:等价于request.getReader()与response.getWriter()

3、HttpSession 

public String session(HttpSession session) {
System.out.println(session);
return "success";
}

4、Model、Map、ModelMap

三者继承关系

@RequestMapping(value = "/model")
public void createUser(Model model, Map model2, ModelMap model3) {
System.out.println(model == model2);
System.out.println(model2 == model3);
System.out.println(model.getClass().getName());
}

输出:

true
true
org.springframework.validation.support.BindingAwareModelMap

5、命令/表单对象

public class UserInfo {
private String name;
private Integer age; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
}
}
@RestController
public class TestController {
@RequestMapping(value = "/hello2")
public String helloWorld2(HttpServletRequest request, UserInfo userInfo) {
System.out.println(userInfo.getName());
return "选择比努力更重要!";
}
}

启动后,访问http://localhost:8080/myweb/hello2?name=matt&age=29

四、参数的注解绑定

参数的注解绑定是指通过注解方式实现功能方法参数的自动赋值,具体如下:

1、@RequestParam  绑定单个请求参数值
2、@PathVariable   绑定URI模板变量值
3、@CookieValue   绑定Cookie数据值
4、@RequestHeader  绑定请求头数据
5、@ModelAttribute  绑定请求参数到命令对象
6、@SessionAttributes  绑定命令对象到session
7、@Value  绑定SpEL表示式
8、@RequestBody  绑定请求内容数据

1、@RequestParam

@RequestParam注解有三个参数:

  • value:参数名字,即入参的请求参数名字,如username表示请求的参数区中的名字为username的参数的值将传入
  • required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报400错误码
  • defaultValue:默认值,表示如果请求中没有同名参数时的默认值,默认值可以是SpEL表达式,如“#{systemProperties['java.vm.version']}”

使用示例

@RestController
public class TestController2 {
@RequestMapping(value="/test1")
public String test1(@RequestParam("name") String username) {
return username;
} @RequestMapping(value="/test2")
public String test2(@RequestParam(value = "name", defaultValue = "#{systemProperties['java.vm.version']}") String username) {
return username;
} @RequestMapping(value="/test3")
public String test3(@RequestParam("role") String roles) {
return roles;
} @RequestMapping(value="/test4")
public String[] test4(@RequestParam("role") String[] roles) {
return roles;
} @RequestMapping(value="/test5")
public List<String> test5(@RequestParam("role") List<String> roles) {
return roles;
}
}

测试:

输入: http://localhost:8080/myweb/test1?name=matt
输出: "matt" 输入: http://localhost:8080/myweb/test1
输出: 400 输入: http://localhost:8080/myweb/test2
输出: "24.51-b03" 输入: http://localhost:8080/myweb/test3?role=admin&role=user
输出: "admin,user" 输入: http://localhost:8080/myweb/test4?role=admin&role=user
输出: ["admin","user"] 输入: http://localhost:8080/myweb/test5?role=admin&role=user
输出: ["admin","user"]

2、@PathVariable

@RequestMapping(value="/test6/{pageNum}")
public int test6(@PathVariable("pageNum") int pageNum) {
return pageNum;
}

启动后,访问http://localhost:8080/myweb/test6/10

3、@CookieValue

@RequestMapping(value="/test7")
public String test7(@CookieValue("name") String name) {
return name;
} @RequestMapping(value="/test8")
public Cookie test8(@CookieValue("name") Cookie cookie) {
return cookie;
}

@CookieValue有与@RequestParam相同的三个属性,含义相同

4、@RequestHeader

@RequestMapping(value="/test9")
public String test9(@RequestHeader("User-Agent") String userAgent, @RequestHeader(value="Accept") String[] accepts) {
return userAgent;
}

@RequestHeader有与@RequestParam相同的三个属性,含义相同

 5、@ModelAttribute

i)@ModelAttribute可绑定请求参数到命令对象,示例如下:

@RequestMapping("/model1")
public String testModel1(@ModelAttribute("user") UserInfo userInfo) {
return "hello";
}

hello.jsp

<%@ page language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
${user.name} ${user.age}
</body>
</html>

启动后,访问http://localhost:8080/myweb/model1?name=matt&age=29,页面输出:matt 29

ii)添加数据到Model,并从Model中绑定数据到处理方法参数,示例如下

@ModelAttribute("user")
public UserInfo getUser() {
UserInfo user = new UserInfo();
user.setName("cheng");
user.setAge(30);
System.out.println("getUser invoked");
return user;
} @RequestMapping("/model2")
public String testModel2(@ModelAttribute("user") UserInfo userInfo, ModelMap model) {
System.out.println(model.containsKey("user"));
return "hello";
}

hello.jsp如上

启动后,访问http://localhost:8080/myweb/model1,并刷新一次,页面输出:cheng 30,console输出如下:

getUser invoked
true
getUser invoked
true

从输出结果可以看出,每次请求均须重新添加数据

补充:

  • 添加数据的一般方法中,可包含参数,并且可用@RequestParam绑定数据,如:
@ModelAttribute("user")
public UserInfo getUser(@RequestParam("name") String userName )
{ ... }
  • 当命令参数的自动绑定存在时,自动绑定最后执行,即优先级更高,如访问:http://localhost:8080/myweb/model1?name=matt,输出结果为:matt 30

6、@SessionAttributes:用处不大,略

7、@Value:绑定SpEL表达式

public String test(@Value("#{systemProperties['java.vm.version']}") String jvmVersion)  

 8、@RequestBody

@RequestBody用于绑定Content-Type: application/json的请求内容区数据,示例如下:

jackson依赖

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>

控制器

@RequestMapping("/json")
@ResponseBody
public String testJson(@RequestBody UserInfo userInfo) {
System.out.println(userInfo.getName() + " " + userInfo.getAge());
return "testConverter";
}

测试(http请求包,使用Fiddler发生请求)

POST http://localhost:8080/myweb/json HTTP/1.1
Content-Type: application/json;charset=UTF-8 {"name":"matt","age":30}

参考:

请求映射规则详解 —— 跟着开涛学SpringMVC

数据绑定(1)—— 跟着开涛学SpringMVC

数据绑定(2)—— 跟着开涛学SpringMVC

Spring MVC 使用介绍(六)—— 注解式控制器(二):请求映射与参数绑定的更多相关文章

  1. 【spring springmvc】springmvc使用注解声明控制器与请求映射

    目录 概述 壹:注解说明 贰:实现注解声明控制器与请求映射 一:使用controller 二:配置包扫描与视图解析器 1.配置包扫描 2.配置试图解析器 三:配置部署描述符 1.读取spring-mv ...

  2. Spring MVC 使用介绍(五)—— 注解式控制器(一):基本介绍

    一.hello world 相对于基于Controller接口的方式,基于注解方式的配置步骤如下: HandlerMapping 与HandlerAdapter 分别配置为RequestMapping ...

  3. spring(6)--注解式控制器

    6.1.注解式控制器简介 一.Spring2.5之前,我们都是通过实现Controller接口或其实现来定义我们的处理器类.已经@Deprecated.   二.Spring2.5引入注解式处理器支持 ...

  4. SpringMVC强大的数据绑定(2)——第六章 注解式控制器详解

    SpringMVC强大的数据绑定(2)——第六章 注解式控制器详解 博客分类: 跟开涛学SpringMVC   6.6.2.@RequestParam绑定单个请求参数值 @RequestParam用于 ...

  5. spring(7)--注解式控制器的数据验证、类型转换及格式化

    7.1.简介 在编写可视化界面项目时,我们通常需要对数据进行类型转换.验证及格式化. 一.在Spring3之前,我们使用如下架构进行类型转换.验证及格式化: 流程: ①:类型转换:首先调用Proper ...

  6. 03springMVC注解式控制器开发

    注解式控制器开发简介 注解式控制器开发HelloWorld HelloWorld的运行流程 处理器定义 REST简介 URL路径映射 数据绑定 不同的Model有相同的属性的处理 静态资源的处理 1  ...

  7. Spring MVC 使用介绍(十四)文件上传下载

    一.概述 文件上传时,http请求头Content-Type须为multipart/form-data,有两种实现方式: 1.基于FormData对象,该方式简单灵活 2.基于<form> ...

  8. Spring MVC 使用介绍(十三)数据验证 (一)基本介绍

    一.消息处理功能 Spring提供MessageSource接口用于提供消息处理功能: public interface MessageSource { String getMessage(Strin ...

  9. J2EE进阶(十三)Spring MVC常用的那些注解

    Spring MVC常用的那些注解 前言 Spring从2.5版本开始在编程中引入注解,用户可以使用@RequestMapping, @RequestParam,@ModelAttribute等等这样 ...

随机推荐

  1. MySQL如何修改密码

    以下几种方法可供选择 第一种方式: 最简单的方法就是借助第三方工具Navicat for MySQL来修改,方法如下: 1.登录mysql到指定库,如:登录到test库. 2.然后点击上方“用户”按钮 ...

  2. 博弈论进阶之SG函数

    SG函数 个人理解:SG函数是人们在研究博弈论的道路上迈出的重要一步,它把许多杂乱无章的博弈游戏通过某种规则结合在了一起,使得一类普遍的博弈问题得到了解决. 从SG函数开始,我们不再是单纯的同过找规律 ...

  3. 无依赖简单易用的Dynamics 365公共视图克隆工具

    本人微信公众号:微软动态CRM专家罗勇 ,回复279或者20180818可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . Dy ...

  4. WLST

    Master Note on WebLogic Server Scripting Tool (WLST) Usage, Sample Scripts and Known Issues Deployin ...

  5. 2019Java查漏补缺(一)

    看到一个总结的知识: 感觉很全面的知识梳理,自己在github上总结了计算机网络笔记就很累了,猜想思维导图的方式一定花费了作者很大的精力,特共享出来.原文:java基础思维导图 自己学习的查漏补缺如下 ...

  6. AngularJS学习之旅—AngularJS Scope作用域(五)

    1.AngularJS Scope(作用域) Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带. Scope 是一个对象,有可用的方法和属性. Sco ...

  7. 周末班:Python基础之网络编程

    一.楔子 你现在已经学会了写python代码,假如你写了两个python文件a.py和b.py,分别去运行,你就会发现,这两个python的文件分别运行的很好.但是如果这两个程序之间想要传递一个数据, ...

  8. C#动态调用webService出现 基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。

    这里因为的原因是https请求要检查证书,有些证书不正确的,网页不会正常展示内容,而会返回链接不安全,是否继续.不安全的链接是否继续. 详情参考: C#动态调用webService出现 基础连接已经关 ...

  9. kernel笔记——网络收发包流程

    本文将介绍网络连接建立的过程.收发包流程,以及其中应用层.tcp层.ip层.设备层和驱动层各层发挥的作用. 应用层 对于使用socket进行网络连接的服务器端程序,我们会先调用socket函数创建一个 ...

  10. R语言学习——矩阵

    > #矩阵是一个二维数组,每个元素都拥有相同的模式(数值型.字符型或者逻辑型).通过matrix()创建,一般使用格式为:mymatrix<-matrix(vector,nrow=numb ...