예를 들어 3개의 HTML 파일을 가지는 웹페이지가 있다고 가정해보자. 각자의 HTML 파일의 Header 부분에는 '어서오세요.'라는 문자가 들어가 있다. 이후 고객의 요구로 인하여 이 '어서오세요.'라는 문자를 '반갑습니다.' 로 변경해야 한다면 HTML 3개의 파일의 Header 부분을 모두 수정해주어야 한다. 현재 웹페이지에는 3개의 HTML 파일만 있으니 손쉽게 수정할 수 있겠지만, 만약 이 웹페이지가 수백개의 HTML 파일을 가지고 있다면 개발자는 수백개의 HTML 파일을 일일이 다 클릭하여 Header를 수정해야 할 것이다. 이와 같은 문제를 손쉽게 해결하기 위하여 Spring에서는 메시지 기능을 제공한다.
메시지를 공통으로 등록하여 사용하기 위해서는 messages.properties 파일을 생성하여야 한다. 기본 경로는 resource 아래에 생성하자.
해당 경로에 파일을 생성한다음 사용할 message를 선언해주어야 한다.
page.header = 어서오세요.
page.headerParam = 어서오세요. {0}
를 가지는 messages.properties 파일을 생성 하였다. 이후에 이 page.header, page.headerParam를 가지고 메시지 기능을 사용할 것이다. page.headerParam = 어서오세요. {0}
와 같이 {0}부분을 파라미터로도 사용할 수 있다.
spring.messages.basename=messages
라는 속성을 등록한다. messages라는 이름을 가지는 properties 파일을 default로 사용하겠다는 의미이다. 하지만 이 속성을 등록하지 않아도 동작한다. Spring Boot를 사용한다면 자동으로 등록을 해준다. 이외에도 messages 관련 속성들이 있는데 그것은 Spring 매뉴얼을 참고하자.
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages", "errors");
messageSource.setDefaultEncoding("utf-8");
return messageSource;
}
기본적으로 Spring의 메시지 기능을 활용하기 위해선 MessageSource 인터페이스를 타입으로 가지는 Bean을 생성해야 한다. 하지만 우리는 이것을 할 필요가 없다. 이 역시 Spring Boot를 사용하면 부트가 다 알아서 빈으로 등록하고 설정을 해준다.
앞서 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)
}
result1 = 어서오세요.
, result2 = 어서오세요. Jay Park.
가 출력된다.사실 메시지 기능은 서버단 보다는 화면단에서 주로 사용한다고 한다. 타임리프에서는 이 메시지 기능을 편리하게 사용할 수 있도록 제공한다.
<h2 th:text="#{page.header}">Header</h2> <!-- (1) -->
<h2 th:text="#{page.header('Jay Park.')}">Header.Param</h2> <!-- (2) -->
간단하게 #키워드를 사용하여 구현할 수 있다.
어서오세요.
로 치환.어서오세요. Jay Park.
로 치환.여기까지 학습이 되었다면 어서오세요.
header 문자를 가지는 HTML 파일이 수십개든 수백개든 수천개든 messages.properties 파일의 page.header만 변경해준다면 매우 간단하게 문자를 변경할 수 있다.
국제화란 메시지 기능에서 한발 더 나아가 접속되는 브라우저 언어 환경에 따라 다른 메시지를 보여준다. 즉 접속하는 브라우저의 언어가 영어(en)라면 미리 만들어놓은 영어 메시지를 보여주고, 한글(ko)이라면 미리 만들어놓은 한글 메시지를 보여준다.
영어로 메시지를 사용하기 위하여 messages_en.properties 파일을 생성하자.
page.header = hello.
page.headerParam = hello. {0}
이후 브라우저의 언어 옵션을 영어로 변경후 접속해보자. 크롬의 경우 설정 > 고급 > 언어 > 영어 속성을 가장 위로 이동시키면 언어 옵션이 변경된다.
이렇게 해당 옵션을 변경해주게 되면 해당 페이지로 요청시 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가 선택될 것이다.
단순히 브라우저의 언어에 따른 HTTP Header accept-language를 기준으로 Locale가 지정되는 것이 아닌 쿠키나 세션을 통해서도 Locale를 지정할 수 있다. 글로벌한 웹페이지를 접속해보면 각 지역에 맞게 언어를 선택하는 것을 볼수있는데, 이와 같은 경우라고 할수 있다.
Spring은 이 Locale를 방식을 변경할 수 있도록 LocaleResolver 인터페이스를 제공하는데, Spring Boot는 기본적으로 accept-language를 활용하는 AcceptHeaderLocaleResolver를 default로 사용한다. 만약 accept-language를 활용하지 않고, 쿠키나 세션등을 활용하여 Locale를 변경하려면 LocaleResolver의 구현체를 변경하면 된다.