3. 스프링 메시지 소스 사용
기본으로 제공되는 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 인터페이스를 보면 코드를 포함한 일부 파라미터로 메시지를 읽어오는 기능을 제공한다.
스프링이 제공하는 메시지 소스를 어떻게 사용하는지 테스트 코드를 통해서 학습할 예정
그 전에, properties 파일에 한글이 계속 깨졌다.
이거 해결 방법
1.
test/java/hello/itemservice/message.MessageSourceTest.java
@SpringBootTest
public class MessageSourceTest {
@Autowired
MessageSource ms;
@Test
void helloMessage() {
String result = ms.getMessage("hello", null, null);
assertThat(result).isEqualTo("안녕");
}
}
화면으로 보면
1) "hello"
: 가져올 메시지의 키. 여기서는 "hello"라는 키를 사용하여 "안녕" 메시지를 가져온다.
2) null
: MessageSourceResolvable 배열로서, 메시지의 파라미터를 전달할 때 사용된다.
여기서는 파라미터를 사용하지 않으므로 null로 전달한다.
3) null
: Locale 객체로서, 특정 언어 또는 로컬라이제이션 설정을 지정할 때 사용된다.
여기서는 null로 전달하여 기본 로케일을 사용한다.
2.
MessageSourceTest 추가 - 메시지가 없는 경우, 기본 메시지
@SpringBootTest
public class MessageSourceTest {
@Autowired
MessageSource ms;
@Test
void helloMessage() {
String result = ms.getMessage("hello", null, null);
assertThat(result).isEqualTo("안녕");
}
// 추가
@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 )를 사용하면 기본 메시지가 반환된다.
화면으로 보면
이 두 테스트는 예외 처리와 기본 메시지 반환 동작이 정확하게 동작하는지 확인하는 데 사용된다.
- 첫 번째 테스트는 예외를 발생시키는지,
- 두 번째 테스트는 기본 메시지를 반환하는지 확인한다.
이러한 테스트는 MessageSource를 사용하는 애플리케이션에서
메시지 처리 동작을 확실히 확인할 수 있도록 도와준다.
3.
MessageSourceTest 추가 - 매개변수 사용
@SpringBootTest
public class MessageSourceTest {
@Autowired
MessageSource ms;
@Test
void helloMessage() {
String result = ms.getMessage("hello", null, null);
assertThat(result).isEqualTo("안녕");
}
@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("기본 메시지");
}
// 추가
@Test
void argumentMessage() {
String result = ms.getMessage("hello.name", new Object[]{"Spring"}, null);
assertThat(result).isEqualTo("안녕 Spring");
}
}
다시 화면으로 보면
국제화 파일 선택
: locale 정보를 기반으로 국제화 파일을 선택한다.
- Locale이 en_US 의 경우 messages_en_US => messages_en => messages 순서로 찾는다.
- Locale 에 맞추어 구체적인 것이 있으면 구체적인 것을 찾고, 없으면 디폴트를 찾는다고 이해하면 된다.
1) MessageSourceTest 추가 - 국제화 파일 선택 1
@SpringBootTest
public class MessageSourceTest {
@Autowired
MessageSource ms;
@Test
void helloMessage() {
String result = ms.getMessage("hello", null, null);
assertThat(result).isEqualTo("안녕");
}
@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("기본 메시지");
}
@Test
void argumentMessage() {
String result = ms.getMessage("hello.name", new Object[]{"Spring"}, null);
assertThat(result).isEqualTo("안녕 Spring");
}
// 추가
@Test
void defaultLang() {
assertThat(ms.getMessage("hello", null, null)).isEqualTo("안녕");
assertThat(ms.getMessage("hello", null, Locale.KOREA)).isEqualTo("안녕");
}
}
화면으로 보면
- 첫 번째 테스트에서 기본 로케일은 시스템 또는 Spring 설정에서 정의한 로케일을 사용하게 된다. 따라서 "안녕"이 예상 결과이다.
- 두 번째 테스트에서는 Locale.KOREA는 한국어 로케일을 나타내므로, "hello" 메시지는 여전히 "안녕"이어야 한다.
2) MessageSourceTest 추가 - 국제화 파일 선택 2
@SpringBootTest
public class MessageSourceTest {
@Autowired
MessageSource ms;
@Test
void helloMessage() {
String result = ms.getMessage("hello", null, null);
assertThat(result).isEqualTo("안녕");
}
@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("기본 메시지");
}
@Test
void argumentMessage() {
String result = ms.getMessage("hello.name", new Object[]{"Spring"}, null);
assertThat(result).isEqualTo("안녕 Spring");
}
// 추가
@Test
void defaultLang() {
assertThat(ms.getMessage("hello", null, null)).isEqualTo("안녕");
assertThat(ms.getMessage("hello", null, Locale.KOREA)).isEqualTo("안녕");
}
// 2 추가
@Test
void enLang() {
assertThat(ms.getMessage("hello", null, Locale.ENGLISH)).isEqualTo("hello");
}
}
화면으로 보면
- locale 정보가 Locale.ENGLISH 이므로 messages_en 을 찾아서 사용
이거 참고!
message.properties 질문 드립니다. - 인프런 | 질문 & 답변
안녕하세요.항상 좋은 강의 감사드립니다.다름아니라 국제화에 대해서 궁금한게 있는데,제가 m1 맥북에어를 사용중이고 시스템 언어를 영어로 사용중입니다.그런 상태에서 messages.properties에는
www.inflearn.com