Springboot Bean Validation校验框架

 2023-09-15 阅读 24 评论 0

摘要:我们的校验框架通常用于DTO层,用户从前端通过Json串传入值,后端对传入的Json封装到DTO层中,我们对DTO层的元素进行校验,比如邮箱,手机号等等。 首先需要引入bean校验需要的jar包: <!-- Validation 相关依赖 --><dependenc

我们的校验框架通常用于DTO层,用户从前端通过Json串传入值,后端对传入的Json封装到DTO层中,我们对DTO层的元素进行校验,比如邮箱,手机号等等。

首先需要引入bean校验需要的jar包:

<!-- Validation 相关依赖 --><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>6.0.16.Final</version></dependency><dependency><groupId>javax.el</groupId><artifactId>javax.el-api</artifactId><version>3.0.0</version></dependency><dependency><groupId>org.glassfish.web</groupId><artifactId>javax.el</artifactId><version>2.2.6</version></dependency>

怎么用?看下面的例子

@Data
public class UserDTO implements Serializable {/*** serialVersionUID*/private static final long serialVersionUID = -5087359471567830690L;/*** 用户名*/@NotBlank(message = "用户名不能为空!",groups = {InsertValidationGroup.class})private String username;/*** 用户密码*/@NotBlank(message = "密码不能为空!",groups = {InsertValidationGroup.class})@Length(min = 6, max = 18,message = "密码长度不能少于6位,不能多于18位!")private String password;/*** 邮箱*/@NotEmpty(message = "邮箱不能为空!",groups = {InsertValidationGroup.class})@Email(message = "必须为有效邮箱!")private String email;/*** 年龄*/@NotNull(message = "年龄不能为空!",groups = {InsertValidationGroup.class})@Max(value = 60, message = "年龄不能大于60岁!")@Min(value = 18, message = "年龄不能小于18岁!")private Integer age;/*** 手机号*/@NotBlank(message = "手机号不能为空!",groups = {InsertValidationGroup.class})private String phone;/*** 版本号*/@NotNull(message = "版本号不能为空!",groups = {UpdateValidationGroup.class})private Long version;/*** 创建时间*/private LocalDateTime created;

如果没有遵循校验框架的注解,就会抛出message中的异常信息。

去除boot校验,常用的约束注解:

  • 空值校验类: @Null, @NotNull, @NotEmpty, @NotBlank等
  • 范围校验类: @Min, @Size, @Digits, @Future, @Negative等
  • 其他校验类: @Email, @URL, @AssertTrue, @Pattern等

上面可以看到groups=UpdateValidationGroup.classgroups = {UpdateValidationGroup.class}groups=UpdateValidationGroup.class的代码,这个是分组校验。也就是说,比如主键注册的时候的无需填入,可以为空值,不需要在插入的时候校验。比如上面的版本号(乐观锁),只是在更新的时候校验。控制层可以这么写:

public ResponseResult update(@NotNull @PathVariable("id") Long id,@Validated(UpdateValidationGroup.class)@RequestBody UserDTO userDTO) {int update = userService.update(id, userDTO);if (update == 1) {return ResponseResult.success("更新成功!");} else {return ResponseResult.failure(ErrorCodeEnum.UPDATE_FAILURE);}}

当然,还需要创建两个空的接口分组:

public interface UpdateValidationGroup {
}
public interface InsertValidationGroup {
}

我们还可以自定义校验注解:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;/*** 自定义手机号约束注解*/
@Documented
// 注解的作用
@Target({ElementType.FIELD})
// 注解的保留策略
@Retention(RetentionPolicy.RUNTIME)
// 与非约束注解的不同之处
// 约束注解关联验证器类
@Constraint(validatedBy = PhoneValidator.class)
public @interface Phone {// 约束注解验证时输出的信息String message() default "手机号校验错误";// 约束注解在验证时所属的组别Class<?>[] groups() default {};// 约束注解的有效负载Class<? extends Payload>[] payload() default {};
}/*** 自定义手机号约束注解关联验证器*/
public class PhoneValidator implements ConstraintValidator<Phone, String> {/*** 自定义校验逻辑方法* @param s* @param constraintValidatorContext* @return*/@Overridepublic boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {// 演示demo// 手机号验证规则 158...String check = "158\\d{8}";Pattern regex = Pattern.compile(check);String phone = Optional.ofNullable(s).orElse("");Matcher matcher = regex.matcher(phone);return matcher.matches();}
}

我们捕捉到了异常之后,下面对异常进行统一的处理:

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {/*** 拦截业务类异常* @param e* @return*/@ResponseBody@ExceptionHandler(value = BusinessException.class)public ResponseResult businessExceptionHandle(BusinessException e) {log.error("捕捉到业务类异常:", e);return ResponseResult.failure(e.getCode(), e.getMessage());}/*** 拦截运行时异常* @param e*/@ResponseBody@ExceptionHandler(value = RuntimeException.class)public ResponseResult runtimeExceptionHandle(RuntimeException e) {log.error("捕捉到运行时异常:", e);return ResponseResult.failure(ErrorCodeEnum.UNKNOWN_ERROR.getCode(),e.getMessage());}/*** 捕捉系统级异常* @param th* @return*/@ResponseBody@ExceptionHandler(value = Throwable.class)public ResponseResult throwableHandle(Throwable th) {log.error("捕捉Throwable异常:", th);return ResponseResult.failure(ErrorCodeEnum.SYSTEM_ERROR.getCode(),th.getMessage());}}

miui去除boot校验?统一的结果封装:

@Data
@ApiModel(value = "统一返回结果实体",description = "封装统一返回结果信息实体"
)
public class ResponseResult<T> implements Serializable {/*** serialVersionUID*/private static final long serialVersionUID = 7813356989387725160L;/*** 是否成功*/@ApiModelProperty(name = "success",value = "是否成功",required = true,dataType = "Boolean")private Boolean success;/*** 编码*/@ApiModelProperty(name = "code",value = "编码",required = false,dataType = "String")private String code;/*** 描述信息*/@ApiModelProperty(value = "描述信息")private String message;/*** 结果*/@ApiModelProperty(value = "泛型结果T")private T result;/*** 成功* @param result* @param <T>* @return*/public static <T> ResponseResult<T> success(T result) {ResponseResult<T> responseResult = new ResponseResult<>();responseResult.setSuccess(Boolean.TRUE);responseResult.setResult(result);return responseResult;}/*** 失败* @param code* @param message* @param <T>* @return*/public static <T> ResponseResult<T> failure(String code, String message) {ResponseResult<T> responseResult = new ResponseResult<>();responseResult.setSuccess(Boolean.FALSE);responseResult.setCode(code);responseResult.setMessage(message);return responseResult;}/*** 失败* @param codeEnum* @param <T>* @return*/public static <T> ResponseResult<T> failure(ErrorCodeEnum codeEnum) {return failure(codeEnum.getCode(), codeEnum.getMessage());}
}

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/61960.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息