메시지와 국제화

gwjeon·2021년 11월 19일
1


학습참조
인프런-스프링 MVC 2편 백엔드 웹 개발 활용 기술(김영한님)


✅ 메시지 기능이란?

예를 들어 3개의 HTML 파일을 가지는 웹페이지가 있다고 가정해보자. 각자의 HTML 파일의 Header 부분에는 '어서오세요.'라는 문자가 들어가 있다. 이후 고객의 요구로 인하여 이 '어서오세요.'라는 문자를 '반갑습니다.' 로 변경해야 한다면 HTML 3개의 파일의 Header 부분을 모두 수정해주어야 한다. 현재 웹페이지에는 3개의 HTML 파일만 있으니 손쉽게 수정할 수 있겠지만, 만약 이 웹페이지가 수백개의 HTML 파일을 가지고 있다면 개발자는 수백개의 HTML 파일을 일일이 다 클릭하여 Header를 수정해야 할 것이다. 이와 같은 문제를 손쉽게 해결하기 위하여 Spring에서는 메시지 기능을 제공한다.


✅ 메시지 기능 사용하기

✔ messages.properties 파일

메시지를 공통으로 등록하여 사용하기 위해서는 messages.properties 파일을 생성하여야 한다. 기본 경로는 resource 아래에 생성하자.

디렉토리 구조

해당 경로에 파일을 생성한다음 사용할 message를 선언해주어야 한다.

page.header = 어서오세요.
page.headerParam = 어서오세요. {0}

를 가지는 messages.properties 파일을 생성 하였다. 이후에 이 page.header, page.headerParam를 가지고 메시지 기능을 사용할 것이다. page.headerParam = 어서오세요. {0}와 같이 {0}부분을 파라미터로도 사용할 수 있다.

✔ application.properties에 속성 지정

spring.messages.basename=messages 라는 속성을 등록한다. messages라는 이름을 가지는 properties 파일을 default로 사용하겠다는 의미이다. 하지만 이 속성을 등록하지 않아도 동작한다. Spring Boot를 사용한다면 자동으로 등록을 해준다. 이외에도 messages 관련 속성들이 있는데 그것은 Spring 매뉴얼을 참고하자.

✔ MessageSource를 Bean으로 등록하자.

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

기본적으로 Spring의 메시지 기능을 활용하기 위해선 MessageSource 인터페이스를 타입으로 가지는 Bean을 생성해야 한다. 하지만 우리는 이것을 할 필요가 없다. 이 역시 Spring Boot를 사용하면 부트가 다 알아서 빈으로 등록하고 설정을 해준다.

✔ Spring에서 MessageSource 사용하기

앞서 Spring Boot가 자동으로 MessageSource를 Bean으로 등록해 준다고 했다. 그렇다면 등록된 MessageSource를 이용해보자.

@Autowired
MessageSource ms; //(1)

void helloMessage() {
    String result1 = ms.getMessage("page.header", null, null); //(2)
    String result2 = ms.getMessage("page.headerParam", new Object[]{"Jay Park."}, null); //(2)
    System.out.println("result1 = " + result1); //(3)
    System.out.println("result2 = " + result2); //(3)
}
  • (1): MessageSource를 필드주입 받는다.
  • (2): argument가 총 3개인데, 첫번째는 messages.properties에 등록된 key값, 두번째는 key value에 parameter를 사용하면 그에 대입될 argument값으로 타입은 배열타입으로 선언한다. 세번째는 Locale 값이다. Locale은 국제화에 필요한부분으로 추후에 설명한다. 여기서는 값이 null이면 default로 지정된 messages.properties를 사용한다.
  • (3): result1 = 어서오세요. , result2 = 어서오세요. Jay Park.가 출력된다.

✔ 타임리프에서 사용하기

사실 메시지 기능은 서버단 보다는 화면단에서 주로 사용한다고 한다. 타임리프에서는 이 메시지 기능을 편리하게 사용할 수 있도록 제공한다.

<h2 th:text="#{page.header}">Header</h2> <!-- (1) -->
<h2 th:text="#{page.header('Jay Park.')}">Header.Param</h2> <!-- (2) -->

간단하게 #키워드를 사용하여 구현할 수 있다.

  • (1): 어서오세요.로 치환.
  • (2): 어서오세요. Jay Park.로 치환.

여기까지 학습이 되었다면 어서오세요. header 문자를 가지는 HTML 파일이 수십개든 수백개든 수천개든 messages.properties 파일의 page.header만 변경해준다면 매우 간단하게 문자를 변경할 수 있다.


✅ 국제화

국제화란 메시지 기능에서 한발 더 나아가 접속되는 브라우저 언어 환경에 따라 다른 메시지를 보여준다. 즉 접속하는 브라우저의 언어가 영어(en)라면 미리 만들어놓은 영어 메시지를 보여주고, 한글(ko)이라면 미리 만들어놓은 한글 메시지를 보여준다.

✔ 국제화 적용, messages_en.properties 파일 생성

영어로 메시지를 사용하기 위하여 messages_en.properties 파일을 생성하자.

page.header = hello.
page.headerParam = hello. {0}

이후 브라우저의 언어 옵션을 영어로 변경후 접속해보자. 크롬의 경우 설정 > 고급 > 언어 > 영어 속성을 가장 위로 이동시키면 언어 옵션이 변경된다.

한국어로 지정시 HTTP Header accept-language

영어로 지정 HTTP Header accept-language

이렇게 해당 옵션을 변경해주게 되면 해당 페이지로 요청시 HTTP Header에 accept-language의 값으로 en이 최우선 순위로 넘어오게 된다. Spring은 이 accept-language를 확인하여 Locale을 지정한다. 이후 Spring에서 지정한 이 Locale를 확인하여 메시지를 사용할 properties 파일을 선택하게 된다.
물론 Spring Boot가 spring.messages.basename=messages 와 같이 default 속성을 messages로 지정하기 때문에 1순위가 ko일때는 messages_ko.properties가 없으므로 messages.properties가 선택된다. 1순위가 en일 경우 messages_en.properties가 선택될 것이다.

✔ LocaleResolver

단순히 브라우저의 언어에 따른 HTTP Header accept-language를 기준으로 Locale가 지정되는 것이 아닌 쿠키나 세션을 통해서도 Locale를 지정할 수 있다. 글로벌한 웹페이지를 접속해보면 각 지역에 맞게 언어를 선택하는 것을 볼수있는데, 이와 같은 경우라고 할수 있다.

IKEA 웹페이지

Spring은 이 Locale를 방식을 변경할 수 있도록 LocaleResolver 인터페이스를 제공하는데, Spring Boot는 기본적으로 accept-language를 활용하는 AcceptHeaderLocaleResolver를 default로 사용한다. 만약 accept-language를 활용하지 않고, 쿠키나 세션등을 활용하여 Locale를 변경하려면 LocaleResolver의 구현체를 변경하면 된다.

profile
ansuzh

0개의 댓글