zoukankan      html  css  js  c++  java
  • SpringMVC 接收表单数据、数据绑定、解决请求参数中文乱码

    接收表单数据有3种方式。

    1、使用简单类型接收表单数据(绑定简单数据类型)

    表单:

      <form action="${pageContext.request.contextPath}/userController/handler" method="post">
        用户名:<input name="username" type="text" /><br />
        密码:<input name="password" type="password" /><br />
        年龄:<input name="age" type="number" /><br />
        <button type="submit">提交</button>
      </form>

    action会有提示,但必须要在前面加${pageContext.request.contextPath}来获取项目名(/项目名的形式),否则会把后面的路径直接拼接到域名后面。

    如果是SpringBoot,则不用加${pageContext.request.contextPath}。

    controller:

    @org.springframework.stereotype.Controller
    @RequestMapping("/userController")
    public class UserController{
    
        @RequestMapping("/handler")
        public ModelAndView handler(String username, String password, int age){
            ModelAndView mav = new ModelAndView("user_info");
            mav.addObject("username", username);
            mav.addObject("password", password);
            mav.addObject("age", age);
            return mav;
        }
    
    }

    参数名要和表单字段的name一致。

    SpringMVC会自动将请求参数转换为需要的数据类型。

    如果表单字段很多,业务方法要写很多参数,太麻烦,不推荐。


    2、使用pojo类接收表单数据(绑定pojo类型)

    pojo:

    public class User {
        private String username;
        private String password;
        private int age;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }

    属性名要与表单字段的name一致。

    controller:

    @org.springframework.stereotype.Controller
    @RequestMapping("/userController")
    public class UserController{
    
        @RequestMapping("/handler")
        public ModelAndView handler(User user){
            ModelAndView mav = new ModelAndView("user_info");
            mav.addObject("user", user);
            return mav;
        }
    
    }

    推荐使用。


    3、使用扩展类接收表单数据(绑定pojo的包装类)

    扩展类:

    public class UserExt {
        private User user;
        //此处省略其它成员变量
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    }

    把bean写为成员变量。

    表单:

      <form action="${pageContext.request.contextPath}/userController/handler" method="post">
        用户名:<input name="user.username" type="text" /><br />
        密码:<input name="user.password" type="password" /><br />
        年龄:<input name="user.age" type="number" /><br />
        <button type="submit">提交</button>
      </form>

    这里的user对应扩展类中的成员变量名。

    controller:

    @org.springframework.stereotype.Controller
    @RequestMapping("/userController")
    public class UserController{
    
        @RequestMapping("/handler")
        public ModelAndView handler(UserExt userExt){
            ModelAndView mav = new ModelAndView("user_info");
            mav.addObject("userExt", userExt);
            return mav;
        }
    
    }

    使用扩展类接收参数,主要是表单传过来的数据有一些不属于实体类,还需要用其它的成员变量来接收。


    单选框、复选框的数据接收

     单选框可用普通类型来接收。

    复选框常用于同时勾选多个选项,比如选择爱好、批量删除等(同一个name、多个value)。

    复选框使用数组来接收,复选框的name要与数组名一致。

    @org.springframework.stereotype.Controller
    @RequestMapping("/userController")
    public class UserController{
    
        @RequestMapping("/handler")
        public ModelAndView handler(String[] hobby){
            ModelAndView mav = new ModelAndView("user_info");
            mav.addObject("hobby",hobby);
            return mav;
        }
    
    }

    批量修改,使用List来接收

    有时候我们需要批量插入、批量修改。

    比如视图以表格的形式列出了多个用户的信息,管理员在页面上修改了多个用户的信息,现在要提交修改,需要使用List<User>来传递数据,批量添加也是一样的。

    不能直接使用List<User>来接收参数,需要使用包装类包装一下。

    包装类:

    public class UserVO {
        private List<User> list;
    
        public List<User> getList() {
            return list;
        }
    
        public void setList(List<User> list) {
            this.list = list;
        }
    }

    VO只有一个属性,及其getter、setter方法。

    表单:

      <form action="${pageContext.request.contextPath}/userController/handler" method="post">
        User1:<br />
        username:<input name="list[0].username" type="text"><br />
        password:<input name="list[0].password" type="password"><br /><br />
    
        User2:<br />
        id:<input name="list[1].username" type="text"><br />
        name:<input name="list[1].password" type="password"><br /><br />
    
        <button type="submit">提交</button>
      </form>

    此处list对应包装类的成员变量名。

    controller:

    @org.springframework.stereotype.Controller
    @RequestMapping("/userController")
    public class UserController{
    
        @RequestMapping("/handler")
        public ModelAndView handler(UserVO userVO){
            ModelAndView mav = new ModelAndView("user_info");
            mav.addObject("list", userVO.getList());
            return mav;
        }
    
    }

    日期的接收

    有时候需要接收表单传递的日期,比如生日。

    后台有2种接收方式:

    • 使用String接收日期

    如果不进行相关计算,使用String表示日期即可;如果要进行相关计算,先用String接收日期,在业务方法中把String转换为Date(可以封装为工具类,在业务方法中调用)。

    表单使用<input type="text" />、<input type="date" />都可以,type="text"要严格校验日期格式。

    • 使用Date接收日期

    表单使用<input type="text" />、<input type="date" />都可以,如果使用type="text",日期格式只能是 年/月/日 (/分隔)。


    DataBinder   数据绑定

    数据绑定的概念:将请求参数的内容与controller中业务方法的参数绑定,比如表单数据的提交。

    数据绑定的流程:

    (1)Spring MVC将ServletRequest对象传递给DataBinder

    (2)Spring MVC从controller的业务方法的签名(声明)中获取参数表(形参名),把它传递给DataBinder

    (3)DataBinder调用ConversionService对ServletRequest中的请求参数进行数据类型的转换、格式化

       ( ConversionService会根据  原始类型  ——目标类型  调用对应的Converter来进行数据转换。Spring MVC内置了常用的类型转换器,我们也可以自定义类型转换器。)

    (4)DataBinder调用Validator校验已经被转换好的请求参数是否合法

    (5)DataBinder调用BindingResult,把请求参数赋给业务方法中对应的参数,完成数据绑定。


    解决前端传过来的数据中文乱码

    使用spring mvc提供的编码过滤器,过滤所有请求。

    在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>
        </filter>
    
        <!--过滤所有请求-->
        <filter-mapping>
            <filter-name>characterEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

    @RequestParam   必需的请求参数

    controller:

    @org.springframework.stereotype.Controller
    @RequestMapping("/userController")
    public class UserController{
    
        @RequestMapping("/handler")
        public String handler(int user_id,Model model){
            model.addAttribute("user_id", user_id);
            return "user_info";
        }
    
    }

    就算请求参数中没有user_id这个字段,也会调用这个业务方法来处理,就是说参数不是必需传递的。

    如果参数是必需的,要求HTTP请求参数中必需要有这个字段,可以这样:

    @org.springframework.stereotype.Controller
    @RequestMapping("/userController")
    public class UserController{
    
        @RequestMapping("/handler")
        public String handler(@RequestParamint user_id,Model model){
            model.addAttribute("user_id", user_id);
            return "user_info";
        }
    
    }

    用@RequestParam修饰某个参数,表示这个参数是必需的,如果没有传递此参数,不会调用业务方法,直接报错。

    如果请求参数的字段名和业务方法的形参名不一致,比如请求参数中的字段名是id,而业务方法中的形参名是user_id,则必须指定该形参与请求参数中的哪个字段绑定: 

        @RequestMapping("/handler")
        public String handler(@RequestParam("id") int user_id,Model model){
            model.addAttribute("user_id", user_id);
            return "user_info";
        }

    如果请求参数的字段名和业务方法的形参名一致,直接写@RequestParam就行,SpringMVC会自动把请求参数赋给业务方法中同名的形参。

    注意:

    必需和必填不是一个概念,必需是指请求参数中必须要有这个字段,只有要这个字段就行,值可以是空的。

    如果一个表单字段(有name属性),没填就提交了,请求参数中是有这个字段的,只不过值是空的。

    可以设置是否必需:

    @org.springframework.stereotype.Controller
    @RequestMapping("/userController")
    public class UserController{
    
        @RequestMapping("/handler")
        public String handler(@RequestParam(value = "user_id",required = false) int user_id,Model model){
            model.addAttribute("user_id", user_id);
            return "user_info";
        }
    
    }

    默认为true——必需,没传递该参数直接报错。

    false——不是必需的,传不传递都行,都会调用业务方法。

    可以设置默认值:

    @org.springframework.stereotype.Controller
    @RequestMapping("/userController")
    public class UserController{
    
        @RequestMapping("/handler")
        public String handler(@RequestParam(value = "user_id",defaultValue = "0") int user_id,Model model){
            model.addAttribute("user_id", user_id);
            return "user_info";
        }
    
    }

    如果没有传递此参数,会自动使用默认值。

  • 相关阅读:
    ossec配置使用腾讯企业邮箱告警
    网络排除工具之tcping
    pyenv 安装
    CVE-2020-1472 漏洞检测
    容器技术的核心
    简述 进程、线程、协程的区别 以及应用场景--记录
    php函数使用
    php使用表单post方法进行页面
    CURL方式使用代理访问网站
    nginx下隐藏admin和当前域名下得index.php
  • 原文地址:https://www.cnblogs.com/chy18883701161/p/12244518.html
Copyright © 2011-2022 走看看