SpringMVC获取请求参数
1、通过servletAPI获取(SpringMVC中一般不用)
首先创建一个测试页面
直接new一个ParamController类,在类中去调用HttpServletRequest接口中的方法获取请求参数。
@Controller
public class ParamController {
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request){
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username:"+username+",password:"+password);
return "success";
}
}
运行后没有问题,可以获取并打印输出到终端。
注意
如果用占位符的方式写路径和请求参数就不能用Servlet接口的这种方法获取请求参数了,因为url的后面没有username和password。当然实际项目中一般不会用servletAPI来获取请求参数,Spring提供了更为简单好用的接口来获取请求参数。
2、使用控制器的形参来获取请求参数
参数不同名的情况
这里在测试的html页面中再加入一行超链接。
然后在控制器中编写一个方法
@RequestMapping("/testParam")
public String testParam(String username,String password){
System.out.println("username:"+username+",password:"+password);
return "success";
}
运行后点击超链接
可以看到也成功获取了请求的参数。
注意
该方法只要使你控制器中的形参名等于你的请求参数名,该控制器的方法就会自动获取你的请求参数赋值到该请求参数名的String类对象中,非常方便。
有多个同名参数的情况
首先写一个form表单来测试一下这种情况
<form th:action="@{testParam}" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
爱好:<input type="checkbox" name="hobby" value="a"><br>
爱好:<input type="checkbox" name="hobby" value="b"><br>
爱好:<input type="checkbox" name="hobby" value="c"><br>
<input type="submit" value="测试使用控制器的形参获取多个同名请求参数">
</form>
再之前的Controller里面加上一个hobby再输出
@RequestMapping("/testParam")
public String testParam(String username,String password, String hobby){
System.out.println("username:"+username+",password:"+password+",hobby:"+hobby);
return "success";
}
从控制台的输出可见hobby的输出格式是以逗号分割。
还有一种方式是将hobby参数设置为数组。
将hobby设置为数组后用Arrays.toString(hobby)将其输出,得到控制台信息
可以看到成功以数组形式输出了。
形参名和请求参数名不一致的情况
@RequestParam注解
这种情况下,SpringMVC提供了一个叫@RequestParam()的注解,来将请求参数与形参建立映射关系。否则则会输出null,也就是获取不到。
将上面的控制器方法中的username改成user,再使用该注解
@RequestMapping("/testParam")
public String testParam(
@RequestParam("username") String user,
String password,
String[] hobby){
System.out.println("username:"+user+",password:"+password+",hobby:"+ Arrays.toString(hobby));
return "success";
}
可以看到该控制器方法任然获取到了该请求参数的值。
注意
- @RequestParam中还有一个required参数,默认值是true,如果未设置该参数,那么该请求参数就是必须的,如果没有传入该请求参数则会报找不到该请求参数的错,如果设置为false则会传入默认值null。
- @RequestParam中还有一个defaultValue参数,叫默认值,可以设置请求参数的默认值,即该请求参数值若为null,也就是不传或者传空字符串,那么就可通过这个形参来设置该请求参数的值。
3、@RequestHeader注解获取请求头信息
该注解与@RequestParam注解使用方法是一样的,都有三个参数,value,required,defaultValue。功能也类似,只不过该注解的value表示的是将请求头信息与形参建立映射关系。否则则会输出null,也就是获取不到。另外两个参数的功能是一样的。
使用方法如下
4、@CookieValue注解获取Cookie信息
该注解与@RequestParam注解使用方法是一样的,都有三个参数,value,required,defaultValue。功能也类似,只不过该注解的value表示的是将cookie信息与形参建立映射关系。否则则会输出null,也就是获取不到。另外两个参数是一样的。
使用方法如下
该demo由于没有创建cookie,所以我们需要再之前创建的testservletAPI的方法中先创建一个session,如下
然后再Controller方法中去使用CookieValue注解才能获取,不然提示没有这个参数。
控制台输出如下
注意
请求之前需要先请求一下testservletAPI方法,将cookie信息创建出来
我点击之后,可以看到,cookie信息已经被创建出来了且跟控制台中输出的是一模一样的。
5、通过POJO对象获取请求参数
有时候我们的请求参数很多,比如说我们需要做一个添加或修改的功能,需要用到数据库,那么这是我们需要添加的数据就要对应数据库中的字段。数据库同样的会对于实体类的对象。SpringMVC中有一个很方便的方法,可以通过实体类的对象来接收请求参数,前提是请求参数名需要与实体类对象名保持一致。
这里我再创建一个表单和实体类来验证。
form表单
<form th:action="@{/testPOJO}" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
性别:<input type="radio" name="sex" value="男"><input type="radio" name="sex" value="女"><br>
密码:<input type="text" name="age"><br>
密码:<input type="text" name="email"><br>
<input type="submit" value="使用实体类接收请求参数">
</form>
下面根据表单来创建实体类
**注意:**这里除了这些属性外,还需要设置有参构造,无参构造,setter,getter和tostring,这个直接生成就行。
然后就是控制器方法
很简单的写法,下面运行一下,填上信息
提交成功后可以看到控制台上输出了这个user对象
这里sex为??是因为我将表单中的sex那一行中的value写的是中文,这个是字符编码的问题,修改一下字符编码或者将value改成数字就行了。
该方式的原理是反射。
6、获取请求参数乱码问题的解决
为什么会出现乱码?
浏览器发送请求的方式有两种:get和post,这两种方式请求参数出现乱码的原因是不一样的。
get:由于tomcat版本太低,未设置乱码过滤器,若是7以上版本,则不会出现这个问题。
解决:在server.xml中改端口号的地方加上一个属性URIEncoding=“utf-8”
post:编码方式不匹配,需要设置编码方式
**注意:**在控制器方法执行之前,DispatcherServlet就已经获取了请求参数,所以我们既不能在DispatcherServlet中设置编码方式,也不能在控制器方法中设置编码方式,因为这两个时候都已经获取完了,在里面设置也没有用,那么就需要在DispatcherServlet获取请求参数之前设置编码方式,服务器中有三大组件,监听器,过滤器、servlet,其中监听器ServletContextListenner的加载时间是最早的,然后是过滤器fliter,最后才是servlet,但监听器是监听的作用,只执行一次,而每一次发送请求都需要先经过过滤器的处理,处理完后再交给DispatcherServlet处理,所以应该通过过滤器设置编码。
解决:在web.xml中注册并进行配置过滤器,在过滤器中强制改变编码方式。
<!--配置过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
7、总结
- 使用控制器形参获取请求参数时,需要保证形参名与请求参数名一致
- 如果请求出现多个同名参数,可以在控制器方法的形参上用String类对象或数组对象来接收
- String类对象接收时多个 参数用逗号分隔
- 数组对象接收直接储存在数组。
- 若请求参数名与形参名不一致,需要使用@RequestParam注解将请求参数与形参建立映射关系
- 若需要获取请求头中的信息,则可以使用@RequestHeader注解,使用方法与@RequestParam一致。
- 若需要获取Cookie中的信息,则可以使用@CookieValue注解,使用方法也与@RequestParam一致。
- 若需要用实体类对象来接收请求参数,需要保证实体类对象中的属性名与请求参数名一致。
- 出现乱码时需要在web.xml配置文件中通过注册配置过滤器来设置编码。