👩🏽💻个人主页:阿木木AEcru (更多精彩内容可进入主页观看)
🔥 系列专栏:《Docker容器化部署系列》 《Java每日面筋》
💹每一次技术突破,都是对自我能力的挑战和超越。
目录
- 一、前言
- 二、使用SpringBoot-Validation
- 2.1 添加依赖
- 2.2 注解使用说明
- 2.3 注解应用到实体
- 2.4 测试是否生效
- 2.5 全局异常捕获
- 三、结尾
一、前言
你还在使用if else
的方式进行入参的校验吗?
能看的出来,这样的校验方式看起来很不优雅,当然也是能达到目的。如果说有非常多的参数需要校验的话,就要写非常多的if else
,就像老太婆的裹脚布一样,又臭又长,让人看起来非常的难受。话不多说,下面我就给大家推荐一个优雅校验入参的方式吧!
二、使用SpringBoot-Validation
2.1 添加依赖
<!-- spring-boot 2.3及以上的版本需要引入包 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
2.2 注解使用说明
注解 | 说明 |
---|---|
@NotNull | 验证注解的元素必须非空(即非null且非空字符串) |
@NotEmpty | 验证注解的字符串元素必须非空且长度大于0 |
@NotBlank | 验证注解的字符串元素必须非空,并且至少包含一个非空白字符 |
@Null | 验证注解的元素必须为null |
@AssertTrue | 验证布尔值必须为true |
@AssertFalse | 验证布尔值必须为false |
@Size | 验证注解的字符串或集合元素的数量是否在指定的范围内 |
@Length | 验证注解的字符串元素的长度是否在指定的范围内 |
@Min | 验证注解的数值是否大于或等于指定的最小值 |
@Max | 验证注解的数值是否小于或等于指定的最大值 |
@DecimalMin | 验证注解的数值是否大于或等于指定的十进制最小值 |
@DecimalMax | 验证注解的数值是否小于或等于指定的十进制最大值 |
@Email | 验证注解的字符串是否是有效的电子邮件地址 |
@Pattern | 验证注解的字符串是否与指定的正则表达式匹配 |
@Past | 验证注解的日期元素是否在当前日期之前 |
@Future | 验证注解的日期元素是否在当前日期之后 |
@Valid | 递归验证关联对象的属性 |
@Positive | 验证注解的数值是否大于0 |
@Negative | 验证注解的数值是否小于0 |
@Digits | 验证注解的数值是否有正确的整数位数和小数位数 |
2.3 注解应用到实体
@Data
public class TestOneDTO {@NotNull(message = "用户名不允许为空")@Size(min = 3, max = 50, message = "用户名长度必须在3到50个字符之间")private String username;@NotNull(message = "密码不允许为空")@Size(min = 6, max = 20, message = "密码长度必须在6到20个字符之间")private String password;@Email(message = "电子邮箱格式不正确")private String email;@Min(value = 18, message = "年龄必须至少为18岁")@Max(value = 100, message = "年龄不允许超过100岁")private Integer age;@Past(message = "生日不能大于当前时间")private LocalDateTime birthDate;@Pattern(regexp = "^((\\+86)|(0086))?(-\\d{3}-)?\\d{8}$", message = "手机号码格式不正确")private String phoneNumber;// 校验对象中的另一个对象(对象内容如下)@Validprivate Address address;public boolean validate() {if (username == null || username.length() < 3 || username.length() > 50) {System.out.println("用户名长度必须在3到50个字符之间");return false;}if (password == null || password.length() < 6 || password.length() > 20) {System.out.println("密码长度必须在6到20个字符之间");return false;}if (email == null || !email.contains("@")) {System.out.println("电子邮箱格式不正确");return false;}if (age == null || age < 18 || age > 100) {System.out.println("年龄必须至少为18岁且不允许超过100岁");return false;}if (birthDate != null && birthDate.isAfter(LocalDateTime.now())) {System.out.println("生日必须是过去的时间");return false;}if (phoneNumber != null && !phoneNumber.matches("^((\\+86)|(0086))?(-\\d{3}-)?\\d{8}$")) {System.out.println("手机号码格式不正确");return false;}return true;}
}@Data
class Address {@NotBlank(message = "地址不允许为空")@Size(min = 5, max = 200, message = "地址长度必须在5到200个字符之间")private String street;@NotBlank(message = "城市不允许为空")private String city;}
2.4 测试是否生效
可以看出,这里没有任何请求内容依然成功了,这是因为还少了一个注解 @Valid
需要在入参前面添加上。
加上 @Valid
注解后,再次请求可以看到已经有异常信息了,这时就能使用 全局异常处理器
进行捕获处理,格式化响应的异常信息内容。
2.5 全局异常捕获
全局异常捕获类如下
@ControllerAdvice
@ResponseBody
@Component
@Slf4j
public class GlobalExceptionHandler {/*** @Valid校验异常处理* @param request* @param e* @return*/@ExceptionHandler(value = MethodArgumentNotValidException.class)public R methodArgumentNotValidExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException e){StringBuffer sb = new StringBuffer();List<ObjectError> allErrors = e.getAllErrors();if (CollUtil.isNotEmpty(allErrors)){for (ObjectError allError : allErrors) {sb.append(allError.getDefaultMessage()).append("|");}}return R.of(CommonConstants.FAIL,null,sb.toString());}@ExceptionHandler(value = Exception.class)public R exceptionHandler(HttpServletRequest request, Exception e){e.printStackTrace();log.info("Exception异常全局拦截:{}",e.getMessage());// 其余异常简单返回为服务器异常return R.failed("服务器繁忙,请联系管理员或稍后再试!");}}
加上之后再次请求
异常信息已经被格式化了,如果需要其他格式的异常信息提示,可以自主调整相关的异常信息格式化内容来满足你的需求。
在这里需要注意的是,当在同一个字段上使用多个注解时,校验框架会按照它们在类定义中出现的顺序进行校验。如果一个字段违反了前面的校验规则,后续的校验可能不会执行。
三、结尾
感谢观看至此,希望该文章能够帮助到您提升知识和技能。如果您喜欢我的内容,请不要忘记点赞和分享哦!👍