이전 프로젝트에 이어서 메시지, 국제화 기능을 학습해보자👍🏻
스프링 통합과 폼에서 개발한 상품 관리 프로젝트를 일부 수정해서 message-start 라는 프로젝트를 사용할 것이다
참고로 메시지, 국제화 예제에 집중하기 위해서 복잡한 체크, 셀렉트 박스 관리 기능은 제거했다😊
악덕기획자😏 : 님들. '상품명' 이라는 단어 그냥 싹 다 '상품이름'으로 바꾸셈
나🤬 : 저..ㅅ.. 말이 쉽지,,ㅋ,,,하드코딩 해놔서 하나하나 다 고쳐야한다고,,,
우리의 스프링😇 : 여러분 걱정마세요^^ 다양한 메시지를 한 곳에서 관리하도록 해주는 "메시지 기능"이라고 있답니다^^
예) 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.properteis
을 각 나라별로 별도로 관리하면 서비스를 국제화 할 수 있다!
예를 들어서 ⬇️아래와 같이⬇️ 2개의 파일을 만들어서 분류할 수 있다!
✔️ messages_en.propertis
item=Item
item.id=Item ID
item.itemName=Item Name
item.price=price
item.quantity=quantity
✔️ messages_ko.propertis
item=상품
item.id=상품 ID
item.itemName=상품명
item.price=가격
item.quantity=수량
messages_en.propertis
를 사용하고,messages_ko.propertis
를 사용하게 개발하면 된다.메시지와 국제화 기능을 직접 구현할 수도 있겠지만, 스프링은 기본적인 메시지와 국제화 기능을 모두 제공한다👍🏻
그리고 타임리프도 스프링이 제공하는 메시지와 국제화 기능을 편리하게 통합해서 제공한다👍🏻
스프링은 기본적인 메시지 관리 기능을 제공한다!
메시지 관리 기능을 사용하려면 스프링이 제공하는 MessageSource
를 스프링 빈으로 등록하면 되는데,
MessageSource
는 인터페이스이다!
➡️ 따라서 구현체인 ResourceBundleMessageSource
를 스프링 빈으로 등록하면 된다.
📌
application.properties
설정 변경
spring.messages.basename=messages,config.i18n.messages
1️⃣ /resources/messages.properties
hello=안녕
hello.name=안녕 {0}
1️⃣ /resources/messages_en.properties
hello=hello
hello.name=hello {0}
📌 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;
⬆️ 이처럼 MessgaeSource
인터페이스를 보면 코드를 포함한 일부 파라미터로 메시지를 읽어오는 기능을 제공한다!!
스프링이 제공하는 메시지 소스를 어떻게 사용하는지 ❗️테스트 코드를 통해 학습❗️해보자
✔️ test/java/hello/itemservice/message.MessageSourceTest.java
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 org.springframework.context.NoSuchMessageException;
import java.util.Locale;
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("안녕");
}
// MessageSourceTest 추가 - 메시지가 없는 경우, 기본 메시지
@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("기본 메시지");
}
// 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=취소
✔️ 타임리프 메시지 적용
#{...}
를 사용하면 스프링의 메시지를 편리하게 조회할 수 있다.#{label.item}
이라고 하면 된다!아래의 타임리프 템플릿 파일들에 메시지를 적용해보자!
➡️ addForm.html
➡️ editForm.html
➡️ item.html
➡️ items.html
✔️ 실행
잘 동작하는지 확인하기 위해 messages.properties
파일의 내용을 가격 ➡️ 금액 으로 변경해서 확인했을 때 잘 동작하는 것을 확인👍🏻
이번에는 웹 애플리케이션에 국제화를 적용(영어 메시지)를 추가하자!
✔️ messages_en.properties
label.item=Item
label.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
놀랍게도 이것으로 국제화 작업은 거의 끝났다😮
앞에서 템플릿 파일에는 모두 #{...}
를 통해서 메시지를 사용하도록 적용해두었기 때문이다!
메시지,,국제화,, 쓸만하군요,,,,^^