1-这种是最常用的表单参数提交,ContentType指定为application/x-www-form-urlencoded,也就是会进行URL编码。

1.1-对象类型实体Bean接收请求参数(表单实体也可以用@ModelAttribute("UserForm"))
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public String login(UserForm userForm, HttpSession session, Model model){
if("wangguodong".equals(userForm.getUname()) && "123".equals(userForm.getUpass())){ //用户名和密码都相等
session.setAttribute("u", userForm);
return "main" ; //登录成功,跳到主页面
}else{
model.addAttribute("messageError", "用户名或密码错误") ;
return "login" ;
}
}
拓展底层:1>因为没有使用注解,最终的参数处理器为ServletModelAttributeMethodProcessor,主要是把HttpServletRequest中的表单参数封装到MutablePropertyValues实例中,
再通过参数类型实例化(通过构造反射创建UserForm实例),反射匹配属性进行值的填充
2>实际上RequestParamMethodArgumentResolver依赖WebConversionService中Converter列表进行参数转换:因为没有UserForm到String的转换器,添加一个
org.springframework.core.convert.converter.Converter实现即可   

  1.2-非对象类型单个参数接收:通过处理方法的形参接收请求参数(就是直接把表单参数写在控制类相应方法的形参中,形参名称与请求参数名称可以不一致时用@RequestParam(name = "name"))
@PostMapping(value = "/post")

public String post(@RequestParam(name = "name") String name,
@RequestParam(name = "age") Integer age) {
String content = String.format("name = %s,age = %d", name, age);
log.info(content);
return content;
}
拓展底层:1>这种情况下,用到的参数处理器是RequestParamMapMethodArgumentResolver。

2-其他参数主要包括请求头、Cookie、Model、Map等相关参数,还有一些并不是很常用或者一些相对原生的属性值获取;例如HttpServletRequest、HttpServletResponse等)

  2.1HttpServletRequest
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public String login(HttpServletRequest request, Model model){
String uname = request.getParameter("uname") ;
String upass = request.getParameter("upass") ;
if("wangguodong".equals(uname) && "123".equals(upass)){ //用户名和密码都相等
return "main" ; //登录成功,跳到主页面
}else{
model.addAttribute("messageError", "用户名或密码错误") ;
return "login" ;
}
}
  2.2请求头的值主要通过@RequestHeader注解的参数获取,
@PostMapping(value = "/header")
public String header(@RequestHeader(name = "Content-Type") String contentType) {
return contentType;
}
拓展底层:1>参数处理器是RequestHeaderMethodArgumentResolver,需要在注解中指定请求头的Key。
  2.3Cookie的值主要通过@CookieValue注解的参数获取,
@PostMapping(value = "/cookie")
public String cookie(@CookieValue(name = "JSESSIONID") String sessionId) {
return sessionId;}
拓展底层:1>参数处理器为ServletCookieValueMethodArgumentResolver,需要在注解中指定Cookie的Key。
  2.4Model类型参数
@GetMapping(value = "/model")
public String model(Model model, ModelMap modelMap) {
log.info("{}", model == modelMap);
return "success";
}
拓展底层:1>Model类型参数的处理器是ModelMethodProcessor,实际上处理此参数是直接返回ModelAndViewContainer实例中的Model(ModelMap类型),因为要桥接不
同的接口和类的功能,因此回调的实例是BindingAwareModelMap类型,此类型继承自ModelMap同时实现了Model接口。ModelMap或者Model中添加的属性项会附加到
HttpRequestServlet中带到页面中进行渲染。
  2.5Errors或者BindingResult参数
@PostMapping(value = "/errors")
public String errors(@RequestBody @Validated ErrorsModel errors, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
for (ObjectError objectError : bindingResult.getAllErrors()) {
log.warn("name={},message={}", objectError.getObjectName(), objectError.getDefaultMessage());
}
}
return errors.toString();}//ErrorsModel@Data@NoArgsConstructorpublic class ErrorsModel {
@NotNull(message = "id must not be null!")
private Integer id;
@NotEmpty(message = "errors name must not be empty!")
private String name;
}

拓展底层:1>Errors其实是BindingResult的父接口,BindingResult主要用于回调JSR参数校验异常的属性项,如果JSR校验异常,一般会抛出
MethodArgumentNotValidException异常,并且会返回400(Bad Request),见全局异常处理器DefaultHandlerExceptionResolver。Errors类型
的参数处理器为ErrorsMethodArgumentResolver。
  2.6Value参数
