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 检查整数值的所有注释都使用新定义的消息。

如果我们需要本地化验证错误消息,则可以应用相同的逻辑。