Spring Boot之Validation自定義實現總結

bladestone發表於2019-03-26

Spring Boot Validation定製

雖然在Spring Boot中已經提供了非常多的預置註解,用以解決在日常開發工作中的各類內容,但是在特定情況仍然存在某些場景,無法滿足需求,需要自行定義相關的validator。本節將針對自定義的validator進行介紹。

自定義的註解

這裡的場景設定為進行IP地址的驗證,通過註解的方式,讓使用者使用驗證規則。註解定義如下:

@Target({ElementType.FIELD})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = IPAddressValidator.class)
public @interface IPAddress {
    String message() default "{ipaddress.invalid}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

這個註解是作用在Field欄位上,執行時生效,觸發的是IPAddressValidator這個驗證類。

  • message
    定製化的提示資訊,主要是從ValidationMessages.properties裡提取,也可以依據實際情況進行定製
  • groups
    這裡主要進行將validator進行分類,不同的類group中會執行不同的validator操作
  • payload
    主要是針對bean的,使用不多。
    然後自定義Validator,這個是真正進行驗證的邏輯程式碼:
public class IPAddressValidator implements ConstraintValidator<IPAddress, String> {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        Pattern pattern = compile("^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$");
        Matcher matcher = pattern.matcher(value);
        try {
            if (!matcher.matches()) {
                return false;
            } else {
                for (int i = 1; i <= 4; i++) {
                    int octet = Integer.valueOf(matcher.group(i));
                    if (octet > 255) {
                        return false;
                    }
                }
                return true;
            }
        } catch (Exception e) {
            return false;
        }
    }
}

關於IP地址的驗證規則是通用的,具體邏輯不用太在意,主要是需要這裡Validator這個介面,以及其中的兩個泛型引數,第一個為註解名稱,第二個為實際欄位的資料型別。

使用自定義的註解

定義了實體類CustomFieldBean.java

@Data
public class CustomFieldBean {
    @IPAddress
    private String ipAddr;
}

使用方法非常簡約,基於註解,無侵入邏輯。

單元測試用例

測試程式碼:

@RunWith(SpringRunner.class)
@SpringBootTest
public class CustomFieldValidatorTest {
    @Autowired
    private ProductService productService;

    @Test(expected = ConstraintViolationException.class)
    public void testInvalid() {
        CustomFieldBean customFieldBean = new CustomFieldBean();
        customFieldBean.setIpAddr("1.2.33");

        this.productService.doCustomField(customFieldBean);
    }

    @Test
    public void testValid() {
        CustomFieldBean customFieldBean = new CustomFieldBean();
        customFieldBean.setIpAddr("1.2.33.123");

        this.productService.doCustomField(customFieldBean);
    }
}

自定義執行Validator

如果不希望由系統自行觸發Validator的驗證邏輯,則可以由開發者自行進行驗證。在Spring Boot已經內建了Validator例項,直接將其載入進來即可。
使用示例如下:

@Autowired
private Validator validator;

自定義執行的單元測試

測試程式碼如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class CodeValidationTest {
    @Autowired
    private Validator validator;

    @Test(expected = ConstraintViolationException.class)
    public void testValidator() {
        CustomFieldBean input = new CustomFieldBean();
        input.setIpAddr("123.3.1");
        Set<ConstraintViolation<CustomFieldBean>> violations = validator.validate(input);
        if (!violations.isEmpty()) {
            throw new ConstraintViolationException(violations);
        }
    }
}

總結

關於Validation的相關用法,一共寫了4篇,希望能夠對大家有用。

相關文章