

Spring
Bootアプリケーションで@DateTimeFormatを使ってExampleForm.java内のDate型のバリデーションを行いたいのですが、messages.propertiesにtypeMismatchを利用してメッセージ定義をしてもメッセージにセットされません。  
色々と調べたのですがやり方がわかリませんでした。

解決策を教えていただきたいです。

**ExampleForm.java**

[code]

    @Getter
    @Setter
    public class ExampleForm {
      @NotNull(message="searchName is Empty!!")
      private String searchName;
    
      // このフィールドのバリデーションメッセージを設定したい
      @DateTimeFormat(pattern="yyyyMMddhhmmss")
      private Date searchDate;
    }
    
[/code]

**ExampleController.java**

[code]

    @RestController
    public class ExampleForm {
    
      @GetMapping("/example/search")
      public List<String> searchExample(@Validated ExampleForm form) throws Exception {
    
        // ... 処理 ...
    
        return list;
      }
    
    }
    
[/code]

**ExceptionControllerAdvice.java**

[code]

    @RestControllerAdvice
    public class ExceptionControllerAdvice {
    
      @ExceptionHandler(BindException.class)
      public List<String> handleExampleBindException(BindException bindEx) throws Exception {
        List<String> list = new ArrayList<String>();
        for(FieldError err : bindEx.getBindingResult().getFieldErrors()) {
          list.add(err.getDefaultMessage());
        }
        return list;
      }
    
    }
    
[/code]

**MessageConfig.java**

[code]

    @Configuration
    public class MessageConfig {
    
      @Bean
      public MessageSource messageSource() {
        ReloadResourceBundleMessageSource ms = ReloadResourceBundleMessageSource();
        ms.setBeanname("classpath:messages");
        ms.setDefaultEncoding("UTF-8");
        return ms;
      }
    
      @Bean
      public MessageSourceAccessor messageSourceAccessor() {
        LocalValidatorFactoryBean lvfb = LocalValidatorFactoryBean();
        lvfb.setValidationMessageSource(messageSource());
      }
    
    }
    
[/code]

**messages.properties**

[code]

    typeMismatch.java.util.Date=Invalid Date Format.
    typeMismatch.exampleForm.searchDate=searchDate of exampleForm is Invalid Date Format.
    typeMismatch.searchDate=searchDate is Invalid Date Format.
    
[/code]

**動作確認コマンド**

[code]

    curl -X GET "http://localhost:port/example/search?searchName=xxxxxxx&searchDate=xxxxxxxxxxxxxx"
    
[/code]

補足  
デフォルトメッセージに入っているのは以下のメッセージでした。

> Failed to convert property value of type 'java.lang.String' to required type
> 'java.util.Date' for property 'searchDate'; nested exception is
> java.lang.IllegalArgumentException: could not parse date: Unparsable
> date:"xxxxxxxxxxxxxx"


CC BY-SA 4.0
2021-07-12T09:53:59.507
78130
2023-04-11T10:02:45.297
47269
question
java spring spring-boot rest
SpringBoot @DateTimeFormatを使ったバリデーションエラーメッセージを設定できない


`MessageSource` から対応するメッセージを取得する必要があります。  
`getDefaultMessage()` で取得したメッセージはあくまで " _デフォルト_ " メッセージです。

[code]

    @RestControllerAdvice
    @RequiredArgsConstructor
    public class ExceptionControllerAdvice {
    
        private final MessageSource messageSource;
    
        @ExceptionHandler(BindException.class)
        public List<String> handleExampleBindException(final BindException bindEx) throws Exception {
            final List<String> list = new ArrayList<>();
            for (final FieldError err : bindEx.getBindingResult().getFieldErrors()) {
                list.add(messageSource.getMessage(err, LocaleContextHolder.getLocale()));
            }
            return list;
        }
    
    }
    
[/code]

Bean Validation(Hibernate Validator) で検証エラーになった場合には
`ValidationMessages.properties`(※) で定義したメッセージがデフォルトメッセージになるので
`getDefaultMessage()` で期待したメッセージが取得できます。

しかし今回のエラーは Bean Validation を使った処理(validation)でなく、それより前の処理(binding)のものです。

※ デフォルト設定の場合。質問文のコードでは `LocalValidatorFactoryBean` カスタマイズによって
`messages.properties` に変更されています。

参考:

  * [3\. Validation, Data Binding, and Type Conversion](https://docs.spring.io/spring-framework/docs/5.3.9/reference/html/core.html#validation)
  * [3.7.3. Configuring a DataBinder](https://docs.spring.io/spring-framework/docs/5.3.9/reference/html/core.html#validation-binder)
  * ([3.2. Resolving Codes to Error Messages](https://docs.spring.io/spring-framework/docs/5.3.9/reference/html/core.html#validation-conversion))

* * *

質問のデフォルトエラーメッセージを設定しているのは
[`DefaultBindingErrorProcessor`](https://github.com/spring-projects/spring-
framework/blob/v5.3.9/spring-
context/src/main/java/org/springframework/validation/DefaultBindingErrorProcessor.java#L78-L79)
なので、このクラスを置き換える(デフォルトメッセージにあらかじめ所望の文字列をセットするようにする)というのも、別の対応策として挙げられるかと思います。


CC BY-SA 4.0
2021-07-17T02:44:18.323
78243
2021-07-17T03:49:10.990
2021-07-17T03:49:10.990
2808
2808
78130
answer