기록용
직접 정의한 헤더값의 language값에 따른 예외처리 메시지 다중화
applicaiton.yml
spring:
messages:
basename: i18n/exception
encoding: UTF-8
resources/i18n/exception_eng.yml
※ 다른 포맷 사용시 그에 따른 값으로 변경
# exception_eng.yml
unKnown:
code: "-9999"
msg: "An unknown error has occurred. SadPepe :("
userNotFound:
code: "-1000"
msg: "This member not exist. SadPepe :("
resources/i18n/exception_kor.yml
※ 다른 포맷 사용시 그에 따른 값으로 변경
# exception_kor.yml
unKnown:
code: "-9999"
msg: "알 수 없는 오류가 발생하였습니다. SadPepe :("
userNotFound:
code: "-1000"
msg: "존재하지 않는 회원입니다. SadPepe :("
ISO_639 alpha-3 포맷 사용 : kor, eng
https://ko.wikipedia.org/wiki/ISO_639-1_%EC%BD%94%EB%93%9C_%EB%AA%A9%EB%A1%9D
Locale 객체 변환 테스트 코드
exception 에러가 뜨지 않으면 정상
import org.apache.commons.lang3.LocaleUtils;
import org.junit.jupiter.api.Test;
import java.util.Locale;
public class LocaleUtilsTest {
@Test
void test() {
Locale kor = LocaleUtils.toLocale("kor");
System.out.println(kor);
Locale eng = LocaleUtils.toLocale("eng");
System.out.println(eng);
}
}
MessageConfiguration.java
@Configuration
public class MessageConfiguration implements WebMvcConfigurer {
@Bean // yml 파일을 참조하는 MessageSource 선언
public MessageSource messageSource(
@Value("${spring.messages.basename}") String basename,
@Value("${spring.messages.encoding}") String encoding
) {
YamlMessageSource ms = new YamlMessageSource();
ms.setBasename(basename);
ms.setDefaultEncoding(encoding);
ms.setAlwaysUseMessageFormat(true);
ms.setUseCodeAsDefaultMessage(true);
ms.setFallbackToSystemLocale(true);
return ms;
}
// locale 정보에 따라 다른 yml 파일을 읽도록 처리 (kor, eng [ISO_639 alpha-3 포맷])
private static class YamlMessageSource extends ResourceBundleMessageSource {
@Override
protected ResourceBundle doGetBundle(String basename, Locale locale) throws MissingResourceException {
return ResourceBundle.getBundle(basename, locale, YamlResourceBundle.Control.INSTANCE);
}
}
}
GlobalExceptionHandler.java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ApplicationException.class)
public ExceptionMessage handleApplicationException(ApplicationException e) {
Locale locale = getLocaleByLanguage();
return ExceptionMessage.of(
getMessage("userNotFound.code", locale),
getMessage("userNotFound.msg", locale)
);
private Locale getLocaleByLanguage() {
String langCd = httpServletRequest.getHeader("langCd"); //직접 정의한 헤더값
return LocaleUtils.toLocale(langCd);
}
// code 정보에 해당하는 메시지를 조회한다.
private String getMessage(String code, Locale locale) {
return messageSource.getMessage(code, null, locale);
}
// code 정보, 추가 argument로 현재 locale에 맞는 메시지를 조회한다.
private String getMessage(String code, Object[] args, Locale locale) {
return messageSource.getMessage(code, args, locale);
}
}
+ spring validaiton 다국어 처리
현재까지 yml은 지원 X
@Getter
@Setter
public class MenuCreateRequest {
@NotNull(message = "{name.notnull}")
private String parentId;
}
/resources/messages/validation_eng.properties
name.notnull=sdaasd
/resources/messages/validation_kor.properties
name.notnull=한글이다
※ 스프링부트는 기본적으로 Accept-Language값에 따라 다국어 처리를 해줌
validaiton_en.properties, validaiton_kr.properties 형식으로 했으면
Accept-Language값이 없을경우 자동으로 Locale.getDefault()값을 기준으로 .properties를 찾음
나는 프론트에서 Accept-Language를 kor, eng 값 포맷으로 보내주길 원함
따라서 값이 없을경우 default로 한글(_kor.properteis)을 찾을 수 있께 설정 추가
MessageConfiguration.java
@Slf4j
@Configuration
public class MessageConfiguration implements WebMvcConfigurer {
//Accept-Language값에 kor 혹은 eng가 없을때 기본값 kor로 설정
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(LocaleUtils.toLocale("kor")); // ko_KR
Locale.setDefault(LocaleUtils.toLocale("kor"));
return localeResolver;
}
@Bean
public MessageSource validationMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:/messages/validation");
messageSource.setDefaultEncoding(Encoding.DEFAULT_CHARSET.toString());
messageSource.setDefaultLocale(Locale.getDefault());
messageSource.setCacheSeconds(600);
return messageSource;
}
@Override
public Validator getValidator() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(validationMessageSource());
return bean;
}
}
참고
https://zepinos.tistory.com/45
https://daddyprogrammer.org/post/499/springboot2-exception-handling-with-messagesource/
https://www.inflearn.com/questions/271842
https://oingdaddy.tistory.com/266
https://ifuwanna.tistory.com/291
'Tech > Spring' 카테고리의 다른 글
SpringBoot 커스텀 프로퍼티에 대한 문서와 자동완성 ※ Spring Configuration Processor (0) | 2024.04.17 |
---|---|
2개 이상의 DB를 사용하는 Spring Boot 환경에서 Spring Data Jpa 사용시 트랜잭션 관련 에러 (0) | 2023.01.29 |
Validation 클래스 단위 제약과 조건부 검사 설정 (0) | 2021.12.22 |
Mybatis와 Jpa 사용시 트랜잭션 묶어서 사용하는 방법(※ 멀티 datasource 설정 / QueryDsl) (0) | 2021.07.24 |
Spring Filter에서 request Body 가공하기 (0) | 2021.07.19 |