获取请求数据
使用原生的Servlet API获取请求数据
java
// 处理注册请求
@PostMapping("/register/user")
public String register(HttpServletRequest request, HttpSession session, HttpServletResponse resp) {
// 获取请求参数
// HttpServletRequest\HttpSession\HttpServletResponse 都属于Servlet API,Spring MVC会自动将它们注入到方法参数中
String username = request.getParameter("username");
String password = request.getParameter("password");
return "success";
}
@RequestParam注解
@RequestParam的作用:将请求参数与方法上的形参映射
java
@PostMapping("/register/user/2")
public String register2(
// @RequestParam注解用于将请求参数绑定到方法参数上,value属性指定请求参数的名称,参数名可以和请求参数名不同
// 可以自动将请求参数转换为方法参数的类型,例如将字符串转换为整数、日期等
@RequestParam("username") String username,
@RequestParam("password") String password) {
return "success";
}
@RequestParam的required和defaultValue属性
required属性:设置该参数是否是必须的。默认true,默认参数是必须的,如果前端没有提交这个参数,则报错。如果设置为false。则不会报错。
defaultValue属性:给参数设置默认值,如果前端没传这个参数,则会使用默认值。
java
@PostMapping("/register/user/2")
public String register2(
// @RequestParam注解用于将请求参数绑定到方法参数上,value属性指定请求参数的名称,参数名可以和请求参数名不同
// 可以自动将请求参数转换为方法参数的类型,例如将字符串转换为整数、日期等
@RequestParam("username") String username,
@RequestParam("password") String password,
@RequestParam(value = "age",required = false,defaultValue = "20") Integer age) {
return "success";
}
依靠控制器方法上的形参名接收
如果请求的参数名和控制器方法上的形参名保持一致。那么 @RequestParam注解可以省略。
如果没对应上,则值为null。
java
@PostMapping("/register/user/3")
public String register3(String username, String password) {
// 这种方式要求请求参数的名称必须与方法参数的名称一致,Spring MVC会自动将请求参数绑定到方法参数上
return "success";
}
使用POJO类/JavaBean接收参数
要求:POJO类/JavaBean的属性名必须和请求参数的参数名保持一致。
底层原理使用反射机制。并且调用JavaBean的set方法,set方法的方法名是关键,springMVC是通过set方法的方法名将对应的参数注入到JavaBean中的。
java
@PostMapping("/register/user/4")
public String register4(User user) {
// 这种方式要求请求参数的名称必须与User类的属性名称一致,Spring MVC会自动将请求参数绑定到User对象的属性上
return "success";
}
RequestHeader注解
作用:将请求头信息映射到方法的形参上。
和@RequestParam注解功能相似。
对于RequestHeader注解来说,也有三个属性:value、required、defaultValue,和RequestParam一样。
java
@PostMapping("/register/user/4")
public String register4(User user, @RequestHeader(value = "Referer",required = false,defaultValue = "") String referer) {
return "success";
}
CookieValue注解
作用:将提交的cookie数据映射到形参上。
同样有三个属性:value、required、defaultValue。
java
@PostMapping("/register/user/4")
public String register4(User user,
@RequestHeader(value = "Referer",required = false,defaultValue = "") String referer,
@CookieValue(value = "JSESSIONID",required = false,defaultValue = "") String jsessionId) {
// 这种方式要求请求参数的名称必须与User对象的属性名称一致,Spring MVC会自动将请求参数绑定到User对象的属性上
// @RequestHeader注解用于将请求头信息绑定到方法参数上,value属性指定请求头的名称
// @CookieValue注解用于将Cookie信息绑定到方法参数上,value属性指定Cookie的名称
return "success";
}
请求的中文乱码问题
get请求乱码
解决方法:对URI进行编码设置,在Tomcat的配置CATALINA_HOME/conf/server.xml文件中:设置Connector 标签,添加 URIEncoding="UTF-8"
tomcat9和10 不会乱码。因为他们已经默认设置URI编码为UTF-8.
对于tomcat8.默认是ISO。所以需要设置为UTF-8。
post请求乱码
解决办法:
java
// 这行代码必须在获取参数的代码之前执行,不能写在下面
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
在tomcat10中,已经自动帮我们解决了乱码问题。
在tomcat9和以前的版本,会出现乱码问题,需要手动解决。
第一种方案:自己编写一个过滤器!过滤器Filter在Servlet执行之前执行。
-
编写过滤器类
javapublic class CharacterEncodingFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 设置请求和响应的字符编码为UTF-8,解决中文乱码问题 servletRequest.setCharacterEncoding("UTF-8"); servletResponse.setContentType("text/html;charset=UTF-8"); // 将请求和响应对象传递给下一个过滤器或目标资源 filterChain.doFilter(servletRequest, servletResponse); } }-
在web.xml配置过滤器
xml<!-- 设置字符编码过滤器,解决post请求中文乱码问题--> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
第二种方案:使用内置过滤器解决,在web.xml中配置如下:
xml
<!-- 使用springmvc提供的字符编码过滤器,解决post请求中文乱码问题-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 设置字符集为UTF-8-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- 请求体和响应体都使用UTF-8字符集-->
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</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>
三个域对象
请求域:request(作用于一个请求中)
会话域:session(作用于一个会话中,浏览器打开到浏览器关闭期间,保存用户登录状态)
应用域:application(作用于一个应用,服务器启动到服务器关闭期间,记录网站在线人数)
request域对象
在springMVC中,在request域对象中共享数据有以下几种方式:
- 使用原生的Servlet API方式
- 使用Model接口
- 使用Map接口
- 使用ModelMap类
- 使用ModelAndView类
使用原生的Servlet API方式
controller中的代码
java
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request) {
// 将共享数据存入request域对象中
request.setAttribute("testRequestScope", "hello,servletAPI");
// 这个跳转视图默认是forward方式,request域对象中的数据可以共享到目标资源中
return "ok";
}
html代码用来取数据
html
<body>
<div th:text="${testRequestScope}"></div>
</body>
使用Model接口
不使用Servlet API,所以单元测试时比较方便。
java
@RequestMapping("/testModel")
public String testModel(Model model) {
// 将共享数据存入model中
model.addAttribute("testRequestScope", "hello,Model");
return "ok";
}
使用Map接口
java
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map) {
// 将共享数据存入map中
map.put("testRequestScope", "hello,Map");
return "ok";
}
使用ModelMap类
java
@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap) {
// 将共享数据存入modelMap中
modelMap.addAttribute("testRequestScope", "hello,ModelMap");
return "ok";
}
Model、Map、ModelMap三者之间的关系
表面上这三者是不同的类和接口,实际上底层都使用了同一个对象BindingAwareModelMap,。
这三者的方法表面上是返回了逻辑视图名称,是一个字符串,在底层实际上都是返回了ModelAndView对象。
使用ModelAndView类
ModelAndView类的实例封装了Model和View。也就是说它既封装了处理业务之后的数据,还封装跳转到哪个视图,使用它可以完成request域数据共享。
java
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(ModelAndView modelAndView) {
// 将共享数据存入modelAndView中
modelAndView.addObject("testRequestScope", "hello,ModelAndView");
// 设置视图名称
modelAndView.setViewName("ok");
return modelAndView;
}
这里需要注意:
- 方法返回值类型不是String.而是ModelAndView对象。
- ModelAndView不是出现在参数位置,而是在方法体中new出来的
- 需要调用addObject向域中存储数据
- 需要调用setViewName设置视图名称。
session域对象
使用原生Servlet API
java
@RequestMapping("/testSessionScope")
public String test(HttpSession session) {
// 将共享数据存入session域对象中
session.setAttribute("testSessionScope", "hello,Session");
return "ok";
}
html代码用来取数据
html
<body>
<div th:text="${session.testSessionScope}"></div>
</body>
使用SessionAttributes注解
使用SessionAttributes注解标注controller
java
@Controller
// @SessionAttributes注解:将指定的属性存储到session域对象中
// 表示 将modelMap中key为"x"和"y"的属性存储到session域对象中
@SessionAttributes(value = {"x", "y"})
public class SessionScopeTestController {
@RequestMapping("/testSessionAttribute")
public String testSessionAttribute(ModelMap modelMap) {
// 将共享数据存入session域对象中
modelMap.addAttribute("x", "hello,x");
modelMap.addAttribute("y", "hello,y");
return "ok";
}
}
application域对象
java
@RequestMapping("/testApplicationScope")
public String test(HttpServletRequest request) {
// 将共享数据存入application域对象中
ServletContext servletContext = request.getServletContext();
servletContext.setAttribute("testApplicationScope", "hello,Application");
return "ok";
}
html代码。用来取数据
html
<body>
<div th:text="${application.testApplicationScope}"></div>
</body>