JSR-303 实现参数校验
1. 什么是JSR-303
JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,官方参考实现是Hibernate Validator。
此实现与 Hibernate ORM 没有任何关系。
JSR-303 用于对 Java Bean 中的字段的值进行验证。
Spring MVC 3.x 之中也大力支持 JSR-303,可以在控制器中对表单提交的数据方便地验证。
JSR-303官网
2. JSR-303内置校验规则

3. SpringBoot整合JSR-303
3.1 导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
3.2 在类的属性上加上相应校验注解
@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
@Email(message="邮箱格式错误")
private String email;
3.3 实现校验
在Controller的处理方法的参数前,加@Valid注解,出错后,错误信息会放置在 Errors或BindingResult 的对象参数中
@RequestMapping("/login")
public String testValid(@Valid User user, BindingResult result){
if (result.hasErrors()){
List<ObjectError> errorList = result.getAllErrors();
for(ObjectError error : errorList){
System.out.println(error.getDefaultMessage());
}
}
return "test";
}
3.4 通过全局统一异常替换BindingResult写法
给controller后的需要校验的bean后加一个BindingResult类就可以获得校验的结果,但是相对麻烦,每次都要写BindingResult。在大项目中一般使用统一异常处理校验结果,返回json格式,如下所示
//后端校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public RtnResult handValidException(MethodArgumentNotValidException e){
BindingResult bindingResult = e.getBindingResult();
Map<String, Object> map = new HashMap<>();
bindingResult.getFieldErrors().forEach(fieldError -> {
map.put(fieldError.getField(),fieldError.getDefaultMessage());
});
return RtnResult.fail(map);
}
3.5 分组校验(多场景的复杂校验)
分组校验应用场景:添加和更新需要不同的校验规则时
3.5.1 先创建添加和更新的接口,该接口仅仅是多场景的一个标识,接口内容为空即可。
public interface AddGroup {
}
public interface UpdateGroup {
}
3.5.2 在 @NotBlank(message = “密码不能为空”) 后加上groups 用于表示给校验注解标注什么情况下需要校验(添加/更新)
//AddGroup.class是添加的标识组,可以有多个
@NotBlank(message = "密码不能为空", groups = {AddGroup.class})
private String password;
@NotBlank(message = "姓名不能为空", groups = {AddGroup.class,UpdateGroup.class})
private String name;
3.5.3 替换controller层原来的@Valid注解,使用mvc提供的@Validated注解,否则不生效
//添加用户 @Validated指定哪个操作使用校验
@PostMapping("/addUser")
public RtnResult addUser(@Validated(AddGroup.class) @RequestBody ClaimUser claimUser){
return claimUserService.addUser(claimUser);
}
如果使用分组校验,校验注解没有使用groups,则校验不生效,一定要使用groups!!
4. 自定义校验注解
当给出的校验规则不能满足需求,可以通过自定义校验来实现,如某个字段只能为0或1。
举例场景:当显示和隐藏的属性showStatus只能时0或1,需要自定义校验注解和自定义校验器
4.1 导入依赖
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
4.2 编写自定义校验注解
PS:可以参考JSR-303原本的校验
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME) //运行环境
@Repeatable(List.class)
@Documented
@Constraint(validatedBy = { }) // 指定自定义校验器,可以适配多个校验器,一个注解完成多种校验
public @interface NotNull {
String message() default "{javax.validation.constraints.NotNull.message}"; // 校验失败的提示信息
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int[] vals() default {}; //标注在属性上的vals={0,1}
}
4.3 编写自定义校验注解
//自定义校验器 必须实现ConstraintValidator
//ConstraintValidator中的 泛型1:绑定的泛型注解 泛型2:校验的数据类型
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {
private Set<Integer> set = new HashSet<>();
//初始化方法,获取在Entity类的属性上标注的符合条件的Integer的值:{0,1}
@Override
public void initialize(ListValue constraintAnnotation) {
int[] vals = constraintAnnotation.vals();
for (int val : vals) {
set.add(val);
}
}
//判断是否校验成功方法
//integer:传进来的值
//判断依据:看integer是否在初始化方法的数组中
@Override
public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) {
if (set.contains(integer)) {
return true;
}
return false;
}
}
4.4 在需要校验的属性上添加自定义注解
@ListValue(vals={0,1},message = "开关状态只能是0或1")
private Integer showStatus;

