• 4、SpringMVC获取请求参数



    【尚硅谷】SSM框架全套教程-讲师:杨博超

    保持热爱、奔赴山河

    4、SpringMVC获取请求参数

    4.1、通过ServletAPI获取

    1 介绍

    在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数。

    2 演示

    <form th:action="@{/testParam}" method="post">
        用户名<input type="text" name="username">
        密码<input type="password" name="password">
        <input type="submit">
    form>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    @RequestMapping("/testParam")
    public String testParam(HttpServletRequest request) {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("username:" + username + ",password:" + password);
        return "success";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.2、通过控制器方法的形参获取请求参数

    1 介绍

    在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,在DispatcherServlet中就会将请求参数赋值给相应的形参。

    2 演示

    <a th:href="@{/test/param(username='admin',password=123456)}">测试获取请求参数--
    >/testParama><br>
    
    • 1
    • 2
    @RequestMapping("/test/param")
    public String testParam(String username, String password) {
        System.out.println("username:" + username + ",password:" + password);
        return "success";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3 注意

    若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串数组或者字符串类型的形参接收此请求参数。

    若使用字符串数组类型的形参,此参数的数组中包含了每一个数据。

    若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果。

    4.3、@RequestParam

    1 介绍

    @RequestParam:当请求参数与控制器方法的形参名称不一致,通过自定义名称来创建映射关系。

    @RequestParam注解一共有三个属性:

    value:

    • 设置与形参绑定的请求参数的名称。

    required:

    • 设置是否必须传输value多对应的请求参数。
    • 默认值为true,若设置为true时,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,且没有设置defaultValue属性,则页面报错400:Required String parameter ‘xxx’ is not present;
    • 设置为false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为null。

    defaultValue:

    • 当没有传输value所对应的请求参数时,为形参设置默认值,此时和required属性值无关。

    2 演示

    @RequestMapping("/test/param")
    public String testParam(@RequestParam("username") String username, @RequestParam("password") String password) {
        System.out.println("username:" + username + ",password:" + password);
        return "success";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.4、@RequestHeader

    1 介绍

    @RequestHeader:将请求头信息与控制器方法的形参绑定。

    @RequestHeader注解的三个属性:value、required、defaultValue,用法同@RequestParam。

    2 演示

    @RequestMapping("/test/param")
    public String testParam(@RequestParam("username") String username, @RequestParam("password") String password, @RequestHeader("referer") String referer) {
        System.out.println("referer:" + referer);
        System.out.println("username:" + username + ",password:" + password);
        return "success";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.5、@CookieValue

    1 介绍

    @CookieValue:将cookie数据和控制器方法的形参绑定。

    @CookieValue注解的三个属性:value、required、defaultValue,用法同@RequestParam。

    2 演示

    先通过session向浏览器发送一个名为JSESSIONID的cookie。

    @RequestMapping("/test/servletapi")
    public String testServletAPI(HttpServletRequest request) {
    		// 向浏览器响应一个JSESSIONID的Cookie
    		HttpSession session = request.getSession();
        return "success";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    @RequestMapping("/test/param")
    public String testParam(@RequestParam("username") String username, @RequestParam("password") String password, @CookieValue("JSESSIONID") String jsessionId) {
        System.out.println("JSESSIONID:" + jsessionId);
        System.out.println("username:" + username + ",password:" + password);
        return "success";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.6、通过实体类获取请求参数

    1 介绍

    在控制器方法的形参位置设置一个实体类类型的形参,实体类中的属性名与请求参数的参数名一致,就可以通过实体类类型的形参获取请求参数。

    2 演示

    <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">
    form>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    @RequestMapping("/testpojo")
    public String testPOJO(User user){
    	System.out.println(user);
    	return "success";
    }
    // 最终结果-->User{id=null, username='张三', password='123', age=23, sex='男',
    // email='123@qq.com'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.7、解决获取请求参数的乱码问题

    1 介绍

    解决获取请求参数的乱码问题,可以使用SpringMVC提供的编码过滤器CharacterEncodingFilter,但是必须在web.xml中进行注册。

    如果使用控制器方法传参的方式获取request,在设置字符集编码是无效的,因为request设置字符集编码必须写在所有代码前面

    Tomcat 7 中GET乱码问题,Tomcat 8.5中GET没有乱码问题。

    Tomcat 7Tomcat 8.5中POST都有乱码问题。

    2 GET解决方法

    是在Tomcat目录下—>conf—>server.xml文件,在Connector标签中添加URIEncoding=“UTF-8”。

    在这里插入图片描述

    3 POST解决方法

    使用Servlet的解决方法

    // servlet中解决方法,这个方法在SpringMVC中不能用,设置
    // 编码之前不能获取任何参数
    request.setCharacterEncoding("UTF-8");
    
    • 1
    • 2
    • 3

    使用SpringMVC提供的过滤器解决Tomcat中POST乱码问题。

    
    <filter>
        <filter-name>CharacterEncodingFilterfilter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <init-param>
            <param-name>encodingparam-name>
            <param-value>UTF-8param-value>
        init-param>
        <init-param>
            <param-name>forceEncodingparam-name>
            <param-value>trueparam-value>
        init-param>
    filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4 查看源码

    SpringMVC的编码过滤器传入的两个参数

    • encoding: 设置请求的编码
    • forceEncoding:设置 请求 + 响应 的编码

    查看CharacterEncodingFilter类

    构造方法(“UTF-8”,“true”)

    在这里插入图片描述
    自动调用三个参数构造方法
    forceRequestEncoding = “true”;
    forceResponseEncoding = “true”;
    在这里插入图片描述返回这两个变量
    在这里插入图片描述
    在这里插入图片描述

    解决乱码的具体实现

    当encoding不等于空,没有设置request,并且这两个变量true,设置request字符集,设置response字符集。
    在这里插入图片描述

    5 注意

    SpringMVC中处理编码的过滤器一定要配置到其他过滤器之前,否则无效。

    4.8、自定义过滤器(万能解决)

    package com.kuang.filter;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.util.Map;
    
    /**
    * 解决get和post请求 全部乱码的过滤器
    */
    public class GenericEncodingFilter implements Filter {
    
       @Override
       public void destroy() {
      }
    
       @Override
       public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
           //处理response的字符编码
           HttpServletResponse myResponse=(HttpServletResponse) response;
           myResponse.setContentType("text/html;charset=UTF-8");
    
           // 转型为与协议相关对象
           HttpServletRequest httpServletRequest = (HttpServletRequest) request;
           // 对request包装增强
           HttpServletRequest myrequest = new MyRequest(httpServletRequest);
           chain.doFilter(myrequest, response);
      }
    
       @Override
       public void init(FilterConfig filterConfig) throws ServletException {
      }
    
    }
    
    //自定义request对象,HttpServletRequest的包装类
    class MyRequest extends HttpServletRequestWrapper {
    
       private HttpServletRequest request;
       //是否编码的标记
       private boolean hasEncode;
       //定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
       public MyRequest(HttpServletRequest request) {
           super(request);// super必须写
           this.request = request;
      }
    
       // 对需要增强方法 进行覆盖
       @Override
       public Map getParameterMap() {
           // 先获得请求方式
           String method = request.getMethod();
           if (method.equalsIgnoreCase("post")) {
               // post请求
               try {
                   // 处理post乱码
                   request.setCharacterEncoding("utf-8");
                   return request.getParameterMap();
              } catch (UnsupportedEncodingException e) {
                   e.printStackTrace();
              }
          } else if (method.equalsIgnoreCase("get")) {
               // get请求
               Map<String, String[]> parameterMap = request.getParameterMap();
               if (!hasEncode) { // 确保get手动编码逻辑只运行一次
                   for (String parameterName : parameterMap.keySet()) {
                       String[] values = parameterMap.get(parameterName);
                       if (values != null) {
                           for (int i = 0; i < values.length; i++) {
                               try {
                                   // 处理get乱码
                                   values[i] = new String(values[i]
                                          .getBytes("ISO-8859-1"), "utf-8");
                              } catch (UnsupportedEncodingException e) {
                                   e.printStackTrace();
                              }
                          }
                      }
                  }
                   hasEncode = true;
              }
               return parameterMap;
          }
           return super.getParameterMap();
      }
    
       //取一个值
       @Override
       public String getParameter(String name) {
           Map<String, String[]> parameterMap = getParameterMap();
           String[] values = parameterMap.get(name);
           if (values == null) {
               return null;
          }
           return values[0]; // 取回参数的第一个值
      }
    
       //取所有值
       @Override
       public String[] getParameterValues(String name) {
           Map<String, String[]> parameterMap = getParameterMap();
           String[] values = parameterMap.get(name);
           return values;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108

    一般情况下,SpringMVC默认的乱码处理就已经能够很好的解决了!

    然后在web.xml中配置这个过滤器即可!

    乱码问题,需要平时多注意,在尽可能能设置编码的地方,都设置为统一编码 UTF-8!

  • 相关阅读:
    .NET 开源工作流: Slickflow流程引擎高级开发(十) -- BpmnJS流程设计器集成
    毕业设计-基于机器学习的二维码和条形码识别
    【UE5 C++基础 04】UHT基础
    [附源码]Python计算机毕业设计Django时间管理软件app
    unity-模块卸载重新安装
    electron使用electron-builder macOS windows 打包 签名 更新 上架
    Gitlab API调用给每个人生成一个token,操作api
    通过S3协议实现通用的文件存储服务中间件
    电脑开机密码忘了怎么办
    将数字每千分位用逗号隔开
  • 原文地址:https://blog.csdn.net/zhao854116434/article/details/126855655