java springboot总结--starter-validation

时间:2025-08-29 09:36:01来源:互联网

下面小编就为大家分享一篇java springboot总结--starter-validation,具有很好的参考价值,希望对大家有所帮助。

说明

实际是使用的hibernate-validator的功能

官网:https://hibernate.org/validator/

使用

加入依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
	<version>2.5.14</version>
</dependency>

创建要校验的类

@Data
public class UserInfoVo {
    @NotBlank(message = "名字不能为空")
    private String name;

    @NotBlank(message = "手机号不能为空")
    @Pattern(regexp = "^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$", message = "手机号格式有误")
    private String phone;

    @NotBlank(message = "地址不能为空")
    private String address;
}

全局异常捕获

/**
 * 統一异常处理
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public AjaxResult defaultErrorHandler(HttpServletRequest request, Exception exception) throws Exception {
    	log.error(exception.getMessage(), exception);
        AjaxResult result;
		if (exception instanceof BindException){
            result = AjaxResult.error("参数错误 - " + Objects.requireNonNull(((BindException) exception).getFieldError()).getDefaultMessage());
        }else {
			result = AjaxResult.error("服务器异常");
		}
        return result;
    }
}
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ApiResponse<Map<String, String>>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        BindingResult result = ex.getBindingResult();
        Map<String, String> errors = new HashMap<>();
        result.getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });

        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body(new ApiResponse<>("400", "Validation Error", errors));
    }

    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<ApiResponse<Map<String, String>>> handleConstraintViolationException(ConstraintViolationException ex) {
        Map<String, String> errors = new HashMap<>();
        for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
            String fieldName = violation.getPropertyPath().toString();
            String errorMessage = violation.getMessage();
            errors.put(fieldName, errorMessage);
        }

        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body(new ApiResponse<>("400", "Validation Error", errors));
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiResponse<String>> handleOtherExceptions(Exception ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(new ApiResponse<>("500", "Internal Server Error", null));
    }
}

MethodArgumentNotValidException 主要用于处理通过 @Valid 或 @Validated 注解进行的请求参数验证失败的情况。这种异常通常发生在以下场景:
当使用 @Valid 或 @Validated 注解对请求参数进行验证时,如果验证失败,就会抛出 MethodArgumentNotValidException。
这种异常通常发生在控制器层,用于处理单个对象或多个对象的验证。

ConstraintViolationException 主要用于处理通过 javax.validation 包中的注解(如 @NotNull, @Size, @Pattern 等)进行的验证失败情况。这种异常通常发生在以下场景:
当使用 javax.validation 包中的注解进行验证时,如果验证失败,就会抛出 ConstraintViolationException。
这种异常通常发生在实体对象或领域模型对象的验证过程中。

 

接口如下:

在接口中使用vo类来接受参数,加上@Validated才会生效,不然不生效

在实际开发中,后台数据校验一般放在controller层,使用@Validated集合hibernate提供的一些列注解,可以很轻松优雅的实现数据校验的功能。

@PostMapping("/testVo")
@ResponseBody
public AjaxResult testVo(@Validated UserInfoVo infoVo){
    System.out.println(infoVo);
    return AjaxResult.success("成功");
}

调用接口测试效果

常用注解说明

Bean Validation 中内置的 constraint

注解

作用

@Valid

被注释的元素是一个对象,需要检查此对象的所有字段值

@Null

被注释的元素必须为 null

@NotNull

被注释的元素必须不为 null

@AssertTrue

被注释的元素必须为 true

@AssertFalse

被注释的元素必须为 false

@Min(value)

被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@Max(value)

被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@DecimalMin(value)

被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@DecimalMax(value)

被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@Size(max, min)

被注释的元素的大小必须在指定的范围内

@Digits (integer, fraction)

被注释的元素必须是一个数字,其值必须在可接受的范围内

@Past

被注释的元素必须是一个过去的日期

@Future

被注释的元素必须是一个将来的日期

@Pattern(value)

被注释的元素必须符合指定的正则表达式

 

Hibernate Validator 附加的 constraint

注解

作用

@Email

被注释的元素必须是电子邮箱地址

@Length(min=, max=)

被注释的字符串的大小必须在指定的范围内

@NotEmpty

被注释的字符串或集合不能为null或长度为0

@Range(min=, max=)

被注释的数值元素必须在合适的范围内(包括指定值)

@NotBlank

被注释的字符串不能为null和空格字符串

@URL(protocol=,host=, port=,regexp=, flags=)

被注释的字符串必须是一个有效的url

 

注解属性说明

message:通用属性,用来作为自定义校验不通过提示的文案

groups:通用属性,指定一个或多个分组类

其他

@Valid@Validated说明

@Validated由spring框架提供,@Valid由validation框架提供

@Validated可以用在类型、方法和方法参数上,但是不能用在成员属性上;

@Valid可以用在方法、构造函数、方法参数和成员属性上

分组:@Validated提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制

分组的使用

场景:新增用户信息和修改用户信息所需要验证的字段是不同的

定义两个接口用于分组

public interface AppUserVaildC {
}

public interface AppUserVaildU {
}

Model中字段上指定在什么组内时进行验证

Default 是默认分组

@Range(min = 0,max = 100,message = "年龄必须在[0,100]",groups={Default.class})
    /**年龄*/
private Integer age;
@Range(min = 0,max = 2,message = "性别必须在[0,2]",groups = {AppUserVaildC.class})
    /**性别 0:未知;1:男;2:女*/
private Integer sex;

Controller中指定分组

@PostMapping("save")
public void v1(@RequestBody @Validated({AppUserVaildC.class, AppUserVaildU.class}) AppUser appUser,BindingResult result){
      if(result.hasErrors()){
            for (ObjectError error : result.getAllErrors()) {
                System.out.println(error.getDefaultMessage());
            }
        }
}

组序列:

除了按组指定是否验证之外,还可以指定组的验证顺序,前面组验证不通过的,后面组不进行验证

@GroupSequence({AppUserVaildC.class, AppUserVaildU.class, Default.class})
public interface GroupOrder {
}

Controller中使用

@PostMapping("save")
public void v1(@RequestBody @Validated({GroupOrder.class}) AppUser appUser,BindingResult result){
      if(result.hasErrors()){
            for (ObjectError error : result.getAllErrors()) {
                System.out.println(error.getDefaultMessage());
            }
        }
}

 

本站部分内容转载自互联网,如果有网站内容侵犯了您的权益,可直接联系我们删除,感谢支持!