1. 程式人生 > >【spring】-- jsr303參數校驗器

【spring】-- jsr303參數校驗器

col private 系統 用戶 異常處理器 ont ext image extend

技術分享圖片

一、為什麽要進行參數校驗?

當我們在服務端控制器接受前臺數據時,肯定首先要對數據進行參數驗證,判斷參數是否為空?是否為電話號碼?是否為郵箱格式?等等。

這裏有個問題要註意:

前端代碼一般上會對這些數據進行驗證,為什麽後臺還要驗證一次呢?

  前臺驗證針對的是系統用戶,保證用戶的輸入沒有問題。

  後臺驗證針對的是客戶端傳輸到服務器的這一過程中可能出現的問題導致的數據異常。

二、為什麽要使用jsr303參數校驗器?

不是用jsr303驗證器我們是如何進行參數驗證的呢?

首先創建一個參數校驗工具類(這裏我只是簡單驗證傳入的是否是以1開頭的11位數字)

public class
ValidatorUtil { private static final Pattern mobile_pattern = Pattern.compile("1\\d{10}"); public static boolean isMobile(String src) { if(StringUtils.isEmpty(src)) { return false; } Matcher m = mobile_pattern.matcher(src); return
m.matches(); } }

然後在控制器中判斷是否為空,然後驗證格式

技術分享圖片

這種方式在每個需要參數驗證地方都需要寫這麽一大堆,不符合復用性原則而且不美觀。

那使用jsr303驗證器最終結果是怎樣呢?

最終的控制器代碼:

技術分享圖片

三、jsr303使用步驟

1、引入依賴

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

2、定義註解

模仿官方的@NotNull來寫

官方@NotNull:

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
@Documented
@Constraint(validatedBy = { })
public @interface NotNull {

    String message() default "{javax.validation.constraints.NotNull.message}";

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

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

    /**
     * Defines several {@link NotNull} annotations on the same element.
     *
     * @see javax.validation.constraints.NotNull
     */
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    @Retention(RUNTIME)
    @Documented
    @interface List {

        NotNull[] value();
    }
}

自己定義的:

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {IsMobileValidator.class })
public @interface  IsMobile {
    //是否允許為空,true表示不允許
    boolean required() default true;
    //如果校驗不通過給出的提示信息
    String message() default "手機號碼格式錯誤";

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

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

定義完註解還不夠,因為系統不知道怎樣去校驗該註解,所有還需要編寫一個校驗器類,並且在@Constraint註解中指明校驗器類。(註意將註解文件和校驗器類文件放在同一包下)

3、編寫註解驗證器類

public class IsMobileValidator implements ConstraintValidator<IsMobile, String> {

    //是否可以為空
    private boolean required = false;
    
    public void initialize(IsMobile constraintAnnotation) {
        required = constraintAnnotation.required();
    }

    public boolean isValid(String value, ConstraintValidatorContext context) {
        if(required) {
            return ValidatorUtil.isMobile(value);
        }else {
            if(StringUtils.isEmpty(value)) {
                return true;
            }else {
                return ValidatorUtil.isMobile(value);
            }
        }
    }

}

4、使用註解

技術分享圖片

四、還存在的問題

使用jsr303校驗器校驗參數,如果不通過則直接拋出異常,我們必須定義全局異常處理器來捕獲這個異常,否則前臺用戶必須打開瀏覽器控制臺才能看到錯誤信息。

關於全局異常處理器的使用請看我的下篇文章。

【spring】-- jsr303參數校驗器