@GetMapping(value = "/value")
public String value(@Value(value = "${spring.application.name}") String name) {
log.info("spring.application.name={}", name);
return name;
}
拓展底层:1>控制器方法的参数可以是@Value注解修饰的参数,会从Environment中装配和转换属性值到对应的参数中(也就是参数的来源并不是请求体),
参数处理器为ExpressionValueMethodArgumentResolver。
 2.7Map类型参数的范围相对比较广,对应一系列的参数处理器,

注意区别使用了上面提到的部分注解的Map类型和完全不使用注解的Map类型参数,两者的处理方式不相同。下面列举几个相对典型的Map类型参数处理例子。

不使用任何注解的Map<String,Object>参数
这种情况下参数实际上直接回调ModelAndViewContainer中的ModelMap实例,参数处理器为MapMethodProcessor,往Map参数中添加的属性将会带到页面中。

使用@RequestParam注解的Map<String,Object>参数
这种情况下的参数处理器为RequestParamMapMethodArgumentResolver,使用的请求方式需要指定ContentType为x-www-form-urlencoded,不能使用application/json的

@PostMapping(value = "/map")
public String mapArgs(@RequestParam Map<String, Object> map) {
log.info("{}", map);
return map.toString();
}

使用@RequestHeader注解的Map<String,Object>参数
这种情况下的参数处理器为RequestHeaderMapMethodArgumentResolver,作用是获取请求的所有请求头的Key-Value。

使用@PathVariable注解的Map<String,Object>参数
这种情况下的参数处理器为PathVariableMapMethodArgumentResolver,作用是获取所有路径参数封装为Key-Value结构。

3-直接POST一个JSON字符串这种方式对于SpringMVC来说是比较友好的,只需要把ContentType设置为application/json,提交一个原始的JSON字符串即可:

@PostMapping(value = "/user-2")
public User saveUser2(@RequestBody User user) {
log.info(user.toString());
return user;
}
拓展底层:1>使用了@RequestBody注解,最终使用到的参数处理器为RequestResponseBodyMethodProcessor,实际上会用到
MappingJackson2HttpMessageConverter进行参数类型的转换,底层依赖到Jackson相关的包。

4-带请求路径参数(例如/user/{userId}是一个URL模板(URL模板中的参数占位符是{}),实际请求的URL为/user/1,那么通过匹配实际请求的URL和URL模板就能提取到userId为1)

@GetMapping(value = "/user/{name}/{age}")
public String findUser1(@PathVariable(value = "age") Integer age, @PathVariable(value = "name") String name) {
String content = String.format("name = %s,age = %d", name, age);
log.info(content);
return content;
}
注意一点是,@PathVariable的解析是按照value(name)属性进行匹配,和URL参数的顺序是无关的
其实路径参数支持正则表达式,例如我们在使用/sex/sex}接口的时候,要求sex必须是F(Female)或者M(Male)
@GetMapping(value = "/sex/{sex:M|F}")
public String findUser2(@PathVariable(value = "sex") String sex){
log.info(sex);
return sex;
}
拓展底层:1>对应的参数处理器为PathVariableMethodArgumentResolver。

5-文件上传在使用POSTMAN模拟请求的时候需要选择form-data,POST方式进行提交:
@PostMapping(value = "/file1")
public String file1(@RequestPart(name = "file1") MultipartFile multipartFile) {
String content = String.format("name = %s,originName = %s,size = %d",
multipartFile.getName(), multipartFile.getOriginalFilename(), multipartFile.getSize());
log.info(content);
return content;
}
拓展底层:1>可知MultipartFile实例的主要属性分别来自Content-Disposition、content-type和content-length,另外,InputStream用于读取请求体的最后部分
(文件的字节序列)。参数处理器用到的是RequestPartMethodArgumentResolver(记住一点,使用了@RequestPart和MultipartFile一定是使用此参数处理器)。

6-批量文件上传,我们一般需要接收一个MultipartFile集合,使用MultipartHttpServletRequest参数,直接调用getFiles方法获取MultipartFile列表

@PostMapping(value = "/parts")
public String partArgs(@RequestParam(name = "file") List<MultipartFile> parts) {
log.info("{}", parts);
return parts.toString();
}

