EP2. 메세지와 국제화
Web/MVC2

EP2. 메세지와 국제화

메시지

현재 HTML의 상품명, 가격, 수량 등 'label'에 있는 단어들을 하드코딩 되어있습니다.

만약에 '상품명'이라는 단어를 '상품이름'으로 바꾸려면 모든 HTML상의 단어들을 바꾸어주어야합니다.

 

이런 다양한 메시지들을 한 곳에서 관리할 수 있는 기능을 메시지 기능이라고 합니다.

 

messages.properties

item=상품
item.id=상품 ID
item.itemName=상품명
item.price=가격
item.quantity=수량

 

addForm.html

<label for="itemName" th:text="#{item.itemName}"></label>

 

 

국제화

사용자가 접근한 locale에 따라, 혹은 사용자의 선택에 따라 보이는 메세지의 언어도 다르게 설정할 수 있습니다.

이 기능을 국제화 기능이라고 합니다.

 

메세지에서 설명한 메시지파일(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=수량

 

 

 

스프링(부트)가 제공하는 메세지기능

 

 

스프링에서 메시지 관리 기능을 사용하려면 MessageSource를 스프링 빈으로 등록해야합니다.

@Bean
public MessageSource messageSource() {
  ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
  messageSource.setBasenames("messages", "errors");
  messageSource.setDefaultEncoding("utf-8");
  return messageSource;
}

하지만 스프링 부트를 사용하면 MessageSource를 자동으로 스프링 빈에 등록합니다.

 

 

메세지 소스 설정

 

application.properties

 

(기본 값이 spring.messages.basename=messages 이므로 안써준 것과 동일합니다.)

spring.messages.basename=messages

 

 

 

메시지 파일 생성

messages.properties

hello=안녕
hello.name=안녕 {0}

 

messages_en.properties

hello=hello
hello.name=hello {0}

 

 

사용해보기

 

1. MessageSource 주입받기

    @Autowired
    MessageSource ms;

 

 

 

2. 인스턴스의 getMessage 사용

3가지 매개변수를 입력합니다.

  1. code (치환할 이름)
  2. 매개변수 (code의 매개변수)
  3. locale (나라)

    @Test
    void argumentMessage() {
        String message = ms.getMessage("hello.name", new Object[]{"Spring"}, null);
        assertThat(message).isEqualTo("안녕 Spring");
    }

 

 

2-1. getMessage()에서 기본메세지 이용하기

 

code입력부분에 없는 code를 입력후 args 다음에 출력할 기본메세지를 넣어줍니다.

    @Test
    void notFoundMessageCodeDefaultMessage() {
        String result = ms.getMessage("no_code", null, "기본 메시지", null);
        assertThat(result).isEqualTo("기본 메시지");
    }

 

 

2-2. getMessage()에서 locale 사용

    @Test
    void defaultLang() {
        assertThat(ms.getMessage("hello", null, null)).isEqualTo("안녕");
        assertThat(ms.getMessage("hello", null, Locale.KOREA)).isEqualTo("안녕");
    }

    @Test
    void enLang() {
        assertThat(ms.getMessage("hello", null, Locale.ENGLISH)).isEqualTo("hello");
    }

 

 

 

 

웹 어플리케이션에 적용해보기

 

 

메세지 적용

messages.properties

사용할 메세지들을 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=취소

 

 

items.html

기존에 html에 하드코딩 했던 메세지들을 th:text="#{}" 를 이용해서 messages.properties에 설정해 둔 code들로 렌더링 할 수 있습니다.

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <link th:href="@{/css/bootstrap.min.css}"
            href="../css/bootstrap.min.css" rel="stylesheet">
</head>
<body>

<div class="container" style="max-width: 600px">
    <div class="py-5 text-center">
        <h2 th:text="#{page.items}">상품 목록</h2>
    </div>

    <div class="row">
        <div class="col">
            <button class="btn btn-primary float-end"
                    onclick="location.href='addForm.html'"
                    th:onclick="|location.href='@{/message/items/add}'|"
                    type="button" th:text="#{page.addItem}">상품 등록</button>
        </div>
    </div>

    <hr class="my-4">
    <div>
        <table class="table">
            <thead>
            <tr>
                <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>
            </tr>
            </thead>
            <tbody>
            <tr th:each="item : ${items}">
                <td><a href="item.html" th:href="@{/message/items/{itemId}(itemId=${item.id})}" th:text="${item.id}">회원id</a></td>
                <td><a href="item.html" th:href="@{|/message/items/${item.id}|}" th:text="${item.itemName}">상품명</a></td>
                <td th:text="${item.price}">10000</td>
                <td th:text="${item.quantity}">10</td>
            </tr>
            </tbody>
        </table>
    </div>

</div> <!-- /container -->

</body>
</html>

 

 

 

 

국제화 적용

국제화 적용은 아주 간단합니다.

국제화를 적용할 언어의 messages.properties를 추가만 해주시면 됩니다.

 

messages_en.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=취소

 

이제 locale은 스프링이 알아서 넣어줍니다.

 

 

Accept-Language 에서 맨 처음에 ko이 와서 한국어로 보여지고,

 

 

크롬 설정에서 영어를 제일 높은 우선순위로 설정하고 새로고침하면

 

 

 

Accept-Language가 en으로 가게 되면서 스프링에서 자동으로 국제화를 적용해줍니다.

 

 

 

LocaleResolver 변경

만약 Locale 방식을 바꾸고 싶은경우에는 (팝업창으로 언어선택 등) 제공되는 LocaleResolver 인터페이스를 이용하면 됩니다.

 

 

'Web > MVC2' 카테고리의 다른 글

EP4. 검증2 - Bean Validation  (0) 2021.10.14
EP3. 검증1 - Validation  (0) 2021.10.10
EP1. 타임리프 Thymeleaf  (0) 2021.07.26