빙응의 공부 블로그
[Spring]스프링 MVC 2편 - 메시지, 국제화 본문
📝메시지
만약 요구사항을 수정하는 중에 각 웹 페이지의 상품명이라는 단어를 모두 상품이름으로 고쳐야 한다면 어떻게 해야할까?
그러면 HTML 구현 기준으로 모두 고쳐야 한다.
이것을 HTML 하드 코딩이라고 한다.
하드 코드 예)
<div>
<label for="itemName">상품명</label>
<input type="text" id="itemName" th:field="*{itemName}" class="form-control" placeholder="이름을 입력하세요">
</div>
<div>
<label for="price">가격</label>
<input type="text" id="price" th:field="*{price}" class="form-control" placeholder="가격을 입력하세요">
</div>
<div>
<label for="quantity">수량</label>
<input type="text" id="quantity" th:field="*{quantity}" class="form-control" placeholder="수량을 입력하세요">
</div>
이것을 해결하는 방법이 메시지 일관 관리 기능이다.
messages.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.properties)을 각 나라별로 별도로 관리하면서 서비스를 국제화할 수 있다.
전에 포스팅에서 봤듯이 우리는 요청이 어느나라 언어로 오는지 알 수 있다.
바로 HTTP accept-language 헤더
이것을 이용해 헤더에 따라 언어를 다르게 해주면 된다.
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=수량
참고! 스프링은 기본적인 메시지와 국제화 기능은 모두 제공한다. 그리고 타임리프도 스프링이 제공하는 메시지와 국제화 기능을 편리하게 제공한다.
📝스프링 메시지 소스 설정
스프링은 기본적으로 메시지 관리 기능을 제공한다.
그러나 일단 직접 등록을 해보자
직접 등록
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = newResourceBundleMessageSource();
messageSource.setBasenames("messages", "errors");
messageSource.setDefaultEncoding("utf-8");
return messageSource;
}
이렇게 빈에 넣어서 직접 등록을 할 수 있다.
자동 사용
스프링 부트를 사용하면 스프링 부트가 MessageSource를 자동으로 스프링 빈에 등록한다.
또한 해당 스프링 부트 메시지 소스를 사용하려면 application.properties에 해당 구문을 추가해줘야 한다.
spring.messages.basename=messages,config.i18n.messages
해당 구문은 기본 이름을 messages로 하고 여러개의 파일을 쉼표로 구분한다는 뜻이다.
즉 messages_en.properties , messages_ko.properties , messages.properties 이런것이 포함된다.
📝메시지 소스 사용해보기
MessageSource를 사용하는 인터페이스는 다음과 같은 메소드를 가진다.
public interface MessageSource {
String getMessage(String code, @Nullable Object[] args, @Nullable StringdefaultMessage, Locale locale);
String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
이 메소드들은 코드를 포함한 일부 파라미터로 메시지를 읽어오는 기능을 제공한다.
실습
@SpringBootTest
public class MessagesSourceTest {
@Autowired
MessageSource messagesSource;
@Test
@DisplayName("메시지 국제화 테스트")
void MessagesTest(){
String result = messagesSource.getMessage("hello", null, null);
Assertions.assertThat(result).isEqualTo("hello");
}
@Test
@DisplayName("메시지 국제화 매개변수 테스트")
void MessagesTest2() {
String result = messagesSource.getMessage("hello.name", new Object[]{"John"}, Locale.getDefault());
Assertions.assertThat(result).isEqualTo("안녕 John");
}
}
해당 코드는 messages.properties와 messages_en.properties를 이용해서 테스트를 해보았다.
첫번째 테스트는 기본이 ko이기 때문에 틀리게 나온다. result는 안녕이 나오기 때문이다.
이제 HTML에 적용하는 법을 알아보자!
label.item=Item
label.item.id=Item ID
label.item.itemName=Item Name
label.item.price=price
label.item.quantity=quantity
해당 코드처럼 messages.properties에 지정했다고 해보자.
<th>ID</th>
<th>상품명</th>
<th>가격</th>
<th>수량</th>
이것을 바꾸면
<th th:text="#{label.item.id}">ID</th>
<th th:text="#{label.item.itemName}">상품명</th>
<th th:text="#{label.item.price}">가격</th>
<th th:text="#{label.item.quantity}">수량</th>
이렇게 된다.
잘된다!!!!!
📝스프링의 국제화 메시지 선택
그렇다면 스프링은 어떻게 국제화 메시지를 선택할 수 있는걸까?
그것은 Locale 선택 방식을 변경하는 LocaleResolver 라는 인터페이스에 있다!
LocaleResolver
public interface LocaleResolver {
Locale resolveLocale(HttpServletRequest request);
void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale);
}
만약 Locale 선택 방식을 변경하려면 LocaleResolver의 구현체를 변경해서 쿠키나 세션 기반으로 변경할 수 있다.
'Spring > 인프런_개념' 카테고리의 다른 글
[Spring]스프링 MVC 2편 - 쿠키와 보안 (1) | 2024.02.01 |
---|---|
[Spring]스프링 MVC - 검증(Validation) (0) | 2024.01.28 |
[Spring]스프링 MVC 1편 - 스프링 MVC 기본 기능(응답) (0) | 2024.01.15 |
[Spring]스프링 MVC 1편 - 스프링 MVC 기본 기능(요청) (1) | 2024.01.14 |
[Spring]스프링 MVC 1편 - 구조 이해2 (0) | 2024.01.12 |