Spring 메세지 국제화

바그다드·2023년 5월 6일
0
  • 웹은 기본적으로 전세계 어느 사람이나 접근할 수 있다. 하지만 웹에 표현되어 있는 언어는 각 나라별로 달라지는데, 웹에서 사용되는 문자열 값들을 변경하려면 일일이 찾아서 고쳐줘야 한다.
  • 만약에 웹을 표현하는 문구가 '바그다드'였는데, 이게 마음에 들지 않아 'qkrmekm'라고 고쳐야 한다면, '바그다드'라는 단어가 들어가 있는 부분을 일일이 찾아 고쳐워댜 하는 번거로움이 있다.
  • 이럴 때 스프링에서는 properties파일을 활용하면 국제화 등의 문제를 해결할 수 있다!!!
    그런데 나는 프로젝트 때문에 properties를 활용해본 적이 있는데, 그 때는 db관련 정보나, api와 관련된 민감한 정보들을 감추기 위해서 사용을 했다. 어쨌든 properties를 활용해 국제화하는 방법을 먼저 알아보자.

message_en.properties

item=Item
item.id=Item ID
item.itemName=Item Name
item.price=price
item.quantity=quantity

message_ko.properties

item=상품
item.id=상품 ID
item.itemName=상품명
item.price=가격
item.quantity=수량
  • 이런식으로 각 언어별로 properties파일을 생성해서 http헤더의 accept-language값을 활용하거나, 언어를 선택할 수 있도록 설정해두면 웹 사이트를 국제화시킬 수 있게 된다.
    그럼 실제로 properties파일을 이용해 메세지 국제화를 해보자

messages.properties

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

messages_en.properties

hello=hello
hello.name=hello {0}
  • 그리고 application.properties에 다음 코드를 추가해주자
spring.messages.basename=messages
  • 원래는 메세지 관리 기능을 이용하기 위해서는 MessageSource라는 빈을 이용해야 하는데, MessageSource를 따로 빈으로 등록하지 않고, 별도의 설정이 없다면 messages라는 이름으로 빈이 자동으로 등록이 된다. 따라서 messages_en.properties, messages_ko.properties, messages.properties 파일을 등록하면 자동으로 인식된다!!!
    - MessageSource는 인터페이스이므로 빈으로 등록하려면 ResourceBundleMessageSource라는 구현체를 빈으로 등록하면 된다. 아래 코드는 빈으로 등록할 때의 예시 코드이다. 참고만 하자.
      @Bean
      public MessageSource messageSource() {
      ResourceBundleMessageSource messageSource = new
      ResourceBundleMessageSource();
      messageSource.setBasenames("messages", "errors");
      messageSource.setDefaultEncoding("utf-8");
      return messageSource;
      }
  • 위에서 application.properties에 basenames의 값으로 messages를 부여했기 때문에 messages.properties를 읽어서 사용한다.
    이제 테스트를 해보자

Test코드 작성

@SpringBootTest
public class MessageSourceTest {

    @Autowired
    MessageSource ms;

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

    // 국제화 - 영어
    @Test
    void enLang() {
    	// 매개변수 X
        assertThat(ms.getMessage("hello", null, Locale.ENGLISH)).isEqualTo("hello");
        // 매개변수 O
        assertThat(ms.getMessage("hello.name", new Object[]{"Spring"}, Locale.ENGLISH)).isEqualTo("hello Spring");
    }
}
  • ms.getMessage("변수이름","매개변수", Locale)메서드를 이용하여 값을 가져올 수 있다.
  • defaultLang()메서드를 보면 Locale을 Locale.KOREA로 설정하여 스프링에서 messages_ko를 찾지만 존재하지 않으므로 기본 값인 messages를 사용한다.

메세지 적용하기

  • 그럼 이제 메세지를 웹 어플리케이션에 등록해보자
    먼저 메세지를 생성해주자(messages.properties에 추가)
label.item.id=상품 ID
label.item.itemName=상품명
label.item.price=가격
label.item.quantity=수량
  • 이제 메세지를 적용해보자
            <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>
  • #{key값} 이런식으로 메세지를 타임리프에서 가져올 수 있다.

파라미터 사용하기

properties

hello.name=안녕 {0}

html

<p th:text="#{hello.name(${item.itemName})}"></p>
  • ${item.itemName}의 값이 Spring 이라면 웹 페이지에는 '안녕 Spring'이라는 메세지가 뜰 것이다.
  • 이제 마지막으로 국제화 기능을 추가해보자!!

국제화 기능 적용

  • 이제 국제화 기능을 적용하기 위해 messages_en.properties에 아래의 값을 추가해주자
label.item=Item
label.item.id=Item ID
label.item.itemName=Item Name
label.item.price=price
label.item.quantity=quantity

이러면 설정은 다 완료 되었다. 이제 확인을 해보자

  • 크롬 브라우저-설정-언어-영어(가장 위로 이동)
  • 언어가 영어일 때
  • 언어가 한국어 일때

  • 기본 언어 설정 정보에 따라 http 헤더의 Accept-Language값 내의 우선순위가 바뀌기 때문에 이 값에 따라 제공되는 언어가 달라지게 된다!!!
  • 스프링은 Locale 선택 방식을 변경할 수 있도록 LocaleResolver 라는 인터페이스를 제공하는데, 스프링 부트는 기본으로 Accept-Language 를 활용하는 AcceptHeaderLocaleResolver 를 사용한다.
    만약 변경하고 싶다면 LocaleResolver를 검색하자!!!
    - 쿠키나 세션 기반의 Locale 선택 기능도 사용 가능하다.
profile
꾸준히 하자!

0개의 댓글