目录
1、通过ServletAPI获取request对象
2、通过控制器方法的形参获取请求参数
3、使用@RequestParam注解
4、使用@RequestHeader注解
5、使用@CookieValue注解
6、通过POJO获取请求参数
7、解决请求参数的乱码问题
将HttpServletRequest对象作为控制器方法的形参
,此时request对象就是当前请求报文封装后的对象。
示例
模拟传参
ServletAPI传参
控制器方法
@RequestMapping("/testPath2")
public String testPath2(HttpServletRequest request){
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username = " + username);
System.out.println("password = " + password);
return "target";
}
分析,为什么可以用HttpServletRequest作为控制器方法的形参?
普通的方法中,形参需要我们在调用时,为其赋予值,也就是实参。
而控制器方法,调用者是SpringMVC的组件,那么可以认为是
SpringMVC根据控制器方法的参数列表,自动为其注入的对应的实参
。例如此处,形参类型是HttpServletRequest,需要一个请求对象,SpringMVC就会在调用它时,将当前请求的对象赋值给那个形参。
注意
这种方法不适合rest风格的传参
使用SpringMVC时,
能不用原生API就不用
。
在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,DispatcherServlet就会将请求参数赋值给相应的形参
示例
模拟传参
控制器形参传参
控制器方法
@RequestMapping("/testPath3")
public String testPath3(String username, String password){
System.out.println("username = " + username);
System.out.println("password = " + password);
return "target";
}
分析,为什么此处 直接将方法的参数列表与请求参数对应,就能自动获取到请求参数?
SpringMVC在调用这个控制器方法时,
如果这个方法的形参与请求参数的名称相同,就会自动赋值
。如果形参名和请求参数名不一致,则无法自动赋值。
如果请求参数中包含多个同名的请求参数,如何接收?
有两种方式,使用字符串数组或字符串来接收。
- 若使用
字符串数组
类型的形参,此参数的数组中包含了每一个数据
- 若使用
字符串
类型的形参,此参数的值为每个数据中间使用逗号拼接的结果
如果形参名和请求参数名不一致,就不能使用第二种方法,因为无法修改前端的源码。此时应该手动配置映射关系
。
@RequestParam注解的作用
将请求参数和控制器方法的形参创建映射关系
示例
模拟传参
@RequestParam传参
控制器方法
@RequestMapping("/testPath4")
public String testPath4(@RequestParam("username") String name, @RequestParam("password") String pwd){
System.out.println("name = " + name);
System.out.println("pwd = " + pwd);
return "target";
}
@RequestParam注解如何使用
在控制器方法的参数列表中使用
@RequestParam注解一共有三个属性:
- value(参数名):指定为形参赋值的请求参数的参数名
- required(是否必须):设置是否必须传输此请求参数,默认值为true
- 若设置为true,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,且没有设置 defaultValue属性,则页面报错400:Required String parameter 'xxx' is not present
- 若设置为 false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为 null
- defaultValue(缺省值):不管required属性值为true或false,当value所指定的请求参数没有传输,或传输的值为 "" 时,则使用默认值为形参赋值
为什么要在后端,规定请求参数的必要性和缺省值?
例如注册用户的操作,按理来说前端应该去做表单验证,确保用户名,密码等必填信息都存在才能提交表单。
但如果前端是菜鸟,没有做验证,大量空的用户名和密码涌入数据库,是很要命的。
所以,在后端我们也应该去做这个工作,作为数据库的最后一道防线,确保万无一失。
需要做的工作:
- 设置关键信息为必须传入的参数
- 设置所有信息的默认值,避免空值进入数据库造成污染
还有一个原因,接口是对外开放的,
不能依赖前端去保障安全性
,因为类似PostMan这类的接口测试工具,是可以绕过前端直接调用接口的。
@RequestHeader注解的作用
将请求头信息和控制器方法的形参创建映射关系
用于获取请求头的参数。
注意,通过形参获取请求头内容,没有默认映射,必须手动配置。
@RequestHeader注解如何使用
@RequestHeader注解一共有三个属性:value、required、defaultValue,用法同@RequestParam
@CookieValue注解的作用
将cookie数据和控制器方法的形参创建映射关系
用于获取Cookie中的参数
@CookieValue注解如何使用
@CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam
可以在控制器方法的形参位置设置一个实体类类型的形参
若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为对应属性赋值
示例
实体类
public class User implements Serializable {
private String username;
private String password;
public User() {
}
...
}
模拟传参
POJO传参
控制器方法
@RequestMapping("/testPath5")
public String testPath5(User user){
System.out.println("user = " + user);
return "target";
}
注意
Spring是通过反射,获取POJO的无参构造器来创建对象,所以POJO类必须有无参构造器。
为什么会发生乱码
只有post方式会出现乱码问题,因为tomcat8之后的get方法,都做好了处理。
为什么get方式不会发生乱码
Get是URL解码方式。默认解码格式是Tomcat8编码格式,而tomcat8在server.xml中设置,url的编码方式为UTF-8
为什么post方式会发生乱码
Post是实体内容解码方式。默认解码格式是request编码格式。与Tomcat8编码格式无关,默认以ISO8859-1的编码解析数据,所以需要想办法手动设置为UTF-8
如何解决post的乱码问题
必须在获取到请求参数之前,设置请求参数的编码方式,所以应该使用过滤器来处理,而且要配置到其他所有过滤器之前。
解决获取请求参数的乱码问题,可以使用SpringMVC提供的编码过滤器CharacterEncodingFilter,但是必须
在web.xml中进行注册
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceResponseEncoding
true
CharacterEncodingFilter
/*
SpringMVC中处理编码的过滤器一定要配置到其他过滤器之前
,否则无效