Spring MVC(十四)--SpringMVC验证表单

在Spring MVC中提供了验证器可以进行服务端校验,所有的验证都必须先注册校验器,不过校验器也是Spring MVC自动加载的,在使用Spring MVC校验器之前首先要下载相关的jar包,下面是我的一些jar所对应的maven依赖:

 1 <!-- 验证器所需的包 -->
 2         <dependency>
 3             <groupId>com.fasterxml</groupId>
 4             <artifactId>classmate</artifactId>
 5             <version>1.4.0</version>
 6         </dependency>
 7 
 8         <dependency>
 9             <groupId>org.jboss.logging</groupId>
10             <artifactId>jboss-logging</artifactId>
11             <version>3.3.2.Final</version>
12         </dependency>
13 
14         <dependency>
15             <groupId>org.hibernate.validator</groupId>
16             <artifactId>hibernate-validator</artifactId>
17             <version>6.0.13.Final</version>
18         </dependency>
19 
20         <dependency>
21             <groupId>javax.validation</groupId>
22             <artifactId>validation-api</artifactId>
23             <version>2.0.1.Final</version>
24         </dependency>

其中:

  • validator-api-*:提供关于验证注解的;
  • hibernate-validator-*:是通过hibernate校验规则的包,他还要依赖classmate和jboss-logging这两个包;

Spring MVC中有两种校验方式,一种是使用JSR 303注解验证输入内容,另一种是使用校验器。

一、使用JSR 303注解验证输入内容

spring提供了对bean的校验功能,通过注解@Valid表明对哪个Bean需要启用注解式校验。这种方式可以用来对字段进行非空、合法性等的校验,它还提供了一些校验规则约束:

Bean Validate中提供的约束有以下几种:

Hibernate中也提供了一些约束:

具体内容可参考这个网站:

https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/

二、使用校验器

有时候除了合法性校验之外,还需要进行一些业务逻辑校验,比如用户名不能重复等,这就需要使用校验器来完成。使用校验器需要进行两步操作:

1、完成校验器:SpringMVC提供了一个validator接口,我们只要实现这个接口中的方法即可;

2、绑定到控制器:创建完了校验器之后要告诉容器需要校验哪个控制器,所以需要将校验器和控制器绑定,绑定的方法很简单,就是在控制器中写一个方法并使用注解@InitBinder即可。

下面结合这两种校验方式写一个例子说明。

三 、实例

1、创建一个表单

这个表单用来输入一些信息

<form id="paramForm" action="<%=basePath%>customer/addCustomer"
                method="post">
                <table>
                    <tr>
                        <td>用户名:</td>
                        <td><input type="text" name="cusName" id="input_cus_name"
                            value=""></td>
                    </tr>
                    <tr>
                        <td>用户年龄:</td>
                        <td><input type="text" name="cusAge" id="input_cus_age"
                            value=""></td>
                    </tr>
                    <tr>
                        <td>用户性别:</td>
                        <td><label for="input_cus_sex1"></label><input type="radio"
                            name="cusSex" id="input_cus_sex1" value="1"><label
                            for="input_cus_sex0"></label><input type="radio" name="cusSex"
                            id="input_cus_sex0" value="0"></td>
                    </tr>
                    <tr>
                        <td>手机号码:</td>
                        <td><input type="text" name="cusPhone" id="input_cus_phone"
                            value=""></td>
                    </tr>
                    <tr>
                        <td>邮箱地址:</td>
                        <td><input type="text" name="cusEmail" id="input_cus_email"
                            value=""></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td style="text-align: right;"><input type="submit"
                            value="提交" id="addCustomer"></td>
                    </tr>
                </table>
            </form>

因为向后台传的是个pojo对象,所以name名称要和pojo对象属性保持一致。

2、创建表单中数据对应的pojo,并使用JSR 303校验字段

public class Customer {
    private Integer cusId;

    @NonNull
    @Pattern(regexp = "^([a-zA-Z]*[0-9_-]*$)", message = "只能包含字母、数字、下划线,且不能以数字或下划线开头")
    @Size(min = 8, max = 128)
    private String cusName;

    @NotNull
    @Min(18)
    @Max(40)
    private Integer cusAge;

    @NotNull
    private Integer cusSex;

