Spring JSR 303 驗證 - 自定義錯誤訊息

假設我們有一個帶驗證註釋的簡單類

public class UserDTO {
    @NotEmpty
    private String name;

    @Min(18)
    private int age;

//getters/setters
}

用於檢查 UserDTO 有效性的控制器。

@RestController
public class ValidationController {

    @RequestMapping(value = "/validate", method = RequestMethod.POST)
    public ResponseEntity<String> check(@Valid @RequestBody UserDTO userDTO,
           BindingResult bindingResult) {
        return new ResponseEntity<>("ok" , HttpStatus.OK);
    }
}

並且測試。

@Test
public void testValid() throws Exception {
    TestRestTemplate template = new TestRestTemplate();
    String url = base + contextPath + "/validate";
    Map<String, Object> params = new HashMap<>();
    params.put("name", "");
    params.put("age", "10");

    MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
    headers.add("Content-Type", "application/json");

    HttpEntity<Map<String, Object>> request = new HttpEntity<>(params, headers);
    String res = template.postForObject(url, request, String.class);

    assertThat(res, equalTo("ok"));
}

名稱和年齡都無效,因此在 BindingResult 中我們有兩個驗證錯誤。每個都有程式碼陣列。

最小支票程式碼

0 = "Min.userDTO.age"
1 = "Min.age"
2 = "Min.int"
3 = "Min"

併為 NotEmpty 檢查

0 = "NotEmpty.userDTO.name"
1 = "NotEmpty.name"
2 = "NotEmpty.java.lang.String"
3 = "NotEmpty"

讓我們新增一個 custom.properties 檔案來替換預設訊息。

@SpringBootApplication
@Configuration
public class DemoApplication {

    @Bean(name = "messageSource")
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
        bean.setBasename("classpath:custom");
        bean.setDefaultEncoding("UTF-8");
        return bean;
    }

    @Bean(name = "validator")
    public LocalValidatorFactoryBean validator() {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        bean.setValidationMessageSource(messageSource());
        return bean;
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

如果我們將該行新增到 custom.properties 檔案中

NotEmpty=The field must not be empty!

顯示錯誤的新值。要解決訊息驗證器,請從頭開始檢視程式碼以查詢正確的訊息。

因此,當我們在 .properties 檔案中為使用 @NotEmpty 註釋的所有情況定義 NotEmpty 鍵時,將應用我們的訊息。

如果我們定義一條訊息

Min.int=Some custom message here.

我們 app min 檢查整數值的所有註釋都使用新定義的訊息。

如果我們需要本地化驗證錯誤訊息,則可以應用相同的邏輯。