参考文章

1、使用 validation 校验参数

使用 @Valid 注解总结有如下优点:

  1. 代码简化与可读性@Valid 注解使得表单验证和对象验证更加简洁和易读。传统的验证方式可能需要编写大量的 if 语句来检查每个字段的有效性,而使用 @Valid 注解则可以将验证逻辑与业务逻辑分离,使代码更加清晰。

  2. 强大的验证功能@Valid 注解可以与 Java Bean Validation API 中的其他注解(如 @NotNull, @NotBlank, @NotEmpty 等)结合使用,提供丰富的验证功能。这些注解可以应用于字段、构造函数、getter 方法等多个位置,满足各种验证需求。

  3. 分组验证@Valid 注解支持分组验证,这意味着你可以根据不同的场景应用不同的验证规则。例如,在更新用户信息时,你可能只想验证某些字段,而在创建新用户时,你可能需要验证所有字段。通过定义验证分组,你可以轻松实现这一功能。

  4. 自动处理异常:当验证失败时,Spring MVC 会自动将错误信息绑定到相应的字段上,并返回给前端。这意味着你不需要手动处理验证异常,减少了开发工作量。

  5. 与 Spring 框架集成@Valid 注解是 Spring 框架的一部分,因此它可以与 Spring 的其他功能(如数据绑定、类型转换等)无缝集成,使得整个开发过程更加顺畅。

  6. 可扩展性: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]”)被注释的元素必须符合指定的正则表达式
@Email被注释的元素必须是电子邮件地址
@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/
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