일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- XACT_STATE
- 앵커멤버
- SQL
- 요청매핑
- 홈스쿨링
- getChannel()
- 진경혜
- 스프링
- spring
- renameTo
- 프론트컨트롤러
- 함수
- MSSQL
- XWPF
- 배치
- transferTo
- java
- 재귀멤버
- ERROR_MESSAGE
- 교육법
- 자바
- 디스패처서블릿
- dm_exec_requests
- 요약
- 아이
- TRANCOUNT
- HWPF
- git
- SQLSTATE=42705
- 튜닝
- Today
- Total
필기노트
스프링 메시지, 국제화 본문
1. 메시지
악덕? 기획자가 화면에 보이는 문구가 마음에 들지 않는다고, 상품명이라는 단어를 모두 상품이름으로 고쳐달라고 하면 어떻게 해야할까?
여러 화면들을 다 찾아가면서 모두 변경해야 한다. 화면이 수십개 이상이라면 수십개의 파일을 모두 고쳐야 한다.
왜냐하면 해당 HTML 파일에 메시지가 하드코딩 되어 있기 때문이다.
이런 다양한 메시지를 한 곳에서 관리하도록 하는 기능을 메시지 기능이라 한다.
스프링 부트를 사용하면
스프링 부트가 MessageSource 를 자동으로 스프링 빈으로 등록하고,
메시지 소스는 messages 라는 이름으로 기본 등록된다.
따라서 messages_en.properties , messages_ko.properties , messages.properties 파일만 등록하면 자동으로 인식된다.
messages.properties(기본 값으로 사용, 한글)라는 메시지 관리용 파일을 만들고
hello=안녕
hello.name=안녕 {0}
2. 스프링 메시지 소스 사용
2-1) 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;
MessageSource 인터페이스를 보면 코드를 포함한 일부 파라미터로 메시지를 읽어오는 기능을 제공한다.
@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
- 가장 단순한 테스트는 메시지 코드로 hello 를 입력하고 나머지 값은 null 을 입력했다. locale 정보가 없으면 Locale.getDefault() 을 호출해서 시스템의 기본 로케일을 사용. 시스템의 기본 로케일이 없는 경우 basename 에서 설정한 messages.properties 파일에서 데이터를 조회한다.
2-2) 메시지가 없는 경우, 기본 메시지
@Test
void 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("기본 메시지");
}
- 메시지가 없는 경우에는 NoSuchMessageException 이 발생한다.
- 메시지가 없어도 기본 메시지( defaultMessage )를 사용하면 기본 메시지가 반환된다.
2-3) 매개변수 사용
@Test
void argumentMessage() {
String result = ms.getMessage("hello.name", new Object[]{"Spring"}, null);
assertThat(result).isEqualTo("안녕 Spring");
}
- 다음 메시지의 {0} 부분은 매개변수를 전달해서 치환할 수 있다.
- new Object[]{"Spring"} : hello.name=안녕 {0} -> Spring 단어를 매개변수로 전달 -> 안녕 Spring
3. 웹 애플리케이션에 메시지 적용하기
3-1) messages.properties
item=상품
item.id=상품 ID
item.itemName=상품명
item.price=가격
item.quantity=수량
3-2) 타임리프 메시지 적용
타임리프의 메시지 표현식 #{...} 를 사용하면 스프링의 메시지를 편리하게 조회할 수 있다.
각 HTML들은 다음과 같이 해당 데이터를 key 값으로 불러서 사용하는 것이다.
렌더링 전
<label for="itemName" th:text="#{item.itemName}">상품명</label>
렌더링 후
<label for="itemName">상품명</label>
3-3) 참고로 파라미터는 다음과 같이 사용할 수 있다.
hello.name=안녕 {0}
<p th:text="#{hello.name(${item.itemName})}"></p>
4. 국제화
메시지에서 설명한 메시지 파일( messages.properties )을 각 나라별로 별도로 관리하면 서비스를 국제화 할 수 있다.
국제화 테스트를 위해서 messages_en 파일도 추가하자.
hello=hello
hello.name=hello {0}
messages_en.properties : 영어 국제화 사용
5. 국제화 파일 선택
locale 정보를 기반으로 국제화 파일을 선택한다.
Locale이 en_US 의 경우 messages_en_US -> messages_en -> messages 순서로 찾는다.
Locale 에 맞추어 구체적인 것이 있으면 구체적인 것을 찾고, 없으면 디폴트를 찾는다고 이해하면 된다.
@Test
void defaultLang() {
assertThat(ms.getMessage("hello", null, null)).isEqualTo("안녕");
assertThat(ms.getMessage("hello", null, Locale.KOREA)).isEqualTo("안녕");
assertThat(ms.getMessage("hello", null, Locale.ENGLISH)).isEqualTo("hello");
}
- ms.getMessage("hello", null, null) : locale 정보가 없으므로 messages 를 사용
- ms.getMessage("hello", null, Locale.KOREA) : locale 정보가 있지만, message_ko 가 없으므로 messages 를 사용
- ms.getMessage("hello", null, Locale.ENGLISH) : locale 정보가 Locale.ENGLISH 이므로 messages_en 을 찾아서 사용
6. 한국에서 접근한 것인지 영어에서 접근한 것인지는 인식하는 방법
먼저 영어 메시지를 추가하자.
item=Item
item.id=Item ID
item.itemName=Item Name
item.price=price
item.quantity=quantity
사실 이것으로 국제화 작업은 거의 끝났다. 앞에서 템플릿 파일에는 모두 #{...} 를 통해서 메시지를 사용하도록 적용해두었기 때문이다.
6-1) HTTP accept-language 해더 값
한국에서 접근한 것인지 영어에서 접근한 것인지는 인식하는 방법은 HTTP accept-language 해더 값을 사용한다.
웹 브라우저의 언어 설정 값을 변경하면서 국제화 적용을 확인해보자.
크롬 브라우저 설정 언어를 검색하고, 우선 순위를 변경하면 된다.
우선순위를 영어로 변경하고 테스트해보자.
웹 브라우저의 언어 설정 값을 변경하면 요청시 Accept-Language 의 값이 변경된다.
Accept-Language 는 클라이언트가 서버에 기대하는 언어 정보를 담아서 요청하는 HTTP 요청 헤더이다.
6-2) 사용자가 직접 언어를 선택
고객이 직접 Locale 을 선택하도록 하는 쿠키나 세션 기반의 Locale 선택 기능 관련해서는 LocaleResolver 의 구현체를 검색하면 수 많은 예제가 나오니 필요한 분들은 참고하면 된다.
'김영한 강의 요약' 카테고리의 다른 글
김영한 스프링 강의 요약 - 로그인(세션, 쿠키) (0) | 2023.12.15 |
---|---|
김영한 스프링 강의 요약 - 검증(유효성 검사) (0) | 2023.11.23 |
타임리프 스프링 통합과 폼 (0) | 2023.11.03 |
타임리프 기본 기능 (0) | 2023.10.23 |
타임리프 간단히 알아보기 (0) | 2023.10.20 |