找回密码
 立即注册
首页 业界区 业界 springMVC-获取前端请求的数据与三个作用域 ...

springMVC-获取前端请求的数据与三个作用域

钦娅芬 昨天 17:55
获取请求数据

使用原生的Servlet API获取请求数据
  1. // 处理注册请求
  2. @PostMapping("/register/user")
  3. public String register(HttpServletRequest request, HttpSession session, HttpServletResponse resp) {
  4.     // 获取请求参数
  5.     // HttpServletRequest\HttpSession\HttpServletResponse 都属于Servlet API,Spring MVC会自动将它们注入到方法参数中
  6.     String username = request.getParameter("username");
  7.     String password = request.getParameter("password");
  8.     return "success";
  9. }
复制代码
@RequestParam注解

@RequestParam的作用:将请求参数与方法上的形参映射
  1. @PostMapping("/register/user/2")
  2. public String register2(
  3.         // @RequestParam注解用于将请求参数绑定到方法参数上,value属性指定请求参数的名称,参数名可以和请求参数名不同
  4.         // 可以自动将请求参数转换为方法参数的类型,例如将字符串转换为整数、日期等
  5.         @RequestParam("username") String username,
  6.         @RequestParam("password") String password) {
  7.     return "success";
  8. }
复制代码
@RequestParam的required和defaultValue属性

required属性:设置该参数是否是必须的。默认true,默认参数是必须的,如果前端没有提交这个参数,则报错。如果设置为false。则不会报错。
defaultValue属性:给参数设置默认值,如果前端没传这个参数,则会使用默认值。
  1. @PostMapping("/register/user/2")
  2. public String register2(
  3.         // @RequestParam注解用于将请求参数绑定到方法参数上,value属性指定请求参数的名称,参数名可以和请求参数名不同
  4.         // 可以自动将请求参数转换为方法参数的类型,例如将字符串转换为整数、日期等
  5.         @RequestParam("username") String username,
  6.         @RequestParam("password") String password,
  7.         @RequestParam(value = "age",required = false,defaultValue = "20") Integer age) {
  8.     return "success";
  9. }
复制代码
依靠控制器方法上的形参名接收

如果请求的参数名和控制器方法上的形参名保持一致。那么 @RequestParam注解可以省略。
如果没对应上,则值为null。
  1. @PostMapping("/register/user/3")
  2. public String register3(String username, String password) {
  3.     // 这种方式要求请求参数的名称必须与方法参数的名称一致,Spring MVC会自动将请求参数绑定到方法参数上
  4.     return "success";
  5. }
复制代码
使用POJO类/JavaBean接收参数

要求:POJO类/JavaBean的属性名必须和请求参数的参数名保持一致。
底层原理使用反射机制。并且调用JavaBean的set方法,set方法的方法名是关键,springMVC是通过set方法的方法名将对应的参数注入到JavaBean中的。
  1. @PostMapping("/register/user/4")
  2. public String register4(User user) {
  3.     // 这种方式要求请求参数的名称必须与User类的属性名称一致,Spring MVC会自动将请求参数绑定到User对象的属性上
  4.     return "success";
  5. }
复制代码
RequestHeader注解

作用:将请求头信息映射到方法的形参上。
和@RequestParam注解功能相似。
对于RequestHeader注解来说,也有三个属性:value、required、defaultValue,和RequestParam一样。
  1. @PostMapping("/register/user/4")
  2. public String register4(User user, @RequestHeader(value = "Referer",required = false,defaultValue = "") String referer) {
  3.     return "success";
  4. }
复制代码
CookieValue注解

作用:将提交的cookie数据映射到形参上。
同样有三个属性:value、required、defaultValue。
  1. @PostMapping("/register/user/4")
  2. public String register4(User user,
  3.                         @RequestHeader(value = "Referer",required = false,defaultValue = "") String referer,
  4.                         @CookieValue(value = "JSESSIONID",required = false,defaultValue = "") String jsessionId) {
  5.     // 这种方式要求请求参数的名称必须与User对象的属性名称一致,Spring MVC会自动将请求参数绑定到User对象的属性上
  6.     // @RequestHeader注解用于将请求头信息绑定到方法参数上,value属性指定请求头的名称
  7.     // @CookieValue注解用于将Cookie信息绑定到方法参数上,value属性指定Cookie的名称
  8.     return "success";
  9. }
复制代码
请求的中文乱码问题

get请求乱码

解决方法:对URI进行编码设置,在Tomcat的配置CATALINA_HOME/conf/server.xml文件中:设置Connector 标签,添加   URIEncoding="UTF-8"

tomcat9和10 不会乱码。因为他们已经默认设置URI编码为UTF-8.
对于tomcat8.默认是ISO。所以需要设置为UTF-8。
post请求乱码

解决办法:
  1. // 这行代码必须在获取参数的代码之前执行,不能写在下面
  2. request.setCharacterEncoding("UTF-8");
  3. String username = request.getParameter("username");
