[Spring]메시지와 국제화
Inflearn의 김영한님의 스프링 MVC 2편 -백엔드 웹 개발 활용 기술 강의를 참고하여 작성한 내용입니다.
👉메시지
만약 화면에 보이는 상품명, 가격, 수량 등, label에 있는 단어를 변경해야하는 상황이 생긴다면 HTML 파일에 메시지가 하드코딩 되어 있기 때문에 화면 수가 수십개 이상이라면 수십개의 파일을 모두 고쳐야 하는 상황이 생긴다. 이런 다양한 메시지를 한 곳에서 관리하도록 하는 기능을 메시지 기능이라고 한다.
messages.properties 라는 메시지 관리용 파일을 만든다.
item=상품
item.id=상품 ID
item.itemName=상품명
item.price=가격
item.quantity=수량
HTML에서 해당 데이터를 key 값으로 불러 사용한다.
<label for="itemName" th:text="#{item.itemName}"></label>
<label for="itemName" th:text="#{item.itemName}"></label>
👉국제화
메시지에서 설명한 메시지 파일(messages.properties)을 각 나라별로 별도로 관리하면 서비스를 국제화 할 수 있다.
messages_en.properties
item=Item
item.id=Item IDitem.itemName=Item Name
item.price=price
item.quantity=quantity
messages_ko.properties
item=상품
item.id=상품 ID
item.itemName=상품명
item.price=가격
item.quantity=수량
영어를 사용해야 하는 상황이면 messages_en.propeties를 사용하고, 한국어를 사용해야 하는 상황이면 messages_ko.properties를 사용하게 하면 된다.
한국에서 접근한 것인지 영어에서 접근한 것인지 인식하는 방법은 HTTP accept-language해더 값을 사용하거나 사용자가 직접 언어를 선택하도록 하고, 쿠키 등을 사용해 처리한다.
👉스프링 메시지 소스 설정
메시지 관리 기능을 사용하기 위해 스프링이 제공하는 MessageSource를 스프링 빈으로 등록하면 되는데, MessageSource는 인터페이스이기 때문에 구현체인 ResourceBundleMessageSource를 스프링 빈으로 등록하면 된다. 스프링 부트는 MessageSource를 자동으로 스프링 빈으로 등록한다.
직접 등록하는 법
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages", "errors");
messageSource.setDefaultEncoding("utf-8");
return messageSource;
}
스프링 부트 사용시 메시지 소스를 아래와 같이 설정 가능하다.
application.properties
spring.messages.basename=messages,config.i18n.messages
👉메시지 파일 생성
메시지 파일은 아래와 같이 생성 가능하다
/resources/messages.properties
hello=안녕
hello.name=안녕 {0}
👉스프링 메시지 소스 사용
MessageSource 인터페이스를 사용해 코드를 포함한 일부 파라미터로 메시지를 읽어오는 기능을 사용 가능하다.
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;
MessageSourceTest
package hello.itemservice.message;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.MessageSource;
import static org.assertj.core.api.Assertions.*;
@SpringBootTest
public class MessageSourceTest {
@Autowired
MessageSource ms;
@Test
void helloMessage() {
String result = ms.getMessage("hello", null, null);
assertThat(result).isEqualTo("안녕");
}
}
ms.getMessage("hello", null, null)
- code: hello
- args: null
- locale: null
locale 정보가 없으면 basename에서 설정한 기본 이름 메시지 파일을 조회한다. basename으로 messages를 지정해서 messages.properties파일에서 데이터를 조회한다.
MessageSourceTest - 메시지가 없는 경우, 기본 메시지
@Testvoid notFoundMessageCode() {
assertThatThrownBy(() -> ms.getMessage("no_code", null, null))
.isInstanceOf(NoSuchMessageException.class);
}
@Test
void notFoundMessageCodeDefaultMessage() {
String result = ms.getMessage("no_code", null, "기본 메시지", null);
assertThat(result).isEqualTo("기본 메시지");
}
MessageSourceTest - 매개변수 사용
@Test
void argumentMessage() {
String result = ms.getMessage("hello.name", new Object[]{"Spring"}, null);
assertThat(result).isEqualTo("안녕 Spring");
}
MessageSourceTest - 국제화 파일 선택1
@Test
void defaultLang() {
assertThat(ms.getMessage("hello", null, null)).isEqualTo("안녕");
assertThat(ms.getMessage("hello", null, Locale.KOREA)).isEqualTo("안녕");
}
MessageSourceTest - 국제화 파일 선택2
@Test
void enLang() {
assertThat(ms.getMessage("hello", null,
Locale.ENGLISH)).isEqualTo("hello");
}
👉웹 애플리케이션에 메시지 적용해보기
messages.properties
label.item=상품
label.item.id=상품 ID
label.item.itemName=상품명label.item.price=가격
label.item.quantity=수량
page.items=상품 목록
page.item=상품 상세
page.addItem=상품 등록
page.updateItem=상품 수정
button.save=저장
button.cancel=취소
타임리프로 메시지 적용
#{...}를 사용해 스프링의 메시지를 조회 가능하다.
ex) #{label.item}
페이지 이름에 적용
<h2>상품 등록 폼</h2>
<h2 th:text="#{page.addItem}">상품 등록</h2>
레이블에 적용
<label for="itemName">상품명</label>
<label for="itemName" th:text="#{label.item.itemName}">상품명</label>
<label for="price" th:text="#{label.item.price}">가격</label>
<label for="quantity" th:text="#{label.item.quantity}">수량</label>
버튼에 적용
<button type="submit">상품 등록</button>
<button type="submit" th:text="#{button.save}">저장</button>
<button type="button" th:text="#{button.cancel}">취소</button>
👉웹 애플리케이션에 국제화 적용해보기
messages_en.properties
label.item=Itemlabel.item.id=Item ID
label.item.itemName=Item Name
label.item.price=price
label.item.quantity=quantity
page.items=Item List
page.item=Item Detail
page.addItem=Item Add
page.updateItem=Item Update
button.save=Save
button.cancel=Cancel
위 파일만 만들어주면 국제화 작업은 거의 끝이다.
웹으로 확인하는 방법은 아래와 같다.
'Spring Boot' 카테고리의 다른 글
[Spring] Grafana와 Prometheus로 서버 모니터링 하기 (0) | 2023.07.07 |
---|---|
[Spring] Spring MVC의 구조 (0) | 2023.06.03 |
[Spring] Spring boot JPA사용해 로그인, 회원가입 구현 (0) | 2023.05.29 |
[Spring]@ModelAttribute 어노테이션의 기능과 사용법 (0) | 2023.05.23 |
[Spring]Spring Boot로 Hello World찍기 (0) | 2023.01.29 |
댓글