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 工具直接向后端请求一些违法数据. 本文结合自己在项目 ...
随机推荐
- win10/windows 安装Pytorch
https://pytorch.org/get-started/locally/ 去官网,选择你需要的版本. 把 pip install torch==1.5.0+cu101 torchvision= ...
- 关于 percona monitoring plugins插件报slave is stoped on ip地址
思路:肯定是某个item触发了触发器 去看触发器,找到 slave is stoped,如下图 看到键是mysql.running-slave ,然后去定义key的文件中查看该键对应的脚本,修改脚本. ...
- 彻底搞懂MySQL为什么要使用B+树索引
目录 MySQL的存储结构 表存储结构 B+树索引结构 B+树页节点结构 为什么要用B+树索引 二叉树 多叉树 B树 B+树 搞懂这个问题之前,我们首先来看一下,MySQL表的存储结构 MySQL的存 ...
- MySQL全面瓦解17:触发器相关
关于触发器 现实开发中我们经常会遇到这种情况,比如添加.删除和修改信息的时候需要记录日志,我们就要在完成常规的数据库逻辑操作之后再去写入日志表,这样变成了两步操作,更复杂了. 又比如删除一个人员信息的 ...
- 转 9 jmeter之检查点
9 jmeter之检查点 jmeter有类似loadrunner检查点的功能,就是断言中的响应断言. 1.响应断言(对返回文字结果进行相应的匹配)右击请求-->添加-->断言--> ...
- 【Coursera】Internet History 读书笔记
前言 这个Internet History 有些令人劝退.电脑无法播放视频.手机不能播放.最后百度了改了hosts文件才可以. 附上解决方法: 解决coursera可以登录但无法播放视频 第一周 第三 ...
- java的几种对象(PO,VO,DAO,BO,POJO)
一.PO persistant object 持久对象,可以看成是与数据库中的表相映射的java对象.最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合.PO中应该不包含任何对数 ...
- 浅聊ARP
今天借用思科公司的Cisco Packet Tracer Student这款软件浅聊ARP 什么是ARP? ARP即地址解析协议(Address Resolution Protocol),是根据Ip地 ...
- markdown 编辑器使用教程---字体、颜色、表格换行、链接等
资源池: 绿色版markdown编辑器:点击这里 提取码:ftf9 1.标题 #一级标题 ##二级标题 ###三级标题 ####四级标题 #####五级标题 ######六级标题 一级标题 二级标题 ...
- 修改PowerShell的输入提示符
如下图,"PS C:\Windows\System32\drivers\etc>" 就是PowerShell的输入提示符,默认是显示"PS"加上当前所在的 ...