拙见--springMVC的controller接受的请求参数的更多相关文章

  1. Spring MVC 接受的请求参数

    目录 1. 概述 2. 详解 2.1 处理查询参数 2.2 处理路径参数接受输入 2.3 处理表单 3. 补充内容 3.1 Ajax/JSON 输入 3.2 multipart参数 3.3 接收 he ...

  2. 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...

  3. SpringMVC基础-controller方法中的参数注解

    @PathVariable  映射 URL 绑定的占位符 带占位符的 URL 是 Spring3.0 新增的功能,该功能在 SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义 通过 ...

  4. 详解SpringMVC中Controller的方法中参数的工作原理——基于maven

    转自:http://www.tuicool.com/articles/F7byQn 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:ht ...

  5. 【MVC - 参数原理】详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/spring ...

  6. springmvc 注解式开发 接收请求参数

    1.校正请求参数名: 2.以对象形式整体接收 3.路径变量:

  7. Spring 请求方法的调用原理(Controller)和请求参数的获取的原理

    1.请求映射原理 所有的请求都会经过DispatcherServlet这个类,先了解它的继承树 本质还是httpServlet 原理图 测试 request请求携带的参数 ​ 从requestMapp ...

  8. 详解SpringMVC中Controller的方法中参数的工作原理

    Spring MVC中Controller的处理方法的参数可以是Integer,String,自定义对象,ServletRequest,ServletResponse,ModelAndView等等,非 ...

  9. Spring MVC(三)--控制器接受普通请求参数

    Spring MVC中控制器接受参数的类方式有以下几种: 普通参数:只要保证前端参数名称和传入控制器的参数名称一致即可,适合参数较少的情况: pojo类型:如果前端传的是一个pojo对象,只要保证参数 ...

随机推荐

  1. 学习HTML第二天

    今日内容: HTML标签:表单标签 CSS HTML标签:表单标签 表单项标签: input:可以通过type属性值,改变元素展示的样式 type属性: text:文本输入框,默认值 placehol ...

  2. 解决zabbix5字体中文口口乱码

    环境信息 系统:Ubuntu20.04 zabbix版本:5.4 解决方法一 此方法比较偷懒,就是不改变zabbix相关配置,直接用原名替换字体文件. 原字体字体名称为DejaVuSans.将方法二的 ...

  3. JavaScript学习总结5-作用域

    由于所有的全局变量都会绑定到window上,如果不同的JS文件,使用了相同的全局变量,会造成冲突,可以把自己的代码全部放入及定义的唯一空间中,减少全局命名冲突问题

  4. C# 滑动验证码|拼图验证|SlideCaptcha

    使用背景: 关于滑动验证码的使用场所还是非常多的,如: 调取短信接口之前,和 注册请求之前 或者 频繁会调用的接口 都需要加这个拼图验证.这里先上一下效果图吧(心中无码,自然高清). 话不多说,开撸! ...

  5. 设置 Visual Studio 总是以管理员身份运行

    话不多说直接上干货 第一步: 打开 Visual Studio 的安装目录,找到 devenv.exe,然后右键快捷菜单选择"兼容性疑难解答". 第二步: 选择故障排查选项 疑难解 ...

  6. SD卡之二:SD总线访问模式

    SD 卡是以命令.回应.数据流进行通讯. 1.命令:命令的长度是48位,命令以'0'开始,第2位为'1'表示主机发往SD卡的命令,最后以CRC和结束位'1'结尾. 2.回应:回应的长度是48位或者13 ...

  7. Linux中的RCU机制

    什么是RCU? RCU(Read-Copy Update),顾名思义就是读-拷贝-修改,它是基于其原理命名的.对于被RCU保护的共享数据结构,读者不需要获得任何锁就可以访问它,但写者在访问它时首先拷贝 ...

  8. [笔记] Slope Trick:解决一类凸代价函数的DP优化问题

    原理 当序列 DP 的转移代价函数满足 连续: 凸函数: 分段线性函数. 时,可以通过记录分段函数的最右一段 \(f_r(x)\) 以及其分段点 \(L\) 实现快速维护代价的效果. 如:$ f(x) ...

  9. 虚拟机(Vmvare)与配置,得到一台学习机

    准备: 1.Vmvare 2.CentOS7.4镜像 安装与配置操作系统: 1.配置虚拟机上网 2.配置静态ip地址 开始安装 1. 2.直接下一步选择我们准备好的镜像,然后下一步 3.修改虚拟机的名 ...

  10. kubevirt在360的探索之路(k8s接管虚拟化)

    来源:360云计算 KubeVirt是一个Kubernetes插件,在调度容器之余也可以调度传统的虚拟机.它通过使用自定义资源(CRD)和其它 Kubernetes 功能来无缝扩展现有的集群,以提供一 ...