Spring Boot Mapping验证代码到MessageSource消息

时间:2018-03-26 20:15:23

标签: spring spring-mvc spring-boot spring-web

问题:

我正在尽可能多地使用Spring Boot Auto-configuration来减少锅炉板代码。我无法让Spring Validation代码自动映射到我的外部化messages.properties。它只有在我添加自己的 LocalValidatorFactoryBean 并使用完全限定的javax约束消息时才有效。

目标

我想在我的应用程序中基于Spring Validation code 全局覆盖 @javax.validation.constraints.NotNull defaultMessage

我做的第一件事是注册这个bean ...我真的需要吗?我看到Spring Boot有一个,但它似乎与messages.properties无关。

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

下一个对我来说很惊讶。 Spring Validation有这个漂亮的DefaultMessageCodesResolver,可以为看起来像这样的故障提供出色的代码策略:

"code": "NotNull",
"codes": [
   "NotNull.user.firstName",
   "NotNull.firstName",
   "NotNull.java.lang.String",
   "NotNull"
],

但是@NotNull约束甚至没有考虑这些代码。 Validation Conversion的spring文档暗示这样的东西确实存在但却没有任何有用的东西。

I wrote a sample application here and you can see that it's not working.

问题

如何根据messages.properties中的代码覆盖Spring Validation错误的默认消息?

相关build.gradle

  • springBootVersion =' 2.0.0.RELEASE'
  • 编译(' org.springframework.boot:弹簧引导起动的web&#39)

的src /主/资源/ messages.properties:

NotNull.user.firstName=This doesn't work
NotNull.firstName=Or this
NotNull.java.lang.String=This doesn't work either
NotNull=And this doesn't work

javax.validation.constraints.NotNull.message=THIS DOES WORK! But why have codes then?

弹出自动配置输出,证明自动配置已加载。

   MessageSourceAutoConfiguration matched:
      - ResourceBundle found bundle URL [file:/home/szgaljic/git/jg-github/journey-through-spring/basic-web-validations/build/resources/main/messages.properties] (MessageSourceAutoConfiguration.ResourceBundleCondition)
      - @ConditionalOnMissingBean (types: org.springframework.context.MessageSource; SearchStrategy: current) did not find any beans (OnBeanCondition)

其他一些相关的启动日志:

2018-03-26 14:32:22.970 TRACE 1093 --- [           main] o.s.beans.CachedIntrospectionResults     : Found bean property 'validationMessageSource' of type [org.springframework.context.MessageSource]

验证约束:

public class User {
    @NotNull
    private String username;

    @NotNull
    private String firstName;
}

仅用于测试的控制器:

@RestController
public class UserController {

    @PostMapping("/users")
    public List<ObjectError> testValidation(@Valid @RequestBody User user){
       return null; // null implies no failed validations.. just for testing
    }

}

无法使用代码

我尝试评论/取消注释messages.properties中的消息,但它只接受 javax.validation.constraints.NotNull.message 的值。

1 个答案:

答案 0 :(得分:0)

由于配置

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

因此,您正在使用Bean Validation,然后使用密钥javax.validation.constraints.NotNull.message从message.properties文件中获取来自org.hibernate.validator.ValidationMessages.properties文件的消息。如果您想拥有键值对:

NotNull.user.firstName=This doesn't work
NotNull.firstName=Or this
NotNull.java.lang.String=This doesn't work either
NotNull=And this doesn't work

工作你必须写如下:

@Autowired
private MessageSource messageSource;

@PostMapping("/users")
public List<ObjectError> testValidation(@Valid @RequestBody User user, BindingResult bindingResult){
   bindingResult.getFieldErrors().forEach(fieldError -> new ObjectError(
   /*Assumes that ObjectError has constructor of ObjectError(String message) */
          messageSource.getMessage(fieldError, Locale.getDefault())
   ));
   return null; 
}