いつもお世話になっています。
問題点・質問
SpringBootの@RestControllerを使って、WebAPIを提供するシステムを作成しています。
コントローラにおいて、ドメインに次の2つの入力チェックを行おうとしています
- 桁数チェック(アノテーション)
- 必須チェック(Spring Validator)
エラーが発生した時(@ExceptionHandler(MethodArgumentNotValidException.class)
にて)、BindingResult.getDefaultMessage
によって、エラーメッセージを取得しようとしています。しかし、
- の桁数チェック(アノテーション)ではメッセージプロパティに定義した文章が取得できますが、
- の必須チェック(Spring Validator)では取得結果がnullになってしまいます。
Spring Validatorを使ったチェックでも、メッセージプロパティに定義した文章を取得したいです。
MessageSourceからメッセージを取得するタイミングが無いのだと思いますが、どのように実装するのがよいか、お教え頂ければと思います。
コード
- ドメイン
public class MyFormSpringValidation { @Size(min = 6, max = 20) private String name; ・・・
- バリデータ
import org.springframework.validation.Validator; @Component public class MyFormSpringValidator implements Validator{ ・・・ @Override public void validate(Object target, Errors errors) { MyFormSpringValidation form = (MyFormSpringValidation) target; String name = form.getName(); if(StringUtils.isEmpty(name)) { errors.rejectValue("name" , "myformspringvalidator.name"); } // その他入力チェック増える予定 ・・・
- RESTコントローラ
@RestController @RequestMapping("/api") public class MyFormSpringValidationResource { @Inject MyFormSpringValidator myFormSpringValidator; @InitBinder public void initBinder(WebDataBinder binder) { binder.addValidators(myFormSpringValidator); } @RequestMapping(value = "/myformspringvalidation", method = RequestMethod.POST) @Timed public ResponseEntity<MyFormSpringValidation> createForm(@Validated @RequestBody MyFormSpringValidation myform) { ・・・
- エラー用コントローラ
@ControllerAdvice public class ExceptionTranslator { @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public ErrorDTO processValidationError(MethodArgumentNotValidException ex) { BindingResult result = ex.getBindingResult(); List<FieldError> fieldErrors = result.getFieldErrors(); ErrorDTO dto = new ErrorDTO(ErrorConstants.ERR_VALIDATION); for (FieldError fieldError : fieldErrors) { dto.add(fieldError.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage()); } return dto; }
- エラー用DTO
public class ErrorDTO implements Serializable { private final String message; private final String description; public void add(String objectName, String field, String message) { if (fieldErrors == null) { fieldErrors = new ArrayList<>(); } fieldErrors.add(new FieldErrorDTO(objectName, field, message)); } // 以下、他メンバ、Getter、Setter ・・・
- メッセージソース
@Configuration public class MessageConfiguration { @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasenames("i18n/messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } }
- メッセージソースをバリデータに設定
@Configuration public class LocaleConfiguration extends WebMvcConfigurerAdapter implements EnvironmentAware { @Inject private MessageSource messageSource; @Bean public LocalValidatorFactoryBean validator() { LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); localValidatorFactoryBean.setValidationMessageSource(messageSource); return localValidatorFactoryBean; } @Override public Validator getValidator() { return validator(); }
- メッセージプロパティファイル
myformspringvalidator.name=SpringValidatorでは必須です。 javax.validation.constraints.Size.message=文字数は{min}桁から{max}桁の範囲で入力してください。
試したこと
- バリデータ内の
errors.rejectValue
において、デフォルトメッセージにMessageSourceから取得したメッセージを渡す
import org.springframework.validation.Validator; @Component public class MyFormSpringValidator implements Validator{ ・・・ if(StringUtils.isEmpty(name)) { errors.rejectValue("name" , "myformspringvalidator.name" , messageSource.getMessage("myformspringvalidator.name", null, Locale.getDefault())); }
これはきっと、フレームワークの良しとするところではないかと・・・
ご助力を宜しくお願いします。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。