SpringMVC Validator验证示例

时间:2021-05-19

SpringMVC服务器验证一种是有两种方式,一种是基于Validator接口,一种是使用Annotaion JSR-303标准的验证,下面主要是学习这两种,工作中推荐后者,方便很多

一.基于Validator接口的验证.

首先创建User实例,并加入几个属性

public class User { private String username; private String password; private String nickname; 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 String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } @Override public String toString() { return "username--"+username+"password--"+password+"nickname--"+nickname; }}

接着创建用于校检的类UserValidator,让其实现Validator,覆盖其中的两个方法

import main.java.model.User;import org.springframework.validation.Errors;import org.springframework.validation.Validator;public class UserValidator implements Validator { @Override public boolean supports(Class<?> aClass) { //判断是否是要校验的类,这里是User return User.class.equals(aClass); } @Override public void validate(Object o, Errors errors) { User u = (User) o; if (null == u.getPassword() || "".equals(u.getPassword())){ //此方法可以加四个参数,第一个表单域field, //区分是哪个表单出错,第二个errorCode错误码, //第三个制定了资源文件中占位符,第四个具体错误返回信息 //简写版可以把2,3参数去掉 errors.rejectValue("password",null,null,"password is null"); } }}

上面的类只实现了对密码判断是否为空,为空则注册这一错误信息,也就是”password is null”,接下来要实现控制器,控制器要做的事情,第一是注册这个校验器,第二是实现校验.

import main.java.model.User;....../** * 加上@Controller决定这个类是一个控制器 */@Controller@RequestMapping("/user")public class HelloController { //我们知道在Controller类中通过@InitBinder标记的方法只有在请求当前Controller的时候才会被执行 //所以在这里注册校验器 @InitBinder public void initBainder(DataBinder binder){ binder.replaceValidators(new UserValidator()); } //这个方法主要是跳转到登录页面 @RequestMapping(value = "/login",method = RequestMethod.GET) public String login(Model model){ model.addAttribute(new User()); return "user/login"; } //处理登录表单 @RequestMapping(value = "/login",method = RequestMethod.POST) public String login(@Validated User user, BindingResult br){ if (br.hasErrors()){ return "user/login"; } return "--"; } }

上面代码可以看到@Validated User user, BindingResult br这两个参数,@Validated表明参数user是要校验的类,BindingResult是存储错误信息的类,两者必须一一对应,并且位置挨着,不能中间有其他参数,

最后随便写一个jsp页面实现校检

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@taglib prefix="sf" uri="http://pile(moneyReg); public void initialize(Money money) { // TODO Auto-generated method stub } public boolean isValid(Double value, ConstraintValidatorContext arg1) { // TODO Auto-generated method stub if (value == null) return true; return moneyPattern.matcher(value.toString()).matches(); }}

从上面代码中我们可以看到ConstraintValidator是使用了泛型的。它一共需要指定两种类型,第一个类型是对应的initialize方法的参数类型,第二个类型是对应的isValid方法的第一个参数类型。从上面的两个方法我们可以看出isValid方法是用于进行校验的,有时候我们在校验的过程中是需要取当前的限制类型的属性来进行校验的,比如我们在对@Min限制类型进行校验的时候我们是需要通过其value属性获取到当前校验类型定义的最小值的,我们可以看到isValid方法无法获取到当前的限制类型Money。这个时候initialize方法的作用就出来了。

我们知道initialize方法是可以获取到当前的限制类型的,所以当我们在校验某种限制类型时需要获取当前限制类型的某种属性的时候,我们可以给当前的ConstraintValidator定义对应的属性,然后在initialize方法中给该属性赋值,接下来我们就可以在isValid方法中使用其对应的属性了。针对于这种情况我们来看一个代码示例,现在假设我要定义自己的@Min限制类型和对应的MinValidator校验器,那么我可以如下定义:

@Target({ElementType.FIELD, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy=MinValidator.class)public @interface Min { int value() default 0; String message(); Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {};}MinValidator校验器public class MinValidator implements ConstraintValidator<Min, Integer> { private int minValue; public void initialize(Min min) { // TODO Auto-generated method stub //把Min限制类型的属性value赋值给当前ConstraintValidator的成员变量minValue minValue = min.value(); } public boolean isValid(Integer value, ConstraintValidatorContext arg1) { // TODO Auto-generated method stub //在这里我们就可以通过当前ConstraintValidator的成员变量minValue访问到当前限制类型Min的value属性了 return value >= minValue; }}

继续来说一下ConstraintValidator泛型的第二个类型,我们已经知道它的第二个类型是对应的isValid的方法的第一个参数,从我给的参数名称value来看也可以知道isValid方法的第一个参数正是对应的当前需要校验的数据的值,而它的类型也正是对应的我们需要校验的数据的数据类型。这两者的数据类型必须保持一致,否则spring会提示找不到对应数据类型的ConstraintValidator。建立了自己的限制类型及其对应的ConstraintValidator后,其用法跟标准的JSR-303限制类型是一样的。以下就是使用了上述自己定义的JSR-303限制类型——Money限制和Min限制的一个实体类:

public class User { private int age; private Double salary; @Min(value=8, message="年龄不能小于8岁") public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Money(message="标准的金额形式为xxx.xx") public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; }}

4.配合ajax验证

最近写的项目,感觉直接使用validator不太好用,主要是返回时会刷新整个页面才会出来错误信息,体验相当不好,验证还是用ajax体验比较好,所以配合ajax

思路:验证还是使用springMVC来验证,只是这次发现错误的话,把错误取出,存放到一个map中,然后ajax返回,页面根据ajax返回值来判断,从而显示不同的信息

主要代码:

if (br.hasErrors()){//判断是否有错误 //对错误集合进行遍历,有的话,直接放入map集合中 br.getFieldErrors().forEach(p->{ maps.put(p.getField(),p.getDefaultMessage()); }); return maps; }

这样的话 maps里面存放的就是 错误变量名,错误信息,例如 username -‘用户名不能为空'

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章