一、概述

除了依赖注入、方法参数,Bean Validation 1.1定义的功能还包括:

1、分组验证

2、自定义验证规则

3、类级别验证

4、跨参数验证

5、组合多个验证注解

6、其他

二、分组验证

通过分组,可实现不同情况下的不同验证规则,示例如下:

1、定义分组接口

public interface AddView { 
} public interface UpdateView {
}

2、定义实体

public class Person {
@Null(groups = AddView.class)
@NotNull(groups = {UpdateView.class, Default.class})
private Integer id;
...
}

  注:不指定分组,即为Default分组

3、业务类

@Service
@Validated
public class PersonService {
@Validated(AddView.class)
public void addPerson(@Valid Person person) {} @Validated({UpdateView.class})
public void updatePerson(@Valid Person person) {} public void defaultOp(@Valid Person person) {}
}

4、测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-context.xml")
public class ValidTest {
@Autowired
private PersonService testService; @Test(expected = ConstraintViolationException.class)
public void test1() {
Person person = new Person();
person.setId(12);
testService.addPerson(person);
} @Test(expected = ConstraintViolationException.class)
public void test2() {
Person person = new Person();
testService.updatePerson(person);
} @Test(expected = ConstraintViolationException.class)
public void test3() {
Person person = new Person();
testService.defaultOp(person);
}
}

三、自定义验证规则

系统预定义的验证注解不能满足需求时,可自定义验证注解,示例如下:

1、自定义注解

@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = ForbiddenValidator.class)
@Documented
public @interface Forbidden {
//默认错误消息
String message() default "{forbidden.word}"; //分组
Class<?>[] groups() default { }; //负载
Class<? extends Payload>[] payload() default { }; //指定多个时使用
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@interface List {
Forbidden[] value();
}
}

2、自定义注解处理类

public class ForbiddenValidator implements ConstraintValidator<Forbidden, String> {
private String[] forbiddenWords = {"admin"}; @Override
public void initialize(Forbidden constraintAnnotation) {
//初始化,得到注解数据
} @Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtils.isEmpty(value)) {
return true;
} for(String word : forbiddenWords) {
if(value.contains(word)) {
return false;//验证失败
}
}
return true;
}
}

3、默认错误消息

# format.properties
forbidden.word=包含敏感词汇

4、实体类

public class Person {
  @Forbidden
  private String name;
  ...
}

5、业务类

@Service
@Validated
public class PersonService {
public void defaultOp(@Valid Person person) { }
}

6、测试

@Test(expected = ConstraintViolationException.class)
public void test4() {
Person person = new Person();
person.setName("admin");
testService.defaultOp(person);
}

四、类级别验证

定义类级别验证,可实现对象中的多个属性组合验证,示例如下:

1、定义注解

@Target({ TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = CheckPasswordValidator.class)
public @interface CheckPassword {
//默认错误消息
String message() default ""; //分组
Class<?>[] groups() default { }; //负载
Class<? extends Payload>[] payload() default { }; //指定多个时使用
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@interface List {
CheckPassword[] value();
}
}

2、定义处理类

public class CheckPasswordValidator implements ConstraintValidator<CheckPassword, Person> {
@Override
public void initialize(CheckPassword constraintAnnotation) {
} @Override
public boolean isValid(Person person, ConstraintValidatorContext context) {
if(person == null) {
return true;
} //没有填密码
if(!StringUtils.isEmpty(person.getNewPassword())) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("{password.null}")
.addPropertyNode("password")
.addConstraintViolation();
return false;
} if(!StringUtils.isEmpty(person.getConfirmPassword())) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("{password.confirmation.null}")
.addPropertyNode("confirmation")
.addConstraintViolation();
return false;
} //两次密码不一样
if (!person.getNewPassword().equals(person.getConfirmPassword())) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("{password.confirmation.error}")
.addPropertyNode("confirmation")
.addConstraintViolation();
return false;
}
return true;
}
}