复制代码
在tomcat10中,已经自动帮我们解决了乱码问题。
在tomcat9和以前的版本,会出现乱码问题,需要手动解决。
第一种方案:自己编写一个过滤器!过滤器Filter在Servlet执行之前执行。

  • 编写过滤器类
    1. public class CharacterEncodingFilter implements Filter {
    2.     @Override
    3.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    4.         // 设置请求和响应的字符编码为UTF-8,解决中文乱码问题
    5.         servletRequest.setCharacterEncoding("UTF-8");
    6.         servletResponse.setContentType("text/html;charset=UTF-8");
    7.         // 将请求和响应对象传递给下一个过滤器或目标资源
    8.         filterChain.doFilter(servletRequest, servletResponse);
    9.     }
    10. }
    复制代码

    • 在web.xml配置过滤器
      1.     <filter>
      2.         <filter-name>characterEncodingFilter</filter-name>
      3.         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      4.     </filter>
      5.     <filter-mapping>
      6.         <filter-name>characterEncodingFilter</filter-name>
      7.         <url-pattern>/*</url-pattern>
      8.     </filter-mapping>
      复制代码

第二种方案:使用内置过滤器解决,在web.xml中配置如下:
  1.     <filter>
  2.         <filter-name>characterEncodingFilter</filter-name>
  3.         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  4.         <init-param>
  5.             <param-name>encoding</param-name>
  6.             <param-value>UTF-8</param-value>
  7.         </init-param>
  8.         <init-param>
  9.             <param-name>forceRequestEncoding</param-name>
  10.             <param-value>true</param-value>
  11.         </init-param>
  12.         <init-param>
  13.             <param-name>forceResponseEncoding</param-name>
  14.             <param-value>true</param-value>
  15.         </init-param>
  16.     </filter>
  17.     <filter-mapping>
  18.         <filter-name>characterEncodingFilter</filter-name>
  19.         <url-pattern>/*</url-pattern>
  20.     </filter-mapping>
复制代码
三个域对象

请求域:request(作用于一个请求中)
会话域:session(作用于一个会话中,浏览器打开到浏览器关闭期间,保存用户登录状态)
应用域:application(作用于一个应用,服务器启动到服务器关闭期间,记录网站在线人数)
request域对象

在springMVC中,在request域对象中共享数据有以下几种方式:

  • 使用原生的Servlet API方式
  • 使用Model接口
  • 使用Map接口
  • 使用ModelMap类
  • 使用ModelAndView类
使用原生的Servlet API方式

controller中的代码
  1. @RequestMapping("/testServletAPI")
  2. public String testServletAPI(HttpServletRequest request) {
  3.     // 将共享数据存入request域对象中
  4.     request.setAttribute("testRequestScope", "hello,servletAPI");
  5.     // 这个跳转视图默认是forward方式,request域对象中的数据可以共享到目标资源中
  6.     return "ok";
  7. }
复制代码
html代码用来取数据
  1. [/code][size=4]使用Model接口[/size]
  2. 不使用Servlet API,所以单元测试时比较方便。
  3. [code]@RequestMapping("/testModel")
  4. public String testModel(Model model) {
  5.     // 将共享数据存入model中
  6.     model.addAttribute("testRequestScope", "hello,Model");
  7.     return "ok";
  8. }
复制代码
使用Map接口
  1. @RequestMapping("/testMap")
  2. public String testMap(Map<String, Object> map) {
  3.     // 将共享数据存入map中
  4.     map.put("testRequestScope", "hello,Map");
  5.     return "ok";
  6. }
复制代码
使用ModelMap类
  1. @RequestMapping("/testModelMap")
  2. public String testModelMap(ModelMap modelMap) {
  3.     // 将共享数据存入modelMap中
  4.     modelMap.addAttribute("testRequestScope", "hello,ModelMap");
  5.     return "ok";
  6. }
复制代码
Model、Map、ModelMap三者之间的关系

表面上这三者是不同的类和接口,实际上底层都使用了同一个对象BindingAwareModelMap,。
这三者的方法表面上是返回了逻辑视图名称,是一个字符串,在底层实际上都是返回了ModelAndView对象。
使用ModelAndView类

ModelAndView类的实例封装了Model和View。也就是说它既封装了处理业务之后的数据,还封装跳转到哪个视图,使用它可以完成request域数据共享。
  1. @RequestMapping("/testModelAndView")
  2. public ModelAndView testModelAndView(ModelAndView modelAndView) {
  3.     // 将共享数据存入modelAndView中
  4.     modelAndView.addObject("testRequestScope", "hello,ModelAndView");
  5.     // 设置视图名称
  6.     modelAndView.setViewName("ok");
  7.     return modelAndView;
  8. }
复制代码
这里需要注意:

  • 方法返回值类型不是String.而是ModelAndView对象。
  • ModelAndView不是出现在参数位置,而是在方法体中new出来的
  • 需要调用addObject向域中存储数据
  • 需要调用setViewName设置视图名称。
session域对象

使用原生Servlet API
  1. @RequestMapping("/testSessionScope")
  2. public String test(HttpSession session) {
  3.     // 将共享数据存入session域对象中
  4.     session.setAttribute("testSessionScope", "hello,Session");
  5.     return "ok";
  6. }
复制代码
html代码用来取数据
  1. [/code][size=4]使用SessionAttributes注解[/size]
  2. 使用SessionAttributes注解标注controller
  3. [code]@Controller
  4. // @SessionAttributes注解:将指定的属性存储到session域对象中
  5. // 表示 将modelMap中key为"x"和"y"的属性存储到session域对象中
  6. @SessionAttributes(value = {"x", "y"})
  7. public class SessionScopeTestController {
  8.    
  9.     @RequestMapping("/testSessionAttribute")
  10.     public String testSessionAttribute(ModelMap modelMap) {
  11.         // 将共享数据存入session域对象中
  12.         modelMap.addAttribute("x", "hello,x");
  13.         modelMap.addAttribute("y", "hello,y");
  14.         return "ok";
  15.     }
  16. }
复制代码
application域对象
  1. @RequestMapping("/testApplicationScope")
  2. public String test(HttpServletRequest request) {
  3.     // 将共享数据存入application域对象中
  4.     ServletContext servletContext = request.getServletContext();
  5.     servletContext.setAttribute("testApplicationScope", "hello,Application");
  6.     return "ok";
  7. }
复制代码
html代码。用来取数据
[code][/code]
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册