本文内容说明:
1、JSR303是规范,定义了一些校验注解
2、hibernate也提供了一些校验注解
3、自定义校验规则(正则)
4、后端获取校验的结果
5、Hibernate Validator官方参考链接
6、其他文章在编写JSR303分组校验,和自定义注解校验
所以在项目中是采用前端校验+后端校验+全局异常捕获
本文先讲解基础校验和统一异常处理
,其他文章在编写
JSR303分组校验
编写自定义校验注解
前端自定义校验请查看我这篇文件入口
JSR303数据校验之分组校验-入口
JSR303自定义校验注解
//包
import org.hibernate.validator.constraints.URL;
import javax.validation.constraints.*;
//使用
@NotEmpty//代表字段不为空--会采用默认的消息提示
private String firstLetter;
@URL(message = "logo必须是地址")//自定义消息提示
private String logo;
@NotEmpty//不为空
@Pattern(regexp = "/^[a-zA-Z]$/",message = "必须是a-z或者A-Z的字母") //自定义规则-使用正则
private String firstLetter;
@NotNull//Integer类型使用@NotNull不能使用@NotEmpty
@Min(value = 0,message = "必须大于等于0")
private Integer sort;
//友情提取最好是多注解校验-非空+其他
@Vaild是规范提供的注解
@Validated是spring提供的注解
public R save( @Valid @RequestBody BrandEntity brand) {}
public R save(@Valid @RequestBody BrandEntity brand,BindingResult result) {}
代码如下-直接看注释
//R是自己定义的ResponseJson
@RequestMapping("/save")
public R save(@Valid @RequestBody BrandEntity brand,BindingResult result) {
//如果校验失败
if (result.hasErrors()){
Map<String, String> map = new HashMap<>();
//获取校验结果
result.getFieldErrors().forEach((item)->{
//FieldError -获取到错误提示
String message = item.getDefaultMessage();
//获取错误字段属性的名字
String field = item.getField();
map.put(field,message);
});
return R.error(400,"数据不合法").put("data",map);
}else {
brandService.save(brand);
}
return R.ok();
}
空检查
@Null 验证对象是否为null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
Booelan检查
@AssertTrue 验证 Boolean 对象是否为 true
@AssertFalse 验证 Boolean 对象是否为 false
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length(min=, max=) string is between min and max included.
日期检查
@Past 验证 Date 和 Calendar 对象是否在当前时间之前
@Future 验证 Date 和 Calendar 对象是否在当前时间之后
@Pattern 验证 对象是否符合正则表达式的规则--自定义校验
自定义校验例如:
@Pattern(regexp = "/^[a-zA-Z]$/",message = "必须是a-z或者A-Z的字母")
private String firstLetter;
如果注解爆红是因为新的版本需要是validation启动器
小编使用springboot2.1.8.RELEASE
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
文档入口
说明:这个方法,实体类的字段需要检验
public R save(@Valid @RequestBody BrandEntity brand) {
brandService.save(brand);
return R.ok();
}
说明:
1、MethodArgumentNotValidException.class是校验失败的异常
2、不能精确匹配异常的话,就去大的异常进行处理
3、其余看注释
4、消息提示,小编采用了枚举也附上自定义枚举的代码
package com.atguigu.gulimall.product.exception;
import com.atguigu.common.exception.BizCodeEnume;
import com.atguigu.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
/**
* @author suqinyi
* @Date 2021/4/8
* 统一处理异常
*/
@Slf4j
//@ResponseBody
//@ControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
@RestControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")//指定位置
public class GulimallExceptionControllerAdvice {
//注明:R是自定义的Json响应工具类
//数据校验的异常
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R handleVildException(MethodArgumentNotValidException e){
log.error("数据校验出现异常{},异常类型{}",e.getMessage(),e.getClass());
BindingResult bindingResult = e.getBindingResult();
HashMap<String, String> map = new HashMap<>();
bindingResult.getFieldErrors().forEach(item->{
map.put(item.getField(),item.getDefaultMessage());
});
// return R.error(400,"数据校验出错,不要瞎搞哦").put("data",map);
return R.error(BizCodeEnume.VALID_EXCEPTION.getCode(),BizCodeEnume.VALID_EXCEPTION.getMsg()).put("data",map);
}
//不能精确匹配异常就来这个最大的异常
@ExceptionHandler(value = Throwable.class)//任意类型的异常
public R handleException( Throwable throwable){
//return R.error(400,"出异常了");
return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
}
}
自定义异常枚举类
package com.atguigu.common.exception;
/**
* @author suqinyi
* @Date 2021/4/8
*/
/***
* 错误码和错误信息定义类
*/
//枚举最大的特点--是私有构造器
public enum BizCodeEnume {
UNKNOW_EXCEPTION(10000,"系统未知异常"),
VALID_EXCEPTION(100001,"参数校验失败");
private int code;
private String msg;
//编写构造器
BizCodeEnume(int code,String msg){
this.code=code;
this.msg=msg;
}
public int getCode(){
return code;
}
public String getMsg(){
return msg;
}
}
这样在controller出现校验失败就会抛出异常,公共异常处理类就能捕获,封装成map返回提示。
JSR303是规范,hibernate也提供的一些注解
全局异常捕获