4.5 自定义参数校验(这边以校验手机号为例)
- 编写注解类
//说明该注解将被包含在javadoc中
@Documented
// 注解的作用目标 类上、方法上、属性上
@Target({ElementType.FIELD, ElementType.PARAMETER})
// 注解的保留位置
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {IsMobileValidator.class }) // 与约束注解关联的验证器
public @interface IsMobile {
boolean required() default true;
String message() default "手机号不正确";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
- 编写校验规则
public class IsMobileValidator implements ConstraintValidator<IsMobile, String> {
private boolean required;
/**
* 重写initialize方法获取注解实例
* @param ca
*/
@Override
public void initialize(IsMobile ca) {
// 重注解实例中获信息
required = ca.required();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// value就是要校验的数据了
if (value != null && required) {
// 手机号校验规则
System.out.println(value);
String regexp= "^(((\\+\\d{2}-)?0\\d{2,3}-\\d{7,8})|((\\+\\d{2}-)?(\\d{2,3}-)?([1][3,4,5,7,8][0-9]\\d{8})))$";
boolean matches = Pattern.matches(regexp, value);
System.out.println(matches);
return matches;
}
return false;
}
}
- 使用自定义校验注解
/**
* 手机号
*/
@IsMobile(message = "用户手机号不正确")
private String tel;
JSR-303 实现参数校验的更多相关文章
- SpringMVC中的 JSR 303 数据校验框架说明
JSR 303 是java为Bean数据合法性校验提供的标准框架,它已经包含在JavaEE 6.0中. JSR 303 通过在Bean属性上标注类似于@NotNull.@Max等标准的注解指定校验规则 ...
- JSR 303 - Bean Validation 介绍及最佳实践
JSR 303 - Bean Validation 介绍及最佳实践 JSR 303 – Bean Validation 是一个数据验证的规范,2009 年 11 月确定最终方案.2009 年 12 月 ...
- JSR 303 - Bean Validation 介绍及最佳实践(转)
JSR 303 – Bean Validation 是一个数据验证的规范,2009 年 11 月确定最终方案.2009 年 12 月 Java EE 6 发布,Bean Validation 作为一个 ...
- JSR 303 - Bean Validation 简单介绍及用法
一.JSR-303简单介绍 JSR-303 是 JAVA EE 6 中的一项子规范.叫做 Bean Validation,官方參考实现是Hibernate Validator. 此实现与 Hibern ...
- Springboot 使用 JSR 303 对 Controller 控制层校验及 Service 服务层 AOP 校验,使用消息资源文件对消息国际化
导包和配置 导入 JSR 303 的包.hibernate valid 的包 <dependency> <groupId>org.hibernate.validator< ...
- JSR 303 进行后台数据校验
一.JSR 303 1.什么是 JSR 303? JSR 是 Java Specification Requests 的缩写,即 Java 规范提案. 存在各种各样的 JSR,简单的理解为 JSR 是 ...
- Spring基础系列-参数校验
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9953744.html Spring中使用参数校验 概述 JSR 303中提出了Bea ...
- Spring Boot 2.x基础教程:JSR-303实现请求参数校验
请求参数的校验是很多新手开发非常容易犯错,或存在较多改进点的常见场景.比较常见的问题主要表现在以下几个方面: 仅依靠前端框架解决参数校验,缺失服务端的校验.这种情况常见于需要同时开发前后端的时候,虽然 ...
- 如何在 Spring/Spring Boot 中做参数校验?你需要了解的都在这里!
本文为作者原创,如需转载请在文首著名地址,公众号转载请申请开白. springboot-guide : 适合新手入门以及有经验的开发人员查阅的 Spring Boot 教程(业余时间维护中,欢迎一起维 ...
- 如何在 Spring/Spring Boot 中做参数校验
数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据. 本文结合自己在项目 ...
随机推荐
- 【Linux】find删除365天以前的文件详细解析
find . -name "*" -mtime +365 -exec rm -rf {} \; -mtime +365 文件被修改的时间,最后一次发生到现在365天 -atime ...
- guava eventbus 原理+源码分析
前言: guava提供的eventbus可以很方便的处理一对多的事件问题, 最近正好使用到了,做个小结,使用的demo网上已经很多了,不再赘述,本文主要是源码分析+使用注意点+新老版本eventbus ...
- HTTP Keep-Alive模式客户端与服务器如何判定传输完成
目录 长连接是什么 服务器如何知道已经完全接受客户端发送的数据 客户端如何知道已经完全接受服务端发送的数据 Transfer-Encoding transfer-coding与Content-Leng ...
- FLask之视图
视图 1 FBV def index(): return render_template('index.html') app.add_url_rule('/index', 'index', index ...
- 华为三层交换机限制vlan段的指定端口
屏蔽vlan 120这个段的ip的所有2333端口 [NTT_3L]int Vlanif 120 [NTT_3L-Vlanif120]dis this # interface Vlanif120 ip ...
- jQuery 文本段落展开和折叠效果
jQuery 文本段落展开和折叠效果 <!DOCTYPE html> <head> <meta http-equiv="Content-Type" c ...
- IDEA SSM+MAVEN+JWT 图书管理系统
压缩包内含有MAVEN,TOMCAT,需要手动对IDEA进行配置.同时也包含数据库文件. 项目搭载了swagger,可以方便地对接口进行测试 在开发的过程中我也进行了一些记录,可以参考https:// ...
- notepad文件对比
一/格式转换 我用的是json,就以这个为例吧: 打开软件--插件--插件管理 搜索着两个进行安装,自动重启打开 将文件的代码做好,选择语言--J--可以找到json 用刚安装的插件--json vi ...
- jdk安装简洁版
一.jdk是what? jdk其实是个软件语言开发包,包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具. 没有JDK的话,无法编译Java程序(指java源码.java文件),如果想 ...
- 思考gRPC :为什么是HTTP/2
Introducing gRPC Support with NGINX 1.13.10 - NGINX https://www.nginx.com/blog/nginx-1-13-10-grpc/ 思 ...