반응형
보통 MessageSource는 국제화(i18n)를 목적으로 사용한다.
하지만 이를 이용하면 예외처리가 좀 더 간편해진다.
build.gradle에 의존성 추가
implementation 'net.rakugakibox.util:yaml-resource-bundle:1.1'
MessageConfiguration 파일 생성
import net.rakugakibox.util.YamlResourceBundle;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
@Configuration
public class MessageConfiguration implements WebMvcConfigurer {
@Bean // 세션에 지역설정. default는 KOREAN = 'ko'
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(Locale.KOREAN);
return slr;
}
@Bean // 지역설정을 변경하는 인터셉터. 요청시 파라미터에 lang 정보를 지정하면 언어가 변경됨.
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
@Override // 인터셉터를 시스템 레지스트리에 등록
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
@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 파일을 읽도록 처리
private static class YamlMessageSource extends ResourceBundleMessageSource {
@Override
protected ResourceBundle doGetBundle(String basename, Locale locale) throws MissingResourceException {
return ResourceBundle.getBundle(basename, locale, YamlResourceBundle.Control.INSTANCE);
}
}
}
application.yml에 i18n경로 및 인코딩 정보 추가
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/test
driver-class-name: org.h2.Driver
username: sa
jpa:
database-platform: org.hibernate.dialect.H2Dialect
properties.hibernate.hbm2ddl.auto: update
showSql: true
messages:
basename: i18n/exception
encoding: UTF-8
다국어 처리 message yml파일 작성
path : resources\i18n\exception_en.yml resources\i18n\exception_ko.yml
메시지 예시
# exception_en.yml
unKnown:
code: "-9999"
msg: "An unknown error has occurred."
userNotFound:
code: "-1000"
msg: "This member not exist"
# exception_ko.yml
unKnown:
code: "-9999"
msg: "알수 없는 오류가 발생하였습니다."
userNotFound:
code: "-1000"
msg: "존재하지 않는 회원입니다."
ResponseService의 getFailResult메소드에서 code, msg 사용
public CommonResult getFailResult(int code, String msg) {
CommonResult result = new CommonResult();
result.setSuccess(false);
result.setCode(code);
result.setMsg(msg);
return result;
}
ExceptionAdvice의 에러 메시지를 messageSource로 변경
@RequiredArgsConstructor
@RestControllerAdvice
public class ExceptionAdvice {
private final ResponseService responseService;
private final MessageSource messageSource;
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
protected CommonResult defaultException(HttpServletRequest request, Exception e) {
// 예외 처리의 메시지를 MessageSource에서 가져오도록 수정
return responseService.getFailResult(Integer.valueOf(getMessage("unKnown.code")), getMessage("unKnown.msg"));
}
@ExceptionHandler(CUserNotFoundException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
protected CommonResult userNotFoundException(HttpServletRequest request, CUserNotFoundException e) {
// 예외 처리의 메시지를 MessageSource에서 가져오도록 수정
return responseService.getFailResult(Integer.valueOf(getMessage("userNotFound.code")), getMessage("userNotFound.msg"));
}
// code정보에 해당하는 메시지 조회
private String getMessage(String code) {
return getMessage(code, null);
}
// code정보, 추가 argument로 현재 locale에 맞는 메시지 조회
private String getMessage(String code, Object[] args) {
return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
}
}
+ ) 바로 띄울 때
<!-- ... -->
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!-- ... -->
<spring:message code="unKnown.msg" />
++ ) yml파일에 상위 level추가
test:
unKnown:
code: "-9999"
msg: "알수 없는 오류가 발생하였습니다."
호출
<spring:message code="test.unKnown.msg" />
반응형
'Backend > Spring | SpringBoot' 카테고리의 다른 글
[Spring Security] Spring Security 적용 (0) | 2024.03.15 |
---|---|
[Spring] @RequestBody (0) | 2024.03.14 |
[Spring] redirect경로 (0) | 2024.03.13 |
[Spring Security] CSRF 토큰 (0) | 2024.03.13 |
[JPA] Auto Increase가 안될 때 (0) | 2024.03.11 |