springboot之Validation參數校驗


一 前言

本篇是關於springboot的參數校驗知識,當然也適用其它java應用;讀完本篇將學會基本的參數校驗,自定義參數校驗和分組參數校驗;良好的代碼規范和書寫方式猶如散文版清麗脫俗,行雲流水;

公眾號:知識追尋者

知識追尋者(Inheriting the spirit of open source, Spreading technology knowledge;)

二 校驗入門

2.1 pom.xml

springboot在 web啟動器中已經包含validator包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

非springboot項目,需要自行引入依賴

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.5.Final</version>
</dependency>
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>jakarta.el</artifactId>
    <version>3.0.3</version>
</dependency>

2.2 常用約束說明

  • @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(regex=,flag=) :指定的正則表達式
  • @URL:必須是一個URL
  • @Email:必須是email格式
  • @NotBlank: 字符串不能為空
  • @NotEmpty:集合不能為空
  • @Length: 長度必須在指定范圍內
  • @Valid :對實體類進行校驗

2.4 實體約束示例

  • 簡單注解約束使用示例如下;
  • 如果成員是實體,需要帶上 @Valid注解;
/**
 * @Author lsc
 * <p> </p>
 */
@Data
public class SysUser {

    private Long id;

    @NotNull(message ="用戶名不能為空")
    @Size(min = 3, max = 5, message = "用戶名長度為{min}-{max}之間")
    private String username;

    @NotNull(message ="昵稱不能為空")
    private String name;

    @NotNull(message ="密碼不能為空")
    private String password;

    @Email(message = "郵箱格式不合法")
    private String email;

    private String gender;
}

2.5 控制層示例

  1. 需要在class加上 @Validated
  2. 如果參數是實體 需要 加上 @Valid 注解
/**
 * @Author lsc
 * <p> </p>
 */
@RestController
@Validated
public class SysUserController {

    // 方法參數為實體校驗
    @PostMapping("/register")
    public ResponseEntity register(@Valid @RequestBody SysUser sysUser){

        return ResponseEntity.ok(sysUser);
    }

    // 方法參數校驗
    @GetMapping("user")
    public ResponseEntity getUser(@NotNull(message ="用戶名不能為空") String username) {
        SysUser sysUser = new SysUser();
        sysUser.setName("知識追尋者");
        return ResponseEntity.ok(sysUser);
    }
}

2.6 異常捕獲

全局異常捕獲,當出現參數校驗不合法時捕獲異常,並且返回給前端;

/**
 * @Author lsc
 * <p> </p>
 */
@ControllerAdvice
public class GlobHandler {

    // 捕獲方法參數校驗異常
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public ResponseEntity constraintViolationExceptionHandler(ConstraintViolationException e){
        Set<ConstraintViolation<?>> message = e.getConstraintViolations();
        HashMap<String, Object> map = new HashMap<>();
        message.stream().forEach(msg -> {
            String path = msg.getPropertyPath().toString();
            String field = path.substring(path.indexOf(".")+1);
            map.put(field,msg.getMessageTemplate());
        });
        return ResponseEntity.ok(map);
    }

    // 捕獲實體參數校驗異常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseEntity resolveMethodArgumentNotValidException(MethodArgumentNotValidException e){
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        HashMap<String, Object> map = new HashMap<>();
        allErrors.stream().forEach(error -> {
            FieldError fieldError = (FieldError) error;
            map.put(fieldError.getField(), fieldError.getDefaultMessage());
        });
        return ResponseEntity.ok(map);
    }
}

2.7 請求示例

三 自定義校驗規則

特殊的字段需要自定義規則,比如身份證號碼,郵箱,電話等;

定義校驗注解

@Target({ METHOD, FIELD })
@Retention(RUNTIME)
@Constraint(validatedBy = GenderValidator.class)
@Documented
public @interface Gender {

    String message() default "性別為男或者女";


    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default {};
}

GenderValidator 實現 ConstraintValidator 接口並提供校驗規則

/**
 * @Author lsc
 * <p> </p>
 */
public class GenderValidator implements ConstraintValidator<Gender, String> {


    // 初始化校驗值
    @Override
    public void initialize(Gender constraintAnnotation) {

    }

    // 校驗規則
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {

        return "男".equals(value) || "女".equals(value);
    }
}

在成員變量使用 注解

    @Gender()
    private String gender;

四 分組校驗

默認情況下,不指定分組都屬於默認組;使用分組校驗有利於分層校驗開發;

新建2個接口,一個用於查詢, 一個用於添加

/**
 * @Author lsc
 * <p> </p>
 */
public interface ADD extends Default {

}
public interface Select extends Default {
}

修改 實體校驗規則,如果不指定分組 默認是 Default 組

    @NotNull(message ="用戶名不能為空",groups = ADD.class)
    @Size(min = 3, max = 5, message = "用戶名長度為{min}-{max}之間")
    private String username;

    @NotNull(message ="昵稱不能為空", groups = Select.class)
    private String name;

    @NotNull(message ="密碼不能為空",groups = ADD.class)
    private String password;

    @Email(message = "郵箱格式不合法", groups = Select.class)
    private String email;

控制層示例,此時只會校驗 ADD 組和 Default組

    // 分組校驗
    @PostMapping("/user")
    public ResponseEntity addUser(@Validated(value = ADD.class) @RequestBody SysUser sysUser){

        return ResponseEntity.ok(sysUser);
    }

五 參考文檔

https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/

https://zhuanlan.zhihu.com/p/96403211

https://blog.csdn.net/justry_deng/article/details/86571671

https://juejin.im/post/5dc8bc745188254e7a155ba0

https://www.jianshu.com/p/89a675b7c900

本套教程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM