美文网首页
Spring Boot 之表单校验

Spring Boot 之表单校验

作者: 离线中__ | 来源:发表于2019-02-22 19:14 被阅读0次

    一、在实体类添加校验规则注解

    创建实体类,并在实体类属性上添加校验规则注解:

    package cn.alinwork.pojo;
    
    import javax.validation.constraints.Min;
    import javax.validation.constraints.NotNull;
    import org.hibernate.validator.constraints.Length;
    import org.hibernate.validator.constraints.NotEmpty;
    
    public class User {
    
        @NotNull(message="id不能为空")
        private int id;
        @NotEmpty
        @Length(min=4,max=8,message="姓名长度需在4~8之间")
        private String name;
        @Min(value=18,message="年龄不能小于18周岁")
        private int age;
    
        public User() {}
        public User(int id, String name, int age) {
            super();
            this.id = id;
            this.name = name;
            this.age = age;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        @Override
        public String toString() {
            return "name: " + name + " ,age: " + age;
        }
    }
    
    
    • @NotNull: 限制必须不为null
    • @NotEmpty: 判断字符串是否null或者是空串
    • @Length: 判断字符的长度(最大或者最小)( min 与 max 属性 )
    • @Min: 判断数值最小值

    二、在 controller 类开启校验

    package cn.alinwork.controller;
    
    import javax.validation.Valid;
    import org.springframework.stereotype.Controller;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.RequestMapping;
    import cn.alinwork.pojo.User;
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        @RequestMapping("/toAdd")
        private String add(User user){
            return "addUser";
        }
        
        @RequestMapping("/doAdd")
        private String doAdd(@Valid User user,BindingResult result){
            if(result.hasErrors()){
                return "addUser"; //校验失败返回原页面
            }
            System.out.println(user);
            return "ok";
        }
    }
    
    
    • @Valid 注解可以实现数据的验证,在实体的属性上添加校验规则,而在API接收数据时添加@Valid 关键字,这时实体将开启校验
    • BindingResult 封装了校验的结果,并自动放入model ,传递至页面

    三、在页面 addUser.html 提交信息并验证

    1. 页面如下
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8"></meta>
    <title>用户新增</title>
    <style type="text/css">
        font{
            color: red;
        }
    </style>
    </head>
    <body>
        <form th:action="@{/user/doAdd}" method="post">
            用户编号:<input type="text" name="id" /><font th:errors="${user.id}"></font><br>
            手机号码:<input type="text" name="name" /><font th:errors="${user.name}"></font><br>
            用户年龄:<input type="text" name="age" /><font th:errors="${user.age}"></font><br>
            <input type="submit" value="确定" />
        </form>
    </body>
    </html>
    
    • 上面 controller 中 BindingResult 封装了一个对象到 model 中,并传递到页面模版。
    • 对象名为参数类型的驼峰式命名。本例中参数类型为 User ,对应 user,所以页面会收到一个名为 user 的对象。
    • user 对象里封装了校验未通过的错误信息,key 为对象对应属性的值,所以取值如: ${user.name}
    1. 访问页面
      在浏览器访问 http://localhost:8080/user/toAdd ,会发现报错:
      java.lang.IllegalStateException: 
      Neither BindingResult nor plain target object for bean name 'user' available as request attribute
    
    

    这是因为 thymeleaf 模版解析 th:errors="${user.id}" 时,找不到 user 对象

    四、解决异常

    1. 解决异常的方法,在跳转页面的方法中注入一个对象,来解决问题。
      要求参数对象的变量名必须是对象的类名的全称首字母小写。
        /**
         * 解决异常的方式。可以在跳转页面的方法中注入一个Uesr对象
         * 注意:由于 springmvc 会自动将该对象放入到Model中,默认使用该对象类型驼峰式的命名规则来作为key
         * 即:页面模版中参数的变量名需要与对象的名称相同,将首字母小写;与此处函数中的变量名无关;
         * 
         * 如此处将自动放入一个名为 user 的对象至 Model中,函数中的变量名可随意起,如 "u" 
         */
        @RequestMapping("/toAdd")
        private String add(User u){
            return "addUser";
        }
    
    
    1. 此时再次访问页面,发现已无异常

    到这边,我们已经完成了简单的表单验证。
    有人会问,默认传递对象名 user 能改吗? 能 !

    1. 修改传递的对象名
        /**
         * 如果想修改传递的对象名,可用@ModelAttribute("u");
         * 这表示当前传递的对象的 key 为 u;
         * 同时页面中获取该对象的key也需要修改为 u;
         * doAdd 方法也需要同步更改
         */
        @RequestMapping("/toAdd")
        private String add(@ModelAttribute("u")User u){
            return "addUser";
        }
    
    • @ModelAttribute 注解可指定传递对象名,括号中值即传递的对象名;
    • 同时需修改 html 模版中与doAdd方法也需要同步更改;
        <form th:action="@{/user/doAdd}" method="post">
            用户编号:<input type="text" name="id" /><font th:errors="${u.id}"></font><br>
            手机号码:<input type="text" name="name" /><font th:errors="${u.name}"></font><br>
            用户年龄:<input type="text" name="age" /><font th:errors="${u.age}"></font><br>
            <input type="submit" value="确定" />
        </form>
    
        @RequestMapping("/doAdd")
        private String doAdd(@ModelAttribute("u")@Valid User user,BindingResult result){
            if(result.hasErrors()){
                return "addUser";
            }
            System.out.println(user);
            return "ok";
        }
    
    1. 再次打开浏览器访问验证

    五、小结

    限制 说明
    @Null 限制只能为null
    @NotNull 限制必须不为null
    @AssertFalse 限制必须为false
    @AssertTrue 限制必须为true
    @DecimalMax(value) 限制必须为一个不大于指定值的数字
    @DecimalMin(value) 限制必须为一个不小于指定值的数字
    @Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
    @Max(value) 限制必须为一个不大于指定值的数字
    @Min(value) 限制必须为一个不小于指定值的数字
    @Future 限制必须是一个将来的日期
    @Past 限制必须是一个过去的日期
    @Pattern(value) 限制必须符合指定的正则表达式
    @Size(max,min) 限制字符长度必须在min到max之间
    @NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
    @NotBlank 验证注解的元素值不为空(不为null、去除首尾空格后长度不为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
    @Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

    相关文章

      网友评论

          本文标题:Spring Boot 之表单校验

          本文链接:https://www.haomeiwen.com/subject/ztwdyqtx.html