메시지, 국제화
메시지 / 국제화
메시지
기획자가 화면에 보이는 문구 중 "상품명" 단어를 "상품 이름" 으로 바꾸고 싶어한다면 ? 각 화면에서 이 단어를 일일이 변경해야 한다. 화면이 많아질수록 변경해야하는 파일의 수도 기하급수적으로 늘어날 것이고, 이는 비 효율적이다.
해결 방법
이러한 문제를 해결하기 위해 메시지 기능을 사용할 수 있다. 메시지 기능은 다양한 메시지(문구)를 한 곳에서 통합적으로 관리할 수 있다.
예시 : message.properties - 메시지 관리 파일 생성한다
item=상품
item.id=상품 ID
item.itemName=상품명
item.price=가격
item.quantity=수량
각 HTML 파일에서는 해당 데이터를 key 값으로 불러와 사용한다.
addForm.html: <label for="itemName" th:text="#{item.itemName}"></label>
editForm.html: <label for="itemName" th:text="#{item.itemName}"></label>
국제화
국제화는 서비스나 제품을 다양한 언와 문화에 맞게 적용하는 것을 의미한다. 각 나라별로 별도의 메시지 파일을 관리하여 서비스를 국제화 할 수 있다.
messages_en.properties (영어 버전):
item=Item
item.id=Item ID
item.itemName=Item Name
item.price=Price
item.quantity=Quantity
messages_ko.properties (한국어 버전):
item=상품
item.id=상품 ID
item.itemName=상품명
item.price=가격
item.quantity=수량
사용자 언어 인식
한국에서 접근한 것인지, 영어권에서 접근한 것인지 인식하는 방법은 HTTP accept-language 헤더 값을 사용하거나 사용자가 직접 언어를 선택하게 할 수 있다. 선택한 언어 정보는 쿠키 등의 방법으로 저장되어 사용된다.
프레임워크 지원
스프링은 메시지 및 국제화 기능을 기본적으로 제공한다. 추가적으로 뷰 템플릿 타임리프도 스프링이 제공하는 메시지 및 국제화 기능을 통합하여 제공한다.
스프링 메시지 소스 설정
스프링은 메시지 관리 기능을 통해 다국어 처리 및 메시지를 중앙에서 관리할 수 있게 해준다. 이를 위해 "MessageSource" 인터페이스와 그 구현체인 "ResourceBundleMessageSource"를 제공한다.
스프링 MessageSource 스프링 빈 등록
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages", "errors");
messageSource.setDefaultEncoding("utf-8");
return messageSource;
}
setBasenames : 메시지 소스 파일의 기본 이름을 설정한다. 예를 들어 "message"로 설정하면, "message.propertice" 파일을 읽게 된다.
이를 통해 "message_en.properties, message_ko.properties" 와 같이 국제화 기능을 적용할 수 있다.
스프링 부트 MessageSource 스프링 빈 등록
스프링 부트를 사용할 경우 "MessageSource" 가 자동으로 빈으로 등록된다. 따라서 별도의 설정이 필요 없이 "application.properties" 파일에서 속성만 설정하면 된다.
스프링 부트의 기본 설정값
spring.messages.basename=messages
즉, 별도의 설정 없이 "message.properties", "message_en.properties" 등의 파일을 만들면 스프링 부트가 자동으로 인식한다.
스프링 메시지 소스 사용
스프링에서 제공하는 MessageSource 인터페이스는 애플리케이션에서 국제화(i18n) 및 로컬화(l10n) 기능을 지원하기 위한 메시지 소스를 관리한다. 이 인터페이스를 사용하면 다양한 언어로 지정된 메시지를 쉽게 가져올 수 있다.
MessageSource 인터페이스
public interface MessageSource {
String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
1. String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
- 지정된 code 로 메시지를 찾아서 반환한다.
- 만약 해당 코드로 메시지를 찾을수 없을 경우 'defaultMessage' 가 반환된다.
- 'args' 는 메시지 내부에서 사용될 파라미터로 배열로, 메시지에 포함된 플레이스홀더를 대체하는데 사용된다.
- 'locale' 은 특정 언어 및 지역 설정을 나타내며, 해당 로케일에 맞는 메시지를 가져온다.
2. String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
- 지정된 code 로 메시지를 찾아서 반환한다.
- 하지만 해당 코드로 메시지를 찾을 수 없을 경우 'NoSuchMessageException' 예외가 발생한다.
messages.properties 메시지 정의
hello=안녕
hello.name=안녕 {0}
다음과 같이 'MessageSource' 를 사용하여 메시지를 가져올 수 있다.
@Autowired
MessageSource ms;
@Test
void argumentMessage() {
String message = ms.getMessage("hello.name", new Object[]{"Spring"}, null);
assertThat(message).isEqualTo("안녕 Spring");
}
국제화 파일 선택
locale 정보 기반으로 국제화 파일을 선택한다.
- Locale이 en_US의 경우 message_en_US -> message_en -> message 순서로 찾는다.
- Locale에 맞추어 구체적인 것이 있으면 구체적인 것을 찾고, 없으면 dafault 값으로 찾는다.
웹 애플리케이션 메시지,국제화 적용
타임리프 메시지 적용
타임리프의 메시지 표현식 #{} 를 사용하여, 스프링 메시지를 조회할 수 있다. 예를 들어 'label.item' 메시지를 조회하려면 #{label.item} 을 사용한다.
렌더링 전
<div th:text="#{label.item}"></div>
렌더링 후
//Locale.KR
<div>상품</div>
//Locale.ENGLISH
<div>Item</div>
타임리프 템플릿 메시지 적용
<h2 th:text="#{page.addItem}">상품 등록</h2>
...
<label for="itemName" th:text="#{label.item.itemName}">상품명</label>
...
스프링의 국제화 메시지 선택
웹 브라우저의 언어 설정 값을 변경하면 요청시 Accept-Language 의 값이 변경된다.
스프링은 Loacle 정보를 Accpet - Longuage 헤더 기반으로 언어를 선택한다.
LocaleResolver
스프링은 LocaleResolver 인터페이스를 통해 언어 선택 방법을 제공한다. 스프링 부트는 기본적으로 AcceptHeaderLocaleResolver 를 사용하여 'Accept - Language' 헤더 값을 활용 한다.
LocaleResolver 인터페이스
public interface LocaleResolver {
Locale resolveLocale(HttpServletRequest request);
void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale);
}
LocaleResolver 변경
구현을 변경하면 언어 선택 방법도 변경할 수 있다. 예를 들어, 쿠키나 세션 기반의 언어 선택 방법을 사용할 수 있다. 또한 사용자가 직접 언어를 선택할 수 있게 하는 방법도 구현할 수 있다.
결론적으로 스프링에서 국제화를 구현하기 위해서는 메시지 소스의 설정, 웹 브라우저의 언어 설정 변경 'LocaleResolver' 의 활용 및 변경 등의 방법이 있으며, 원하는 방법을 통해 국제화를 적용은 물론, 적절한 메시지와 리소스를 제공할 수 있다.
출처 : 인프런 - 🔗 스프링 MVC 2 - 백엔드 개발 활용 기술 by 우아한형제 김영한님