【SpringBoot3】统一参数校验
使用@Valid注解在Spring MVC和其他Java EE应用程序中带来了显著的好处。它简化了验证逻辑,使得代码更加清晰和易于阅读,通过将验证规则与业务逻辑分离,提高了代码的可维护性。此外,@Valid注解提供了丰富的验证功能,包括分组验证和自动处理异常,使得验证过程更加灵活和高效。由于其与Spring框架的紧密集成,开发者能够更容易地利用Spring提供的其他功能,如数据绑定和类型转换
参考文章
1、使用 validation
校验参数
使用 @Valid
注解总结有如下优点:
-
代码简化与可读性:
@Valid
注解使得表单验证和对象验证更加简洁和易读。传统的验证方式可能需要编写大量的 if 语句来检查每个字段的有效性,而使用@Valid
注解则可以将验证逻辑与业务逻辑分离,使代码更加清晰。 -
强大的验证功能:
@Valid
注解可以与 Java Bean Validation API 中的其他注解(如@NotNull
,@NotBlank
,@NotEmpty
等)结合使用,提供丰富的验证功能。这些注解可以应用于字段、构造函数、getter 方法等多个位置,满足各种验证需求。 -
分组验证:
@Valid
注解支持分组验证,这意味着你可以根据不同的场景应用不同的验证规则。例如,在更新用户信息时,你可能只想验证某些字段,而在创建新用户时,你可能需要验证所有字段。通过定义验证分组,你可以轻松实现这一功能。 -
自动处理异常:当验证失败时,Spring MVC 会自动将错误信息绑定到相应的字段上,并返回给前端。这意味着你不需要手动处理验证异常,减少了开发工作量。
-
与 Spring 框架集成:
@Valid
注解是 Spring 框架的一部分,因此它可以与 Spring 的其他功能(如数据绑定、类型转换等)无缝集成,使得整个开发过程更加顺畅。 -
可扩展性:Java Bean Validation API 是可扩展的,你可以定义自己的验证注解和验证器,以满足特定的验证需求。这使得
@Valid
注解具有很高的灵活性。
综上所述,使用 @Valid
注解可以提高代码的可读性、可维护性和可扩展性,同时简化验证逻辑,减少开发工作量。
validation
具体使用步骤
1)引入jar包依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2)Controller参数中增加注解 @Valid
@GetMapping("/user")
@ResponseBody
public User user(@Valid User user) {
return user;
}
3)在参数Vo中增加具体校验注解
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@NotNull(message = "名字不能为空")
String name;
@Min(value = 18, message = "必须年满18岁")
int age;
}
4)在全局异常拦截器 WebExceptionHandler 中增加异常统一处理方法
取得抛出的异常信息,并封装成统一的自定义异常
@ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
@ResponseBody
public AjaxResponse<?> hanlderValidException(BindException e) {
List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
String message = fieldErrors.stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(";"));
return AjaxResponse.error(new CustomException(ErrorCode.BAD_REQUEST, message));
}
validation
有哪些校验方法
@Valid
注解主要用于表单验证,它可以与其他校验注解结合使用,确保提交的数据满足一定的规则
注解 | 描述 |
---|---|
@Null | 被注释的元素必须为null |
@NotNull | 被注释的元素不能为null |
@AssertTrue | 该字段只能为true |
@AssertFalse | 该字段的值只能为false |
@Min(“value”,“message”) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@Max(“value”,“message”) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@DecimalMin(“value”,“message”) | 被注释的元素必须是一个数字,验证小数的最小值 |
@DecimalMax(“value”,“message”) | 被注释的元素必须是一个数字,验证小数的最大值 |
@Size(max,min) | 检查该字段的size是否在min和max之间,可以是字符串、数组、集合、Map等 |
@Past | 被注释的元素必须是一个过去的日期 |
@Future | 被注释的元素必须是一个将来的日期 |
@Pattern(regexp = “[abc]”) | 被注释的元素必须符合指定的正则表达式 |
被注释的元素必须是电子邮件地址 | |
@Length(max=5,min=1,message=“长度在1~5”) | 检查所属的字段的长度是否在min和max之间,只能用于字符串 |
@NotEmpty | 被注释的字符串必须非空 |
这些注解可以添加在实体类的字段上,以定义字段的校验规则。当使用@Valid
注解时,这些规则将被触发,并对相应的字段进行校验。如果校验不通过,将会返回相应的错误提示信息。
2、使用Spring自带的断言工具类校验参数
使用 org.springframework.util.Assert
校验参数
1)在Controller中校验参数
@GetMapping("/user")
@ResponseBody
public User user(@Valid User user) {
Assert.isTrue(user.getName().equals("jackson"), "User must be a jackson");
return user;
}
2)在全局异常拦截器 WebExceptionHandler 中增加异常统一处理方法
Assert
工具类抛出的是IllegalArgumentException
异常,因此增加该异常的统一处理方法
@ExceptionHandler({IllegalArgumentException.class})
@ResponseBody
public AjaxResponse<?> hanlderIllegalArgumentException(IllegalArgumentException e) {
return AjaxResponse.error(new CustomException(ErrorCode.BAD_REQUEST, e.getMessage()));
}
Assert 有哪些校验方法
org.springframework.util.Assert
类是 Spring 框架提供的一个工具类,用于进行各种断言和校验。这个类包含了一系列静态方法,用于验证条件并在条件不满足时抛出异常
方法 | 描述 |
---|---|
notNull(Object object, String message) | 验证对象是否不为 null,如果为 null 则抛出 IllegalArgumentException ,带有给定的错误消息。 |
notNull(Object object) | 验证对象是否不为 null,如果为 null 则抛出 IllegalArgumentException ,错误消息为 “The object must not be null”。 |
hasText(String text, String message) | 验证字符串是否包含非空白字符,如果不包含则抛出 IllegalArgumentException ,带有给定的错误消息。 |
hasText(String text) | 验证字符串是否包含非空白字符,如果不包含则抛出 IllegalArgumentException ,错误消息为 “The text must not be null or empty”. |
isTrue(boolean expression, String message) | 验证给定的布尔表达式是否为 true,如果为 false 则抛出 IllegalArgumentException ,带有给定的错误消息。 |
isTrue(boolean expression) | 验证给定的布尔表达式是否为 true,如果为 false 则抛出 IllegalArgumentException ,错误消息为 “The expression must be true”. |
state(boolean expression, String message) | 验证给定的布尔表达式是否为 true,如果为 false 则抛出 IllegalStateException ,带有给定的错误消息。 |
state(boolean expression) | 验证给定的布尔表达式是否为 true,如果为 false 则抛出 IllegalStateException ,错误消息为 “The state must be true”. |
argument(boolean expression, String message) | 与 state 方法类似,但抛出的是 IllegalArgumentException 。 |
argument(boolean expression) | 与 state 方法类似,但抛出的是 IllegalArgumentException 。 |
这些方法提供了一种简洁的方式来验证应用程序中的条件,并在条件不满足时提供有用的错误消息。请注意,Assert
类中的方法主要用于内部验证和调试目的,通常不建议在生产代码中大量使用,因为它们可能会导致应用程序意外中断。在生产代码中,更建议使用更细粒度的异常处理和验证逻辑。
3、完整的全局异常拦截器 WebExceptionHandler
@ControllerAdvice
public class WebExceptionHandler {
@ExceptionHandler(CustomException.class)
@ResponseBody
public AjaxResponse<?> customerException(CustomException e) {
return AjaxResponse.error(e);
}
@ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
@ResponseBody
public AjaxResponse<?> hanlderValidException(BindException e) {
List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
String message = fieldErrors.stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(";"));
return AjaxResponse.error(new CustomException(ErrorCode.BAD_REQUEST, message));
}
@ExceptionHandler({IllegalArgumentException.class})
@ResponseBody
public AjaxResponse<?> hanlderIllegalArgumentException(IllegalArgumentException e) {
return AjaxResponse.error(new CustomException(ErrorCode.BAD_REQUEST, e.getMessage()));
}
@ExceptionHandler(Exception.class)
@ResponseBody
public AjaxResponse<?> exception(Exception e) {
return AjaxResponse.error(new CustomException(ErrorCode.UNKNOWN));
}
}
参考
- https://beanvalidation.org/3.0/
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)