복붙노트

[SPRING] 스프링 부트 매핑 검증 코드와 MessageSource 메시지 비교

SPRING

스프링 부트 매핑 검증 코드와 MessageSource 메시지 비교

문제:

보일러 플레이트 코드를 줄이기 위해 가능한 한 많은 스프링 부팅 자동 구성을 사용하려고합니다. 내 외부화 된 messages.properties에 자동으로 매핑 할 수있는 Spring Validation 코드를 얻을 수 없습니다. 내 자신의 LocalValidatorFactoryBean을 추가하고 정규화 된 javax 제약 메시지를 사용하는 경우에만 작동합니다.

Spring Validation 코드를 기반으로하는 애플리케이션에서 @ javax.validation.constraints.NotNull에 대한 defaultMessage를 전역 적으로 덮어 쓰고 싶습니다.

내가 한 첫 번째 일은이 콩을 등록하는 것이 었습니다 ... 꼭해야합니까? 나는 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 제약 조건으로 간주되지 않습니다. 유효성 검사 변환에 대한 봄 문서에는 이와 같은 것이 존재하지만 아직 유용한 것은 없다는 것을 알 수 있습니다.

여기에 샘플 애플리케이션을 작성했는데 작동하지 않는다는 것을 알 수 있습니다.

의문

messages.properties의 코드를 기반으로 Spring Validation 오류의 기본 메시지를 무시하려면 어떻게합니까?

관련 build.gradle

src / main / resources / 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?

Spring Auto-Configuration로드 된 auto-config를 나타내는 출력.

   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. ==============================

    1.구성 때문에

    구성 때문에

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

    그래서 당신은 Bean Validation을 사용하고있다. 그리고 나서 spring은 javax.validation.constraints.NotNull.message 키를 사용하여 org.hibernate.validator.ValidationMessages.properties 파일에서 오버라이드하는 message.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; 
    }
    
  2. from https://stackoverflow.com/questions/49499891/spring-boot-mapping-validation-codes-to-messagesource-message by cc-by-sa and MIT license