3、实体

@CheckPassword
public class Person {
private String newPassword;
private String confirmPassword;
...
}

4、业务类

@Service
@Validated
public class PersonService {
public void checkClassValidation(@Valid Person person) { }
}

5、测试

@Test(expected = ConstraintViolationException.class)
public void test4() {
Person person = new Person();
person.setNewPassword("asd");
person.setConfirmPassword("12132");
testService.checkClassValidation(person);
}

五、跨参数验证

使用跨参数验证,可实现方法级别中的多个参数组合验证,示例如下:

1、定义注解

@Constraint(validatedBy = CrossParameterValidator.class)
@Target({ METHOD, CONSTRUCTOR, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
public @interface CrossParameter {
String message() default "{password.confirmation.error}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}

2、定义处理类

@SupportedValidationTarget(ValidationTarget.PARAMETERS)
public class CrossParameterValidator implements ConstraintValidator<CrossParameter, Object[]> {
@Override
public void initialize(CrossParameter constraintAnnotation) {
} @Override
public boolean isValid(Object[] value, ConstraintValidatorContext context) {
if(value == null || value.length != 2) {
throw new IllegalArgumentException("must have two args");
}
if(value[0] == null || value[1] == null) {
return true;
}
if(value[0].equals(value[1])) {
return true;
}
return false;
}
}

3、业务类

@Service
@Validated
public class PersonService {
@CrossParameter
public void checkParaValidation(String pw1, String pw2) { }
}

4、测试

@Test(expected = ConstraintViolationException.class)
public void test5() {
testService.checkParaValidation("asd", "123");
}

六、组合多个验证注解

可将多个注解组合成一个注解,示例如下:

1、定义注解

@Target({ FIELD})
@Retention(RUNTIME)
@Documented
@NotNull
@Min(1)
@Constraint(validatedBy = { })
public @interface NotNullMin {
String message() default "";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}

2、实体

public class Person {
@NotNullMin
private Integer id;
...
}

3、业务类

@Service
@Validated
public class PersonService {
public void checkCompositionValidation(@Valid Person person) { }
}

4、测试

@Test(expected = ConstraintViolationException.class)
public void test6() {
Person person = new Person();
testService.checkCompositionValidation(person);
}

七、其他

Bean Validation 1.1还支持本地化、脚本验证器,详细见参考文档

参考:

Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC

Spring MVC 使用介绍(十六)数据验证 (三)分组、自定义、跨参数、其他的更多相关文章

  1. Spring MVC 使用介绍(六)—— 注解式控制器(二):请求映射与参数绑定

    一.概述 注解式控制器支持: 请求的映射和限定 参数的自动绑定 参数的注解绑定 二.请求的映射和限定 http请求信息包含六部分信息: ①请求方法: ②URL: ③协议及版本: ④请求头信息(包括Co ...

  2. Spring MVC 使用介绍(十五)数据验证 (二)依赖注入与方法级别验证

    一.概述 JSR-349 (Bean Validation 1.1)对数据验证进一步进行的规范,主要内容如下: 1.依赖注入验证 2.方法级别验证 二.依赖注入验证 spring提供BeanValid ...

  3. Spring MVC 使用介绍(十三)数据验证 (一)基本介绍

    一.消息处理功能 Spring提供MessageSource接口用于提供消息处理功能: public interface MessageSource { String getMessage(Strin ...

  4. Spring MVC 使用介绍(十四)文件上传下载

    一.概述 文件上传时,http请求头Content-Type须为multipart/form-data,有两种实现方式: 1.基于FormData对象,该方式简单灵活 2.基于<form> ...

  5. Spring MVC 使用介绍(十二)控制器返回结果统一处理

    一.概述 在为前端提供http接口时,通常返回的数据需要统一的json格式,如包含错误码和错误信息等字段. 该功能的实现有四种可能的方式: AOP 利用环绕通知,对包含@RequestMapping注 ...

  6. spring(7)--注解式控制器的数据验证、类型转换及格式化

    7.1.简介 在编写可视化界面项目时,我们通常需要对数据进行类型转换.验证及格式化. 一.在Spring3之前,我们使用如下架构进行类型转换.验证及格式化: 流程: ①:类型转换:首先调用Proper ...

  7. Spring MVC—数据绑定机制,数据转换,数据格式化配置,数据校验

    Spring MVC数据绑定机制 数据转换 Spring MVC处理JSON 数据格式化配置使用 数据校验 数据校验 Spring MVC数据绑定机制 Spring MVC解析JSON格式的数据: 步 ...

  8. Spring MVC 3.0 返回JSON数据的方法

    Spring MVC 3.0 返回JSON数据的方法1. 直接 PrintWriter 输出2. 使用 JSP 视图3. 使用Spring内置的支持// Spring MVC 配置<bean c ...

  9. Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作

    详细的Spring MVC框架搭配在这个连接中: Maven 工程下 Spring MVC 站点配置 (一) Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作 这篇主 ...

  10. MySQL行(记录)的详细操作一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理

    MySQL行(记录)的详细操作 阅读目录 一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理 一 介绍 MySQL数据操作: ...

随机推荐

  1. C#语法——元组类型

     元组Tuple   我们现在使用的C#语法已经可以满足日常的开发需求,但C#语法还在进行版本的更新,在创造更多更优秀的语义来让我们使用.这里介绍一下C#5.0里的提供的语法——元组. 在C#中定义T ...

  2. 2.1命令行和JSON的配置「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. 命令行配置 1.新建控制台项目 2.nuget引入microsoft.aspnetcore.all 这里要注意版本 ...

  3. .net工具类 分享一个简单的随机分红包的实现方式

    废话不多说,直接上代码 /// <summary> /// 分红包 /// </summary> public class RandomMoney { public Rando ...

  4. 零基础学Python--------第9章 异常处理及程序调试

    第9章 异常处理及程序调试 9.1 异常概述 在程序运行过程中,经常会遇到各种各样的错误,这些错误统称为“异常”.这些异常有的是由于开发者将关键字敲错导致的,这类错误多数产生的是SyntaxError ...

  5. js实现复制文本内容到剪切板

    function copyUrl() { var Url2=document.getElementById("url").innerText; var oInput = docum ...

  6. OPPO K3在哪里打开USB调试模式的完美方法

    当我们使用pc链接安卓手机的时候,如果手机没有开启USB调试模式,pc则无法成功识别我们的手机,这个时候我们需要找解决方法将手机的USB调试模式打开,今天我们介绍OPPO K3如何开启USB调试模式的 ...

  7. JMeter 接口测试-if控制器

    JMeter 接口测试-if控制器 ​ 使用场景: 当业务场景是用户登录才能支付操作, 不登录点击支付, 页面会跳转到登录页面. 对于接口也是这样, 一个接口需要执行前, 需要有前提条件, 比如0状态 ...

  8. 尝鲜Java 12新特性:switch表达式

    Java 12将在两个月后(2019/3/19)发布,现已进入RDP1阶段,确定加入8个JEP.其中对Java语法的改进是JEP 325: switch表达式.于是我迫不及待,提前感受一下更先进的语言 ...

  9. Linq语法常见普通语法

    闲言碎语 近期比较忙,但还是想写点什么,就分享一些基础的知识给大家看吧,希望能帮助一些linq新手,如果有其它疑问,可以进右上角群,进行交流探讨,谢谢. 开门见山 读这篇文章之前,我先说下,每一种搜索 ...

  10. Delphi 项目配置选项

    打开项目设置窗口: 通过菜单:项目>选项 快捷键    :Shift+Ctrl+F11 Delphi编译器选项说明  Conditional defines 指定条件编译器指令中引用的符号. O ...