项目开发扩展-6.数据校验
项目开发扩展-数据校验
Springboot参数校验
Springboot参数校验的多种实现方式:
基础字段校验、组合校验、自定义注解校验
https://www.cnblogs.com/cjsblog/p/8946768.html
https://www.jianshu.com/p/89a675b7c900
https://www.cnblogs.com/mooba/p/11276062.html
[springboot使用hibernate validator校验]
https://www.cnblogs.com/mr-yang-localhost/p/7812038.html
1.传统校验
传统校验通过工具类进行校验
2.注解校验
未使用校验之前:(通过if、else语句进行数据校验)
配置:Springboot中引入校验,spring-boot-starter-web包自动依赖hibernate-validator,不用再重复引入,需要声明一个bean注册到spring容器,这个bean是一个容器后处理器,会把校验的逻辑通过AOP织入有@Validated注解的class,具体可以看这个类的源码。这一步在springboot其实也不用做,ValidationAutoConfiguration这个配置类自动完成
注意:@Valid 与@Validated的使用场景与区别
部分场景需要制定验证顺序,需指定相应的校验规则:https://www.cnblogs.com/muxi0407/p/12108762.html
// 借助校验器实现简单数据校验优化代码内容
Springboot 校验器的简单使用-使用校验器做简单数据验证,重复性验证额外进行处理:
实体配置:
@Data
@TableName("MIP_ADMIN_USER")
public class Admin extends Model<Admin> {
private static final long serialVersionUID = 1L;
/**
* 管理员ID
*/
@TableId("ADMIN_ID")
private String adminId;
/**
* 管理员编号
*/
@NotBlank(message = "指定管理员编号不能为空")
@TableField("ADMIN_NUM")
private String adminNum;
/**
* 管理员名称
*/
@NotBlank(message = "指定管理员名称不能为空")
@TableField("ADMIN_NAME")
private String adminName;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@TableField("CREATE_TIME")
private Date createTime;
@Override
protected Serializable pkVal() {
return this.adminId;
}
}
controller层校验
@RestController("admin-system-adminUser")
@RequestMapping("/system/adminUser")
public class AdminController {
private static final String SUPER_ADMIN = "superAdmin";
/**
* 操作模块限定
**/
private static final String TITLE = "后台管理-管理员信息维护";
@Autowired
private AdminService adminService;
/**
* 添加/修改管理员信息(根据指定的adminId进行判断)
**/
@RequiresRoles(SUPER_ADMIN)
@SysOperLogAnno(title = TITLE, businessType = BusinessType.INSERT, operationDesc = "编辑管理员账号")
@PostMapping("/edit")
public AjaxResult editAdmin(@Validated @RequestBody Admin admin) {
if (!adminService.editAdmin(admin)) {
return AjaxResultUtil.error(ResultEnum.OPER_FAIL_ERROR);
}
return AjaxResultUtil.success();
}
}
校验器校验模式配置
@Configuration
public class ValidatorConfig {
@Bean
public Validator validator() {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
// failFast的意思只要出现校验失败的情况,就立即结束校验,不再进行后续的校验操作
.failFast(true)
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
return validator;
}
}
全局异常处理配置
捕获校验异常,使异常信息正常返回给前端
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理Get请求中,使用@Valid验证路径中请求实体校验失败后抛出的异常
*/
@ExceptionHandler(BindException.class)
public AjaxResult BindExceptionHandler(BindException e) {
String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
return AjaxResultUtil.error(e.getMessage());
}
/**
* 处理请求参数格式错误
* @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
*/
@ExceptionHandler(ConstraintViolationException.class)
public AjaxResult resolveConstraintViolationException(ConstraintViolationException ex) {
// WebResult errorWebResult = new WebResult(WebResult.FAILED);
Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
if (!CollectionUtils.isEmpty(constraintViolations)) {
StringBuilder msgBuilder = new StringBuilder();
for (ConstraintViolation constraintViolation : constraintViolations) {
msgBuilder.append(constraintViolation.getMessage()).append(",");
}
String errorMessage = msgBuilder.toString();
if (errorMessage.length() > 1) {
errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
}
// errorWebResult.setInfo(errorMessage);
// return errorWebResult;
return AjaxResultUtil.error(errorMessage);
}
return AjaxResultUtil.error(ex.getMessage());
// errorWebResult.setInfo(ex.getMessage());
// return errorWebResult;
}
/**
* 处理请求参数格式错误
* @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常
**/
@ExceptionHandler(MethodArgumentNotValidException.class)
public AjaxResult resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
// WebResult errorWebResult = new WebResult(WebResult.FAILED);
List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
if (!CollectionUtils.isEmpty(objectErrors)) {
StringBuilder msgBuilder = new StringBuilder();
for (ObjectError objectError : objectErrors) {
msgBuilder.append(objectError.getDefaultMessage()).append(",");
}
String errorMessage = msgBuilder.toString();
if (errorMessage.length() > 1) {
errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
}
// errorWebResult.setInfo(errorMessage);
// return errorWebResult;
return AjaxResultUtil.error(errorMessage);
}
// errorWebResult.setInfo(ex.getMessage());
// return errorWebResult;
return AjaxResultUtil.error(ex.getMessage());
}
}
常见错误:
@NotNull 和 @NotEmpty 和@NotBlank 区别
@NotEmpty 用在集合类上面 @NotBlank 用在String上面 @NotNull 用在基本类型上
常用参数注解:
@NotNull 限制必须不为null @AssertFalse 限制必须为false @AssertTrue 限制必须为true @Past 限制必须是一个过去的日期 @Pattern(value) 限制必须符合指定的正则表达式 @Size(max,min) 限制字符长度必须在min到max之间 @Past 验证注解的元素值(日期类型)比当前时间早 @NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) @NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 @Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 @Pattern(regexp = “”) 正则表达式校验参数 @Range(min = 0, max = 10) / Max / @Min 校验最大值/最小值,参数类型为整形(pageNo, pageSize)
Service层参数校验:https://blog.csdn.net/qq_24664619/article/details/103242971
错误页面返回:
Service实现参数校验(借助AOP实现):https://blog.csdn.net/yuxiao97/article/details/98309120
Hibernate Validator 使用介绍:https://www.jianshu.com/p/0bfe2318814f