    @NotNull
    @Size(min = 6, max = 11)
    @Pattern(regexp = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$", message = "请输入正确的手机号")
    private String cusPhone;

    @NotNull
    @Size(min = 10, max = 20)
    @Pattern(regexp = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$", message = "请输入正确的电子邮箱")
    private String cusEmail;

    public Integer getCusId() {
        return cusId;
    }

    public void setCusId(Integer cusId) {
        this.cusId = cusId;
    }

    public String getCusName() {
        return cusName;
    }

    public void setCusName(String cusName) {
        this.cusName = cusName == null ? null : cusName.trim();
    }

    public Integer getCusAge() {
        return cusAge;
    }

    public void setCusAge(Integer cusAge) {
        this.cusAge = cusAge;
    }

    public Integer getCusSex() {
        return cusSex;
    }

    public void setCusSex(Integer cusSex) {
        this.cusSex = cusSex;
    }

    public String getCusPhone() {
        return cusPhone;
    }

    public void setCusPhone(String cusPhone) {
        this.cusPhone = cusPhone == null ? null : cusPhone.trim();
    }

    public String getCusEmail() {
        return cusEmail;
    }

    public void setCusEmail(String cusEmail) {
        this.cusEmail = cusEmail == null ? null : cusEmail.trim();
    }
}

上面红色加粗的部分就是使用JSR 303中的约束规则。

3、创建校验器

这个校验器用来判断输入的用户名是不是Administrator,如果是则校验不通过,并给出提示,否则校验成功;

public class CustomerValidator implements Validator {
/**
     * 检验验证对象是不是Customer类,如果是则进行检验
     */
    @Override
    public boolean supports(Class<?> target) {
        return Customer.class.equals(target);
    }

    /**
     * 校验用户名是否已经存在
     */
    @Override
    public void validate(Object target, Errors errors) {
        Customer customer = (Customer) target;
        String name = customer.getCusName();
        if (name.equals("Administrator")) {
            errors.rejectValue("cusName", null, "该账号已被使用!");

        }
    }

}

创建校验器时只要实现Validator接口并重写对应的方法即可,supports方法是用来判定要校验的bean类型,validate方法用来完成校验逻辑。

4、创建控制器

@Controller
@RequestMapping("/customer")
public class CustomerController {

    @Autowired
    @Qualifier("customerService")
    CustomerService customerServiceImpl = null;

    /**
     * 绑定验证器
     * 
     * @param dataBinder
     */
    @InitBinder
    public void bindValidator(DataBinder dataBinder) {
        dataBinder.setValidator(new CustomerValidator());
    }

    /**
     * customer首页
     * 
     * @param mv
     * @param customer
     * @return
     */
    @RequestMapping("index")
    public ModelAndView indexCustomer(ModelAndView mv, Customer customer) {
        mv.addObject("customer", customer);
        mv.setViewName("index");
        mv.addObject("customer", customer);
        return mv;
    }

    @RequestMapping(value = "addCustomer", method = RequestMethod.POST)
    public ModelAndView validByAnnotation(@Valid Customer customer, Errors errors,
            RedirectAttributes redirectAttributes) {
        ModelAndView mv = new ModelAndView();
        // 判断是否存在错误
        if (errors.hasErrors()) {
            List<FieldError> errorList = errors.getFieldErrors();
            for (FieldError fieldError : errorList) {
                System.out.println("field:" + fieldError.getField() + ";errors:" + fieldError.getDefaultMessage());
            }
            mv.addObject("errorList", errorList);
            mv.setView(new MappingJackson2JsonView());
        } else {
            boolean insert = customerServiceImpl.addCustomer(customer);
            redirectAttributes.addFlashAttribute("customer", customer);
            if (insert) {
                mv.setViewName("redirect:./customer/index");
            } else {
                mv.setViewName("redirect:./customer/error");
            }
        }
        return mv;
    }

    /**
     * 出错页面
     * 
     * @param mv
     * @param customer
     * @return
     */
    @RequestMapping("error")
    public ModelAndView errorInfo(ModelAndView mv, Customer customer) {
        mv.addObject("customer", customer);
        mv.setViewName("customer/error");
        return mv;
    }

}

这个控制器逻辑如下:

  • 首先在方法bindValidator上使用注解@InitBinder完成校验器和控制器的绑定;
  • 然后使用注解@Valid对Customer进行校验,这样校验器中就能通过第一个方法的判断;
  • 通过Error对象判断是不是有错误,如果有错误代表校验失败,失败后打印出失败的信息并返回JDON视图;
  • 如果校验成功则将数据保存在数据库,保存时也判断是否成功,保存成功则返回index页面,否则返回error页面

5、测试

先来测试JSR 303的校验,首先在页面输入以下信息,输入信息都是不通过校验的:

返回信息如下:

其实就是校验失败的提示信息,我是直接返回JSON视图的,所以说明JSR 303校验生效了。下面输入一些合法数据进行测试:

点击提交之后的结果如下:

保存成功并进入index页面,校验成功。

下面测试校验器功能,需要释放绑定逻辑,输入以下正确信息,并让用户名为Administrator

 

提交之后的结果如下:

从提示信息看出校验器校验没用通过并给出提示信息,说明校验通过了。

以上就是Spring MVC中对表单进行服务端校验的内容。

猜你喜欢

转载自www.cnblogs.com/hellowhy/p/9750026.html