버전 : 3.3.4
jdk : 21
스프링 컨트롤러에서 @Valid로 유효성 검사를 할때 클라이언트에 값이 잘못되었을경우 Request객체에 @NotNull, @NotBlank등을 사용하여 유효성 검사를 하고 메세지를 전달하는 방법을 사용할때 기본 메세지를 바꾸는 방법을 알아보자.
기본 컨트롤러와 Request 객체를 만들고 @NotNull, @NotBlank, @Size
를 선언했다. 컨트롤러에서 따로 BindingResult는 선언하지 않았으며 @Valid만 선언하여 ExceptionHandler로 위임했다.
controller
request
exception response 객체
exceptionhandler
어노테이션마다 locale에 따른 파일을 찾고 그 파일에 default 메세지가 선언되어있다.
hibernate-validator.jar에
ValidationMessags.properties에서 확인할 수 있다.
만약 이렇게 어노테이션마다의 message를 입력해주면 해당하는 변수는 작성한 message로 응답이 전송돤다.
프로젝트에서
/resources에 ValidationMessages_ko.properties,
ValidationMessages_en.properties 등으로 기존에 hibernate-validator에 있는 파일과 동일한 이름으로 생성 한 후에
메세지를 작성한다면 각 locale에 맞는 default 메세지가 오버라이딩 된다.
# ValidationMessages_ko.properties
jakarta.validation.constraints.NotBlank.message=필수 입력값 입니다.
jakarta.validation.constraints.NotNull.message=필수 입력값 입니다.
jakarta.validation.constraints.Size.message={min} - {max}사이로 입력해주세요.
# ValidationMessages_en.properties
jakarta.validation.constraints.NotBlank.message=This is a required input value.
jakarta.validation.constraints.NotNull.message=This is a required input value.
jakarta.validation.constraints.Size.message=Please enter between {min} and {max}.
하드코딩되어 message와 name의 msg가 한글로 나온다.
만약 locale에 맞는 메세지를 전달하려면
ValidationMessages에 key를 추가하고
어노테이션 message에 "{추가한key}" 형태로 입력해야 한다.
또한 MessageSource를 추가해 ExceptionHandler에 하드코딩 되어있는 message도 바꿔줘야 한다.
# ValidationMessages_ko.properties
jakarta.validation.constraints.NotBlank.message=필수 입력값 입니다.
jakarta.validation.constraints.NotNull.message=필수 입력값 입니다.
jakarta.validation.constraints.Size.message={min} - {max}사이로 입력해주세요.
user.name.notblank=이름을 입력해주세요. -- 추가
# ValidationMessages_en.properties
jakarta.validation.constraints.NotBlank.message=This is a required input value.
jakarta.validation.constraints.NotNull.message=This is a required input value.
jakarta.validation.constraints.Size.message=Please enter between {min} and {max}.
user.name.notblank=Please enter your name. -- 추가
@NotBlank(message="{user.name.notblank}")
@Configuration
public class LocaleConfig {
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(Locale.getDefault())
return localeResolver;
}
}
@Configuration
public class MessageSourceConfig {
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages/messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(3600);
messageSource.setFallbackToSystemLocale(false);
return messageSource;
}
}
LocaleContextHolder.getLocale() - thread locale 따라감.
@Component
@RequiredArgsConstructor
public class MessageSourceService {
private final MessageSource messageSource;
public String getMessage(String key){
return messageSource.getMessage(key, null, LocaleContextHolder.getLocale());
}
public String getMessage(String key, Object[] args, Locale locale) {
return messageSource.getMessage(key, args, locale);
}
}
resources/경로 - messages.properties 추가(locale - ko, en등)
# messages_ko.properties
MISSING_REQUIRED_VALUE=필수값이 누락되었습니다.
# messages_en.properties
MISSING_REQUIRED_VALUE=A required value is missing.