Spring MVC - 다국어 지원

2010. 9. 5. 11:11plming/Java - Spring

다국어를 지원하기 위해서 모든 인코딩을 EUC-KR에서 UTF-8로 변경

 web.xml

 <filter>
     <filter-name>Encoding Filter</filter-name>
     <filter-class>net.javajigi.filter.EncodingFilter</filter-class>
     <init-param>
         <param-name>encoding</param-name>
         <param-value>UTF-8</param-value>
     </init-param>
 </filter>


모든 메시지와 이미지 등의 정보를 MessageSource 파일에서 관리함으로써 다국어 지원이 가능하다.

 action-servlet.xml

 <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
     <property name="basename" value="Messages" />
 </bean>


다른 언어를 추가적으로 서비스할 필요가 발생하면, 같은 키 값을 가지는 MessageSource 파일을 하나 추가하기만 하면된다.

  관리의 편의성을 위하여 MessageSource를 Properties 파일이 아닌 데이터베이스에서 관리하는 경우도 많다.  하지만, JDK에서 제공하는 java.util.ResourceBundle을 이용할 수 없기 때문에 별도의 구현 클래스를 생성해야 하는 단점이 있다.

  java.util.Bundle의 단점은 Properties 파일의 메시지를 초기화 후 캐싱(Caching)을 하고 있기 때문에 메시지가 변경되더라도 애플리케이션을 재시작하기 전까지는 반영이 되지 않는다.  이를 해결하기 위해 ReloadableResourceBundleMessageSource 클래스를 지원한다.

Spring MVC는 접근하는 클라이언트의 Locale 정보를 기준으로 각 언어에 해당하는 MessageSource를 찾는다.  해당 언어에 대한 파일이 없을 경우에는 디폴트로 사용한 Messages.properties 파일에 있는 메시지가 서비스된다.

- Messages.properties : 애플리케이션의 디폴트 언어를 위한 메시지 및 이미지 파일 정보
- Messages_ko.properties : 한글을 위한 메시지 및 이미지 파일 정보
- Messages_en.properties : 영어을 위한 메시지 및 이미지 파일 정보
- Messages_zh.properties : 중국어을 위한 메시지 및 이미지 파일 정보

테스트 하기 위해 Locale 정보/언어를 브라우저에서 변경하면 된다.  IE의 경우, [도구]-[인터넷옵션]의 [일반]탭에서 [언어]를 선택하여 언어 설정을 바꿔주면 된다.  "한국어[ko]"가 제일 위에 올라와 있다. "영어[en]"를 추가하고, 제일 위로 위치하도록 설정하고 브라우저를 새로 시작하면 영어 메시지를 테스트 할 수 있다.




 index.jsp

 <%@page contentType="text/html; charset=utf-8"%>
 <%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>

 <html>
 <head>
 <title><fmt:message key="index.title"/></title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 </head>
 <body>

 <div id="welcome">
 <h1><fmt:message key="index.welcome.title"/></h1>

 <fmt:message key="index.welcome.body"/>
 </div>

 </body>
 </html>


JSP 파일에서 메시지를 출력하기 위해 JSTL의 <fmt /> 커스텀 태그를 이용할 수 있다.


Spring MVC는 다국어를 지원하기 위해 여러 종류의 LocalResolver를 가지고 있다.  빈 설정파일에서 정의하지 않을 경우, 디폴트로 AcceptHeaderLocaleResolver가 이용된다. 이외에도 FixedLocaleResolver와 브라우저의 Locale에 따라 해당 언어 서비스를 하는 것이 아닌, 원하는 언어를 선택/서비스할 수 있는 CookieLocaleResolver와 SessionLocaleResolver가 있다.

 import java.util.Locale;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
 import org.springframework.web.bind.RequestUtils;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.i18n.SessionLocaleResolver;
 import org.springframework.web.servlet.mvc.Controller;
 
 public class SessionLocaleController implements Controller {
     public static final int KOREA_LOCALE = 1;
     public static final int ENGLISH_LOCALE = 2;
 
     public ModelAndView handleRequest(HttpServletRequest request,
             HttpServletResponse response) throws Exception {
         int localeMode = RequestUtils.getIntParameter(request, "locale", 1);
 
         Locale locale = null;
         if( localeMode == KOREA_LOCALE ){
             locale = Locale.KOREAN;
         } else if( localeMode == ENGLISH_LOCALE ) {
             locale = Locale.ENGLISH;
         } else {
             locale = Locale.KOREAN;
         }
 
         HttpSession session = request.getSession();
         session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale);
 
         return new ModelAndView("/index");
     }
 }

 action-servlet.xml - SessionLocaleResolver 설정

 <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />

 <bean id="/changelocale.do" class="net.javajigi.common.web.SessionLocaleController" />

.../changelocale.do?local=1
.../changelocale.do?local=2

지원해야 하는 언어가 증가하는 부분과 개발이후 변경사항이 발생할 경우의 유지보수 비용의 증가도 줄이는 장점이 있으므로, 초기 빠른 개발 완료를 위해 똑같은 애플리케이션을 언어별로 복사해서 만드는 것보다는 LocaleResolver를 적용하는 것이 낫다.
또한, 다국어를 지원하면서 개발자들이 흔히 간과하는 부분은 이미지를 각 언어별로 관리해야 한다는 것이다.  애플리케이션을 구성하고 있는 이미지에도 글이 포함되어 있기 때문에 이미지의 경로 정보또한 MessageSource에서 관리해야 한다.


[출처] Spring 프레임워크 워크북