Spring에서 다국어 적용하기
스프링에서 다국어처리는 의외로 간단하다, 특히 사용자가 언어를 자유롭게 설정하는 부분도 쉽게 가능하다. 아래와 같이 화면처리를 하고자 한다.
브라우저의 설정된 언어값을 읽어오거나, 아니면 디폴트 언어설정을 지정하거나, 링크를 통해 자유롭게 언어를 바꾸는 화면이다.
그런데 한 가지 주의사항이 있다.
보통 웹사이트에 루트페이지 즉, home.jsp(=index.jsp)
에서 다국어처리가 하는 경우가 대부분일 것이다. 그런데 이부분이 web.xml에 기재되는데
<display-name>home</display-name>
<welcome-file-list>
<welcome-file>/WEB-INF/views/home.jsp</welcome-file>
</welcome-file-list>
이런 상태로 다이렉트로 home.jsp페이지로 이동하면 안된다. 즉, 스프링 다국어처리를 이용하려면 controller를 통해서 해당 home.jsp로 이동하게 해야 한다.
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
}
위와 같이 루트(/)로 접근시 WEB-INF/views/home.jsp
로 처리하는 controller가 존재해야 한다.
그런 다음에 servlet-context.xml에서 다국어 처리부분을 기술해주면 된다.
먼저 다국어 처리를 위해 메시지를 별도의 파일로 분류해야 한다.
경로를 src/main/resources/locale
에 각각 영어, 일본어, 한국어 메시지파일을 만든다.
파일명 | 파일내용 |
---|---|
messages_en.properties | hello=Hello |
messages_ja.properties | hello=こんにちは |
messages_ko.properties | hello=안녕하세요 |
그런 다음에 servlet-context.xml에 다국어 처리부분을 추가한다.
<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basenames" value="locale/messages"/>
</beans:bean>
<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<beans:property name="defaultLocale" value="ko" />
</beans:bean>
<mvc:interceptors>
<beans:bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang" />
</beans:bean>
</mvc:interceptors>
ResourceBundleMessageSource
부분이 바로 위에서 저장된 messages파일들을 읽어오는 부분이다. 해당언어의 파일들이 존재하면 된다.
basenames에서 경로/파일명앞부분
를 적어준다.
localeResolver
에서 다국어처리 방법을 선택한다. localeResolver는 3가지 종류가 있다. 디폴트는 AceeptHeaderLocaleResolver이다.
즉, localeResolver를 별도로 구현하지 않으면 AceeptHeaderLocaleResolver가 브라우저의 설정된 언어값으로 읽어들여 처리한다. 이 값은 변경이 불가능하다.
따라서 사용자가 링크를 통해서 영어, 한국어, 일어등으로 자유롭게 변경하려면 localeResolver를 AceeptHeaderLocaleResolver가 아닌 다른 것으로 선언해야 한다.
반면에 그냥 브라우저에 세팅된 언어로 설정하려면 localeResolver를 없애면 된다.
SessionLocaleResolver
request가 가지고 있는 session으로 부터 locale정보를 가져온다. session에 있는 값을 가져오되, 만약 값이 없다면 defaultLocale로 설정을 지정할 수 있다.
아마 맨처음 접근시에는 session값이 없으므로 defaultLocale를 읽게 된다.
위에서는 SessionLocaleResolver를 정의하고 defaultLocale를 ko로 했으므로 브라우저에
세팅된 언어보다 위에 설정된 언어로 표시하게 된다.
CookieLocaleResolver
는 이름에서 알수있듯이 언어를 변경하고 쿠키에 값을 저장한다.
<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver" >
<beans:property name="cookieName" value="clientlanguage"/>
<beans:property name="cookieMaxAge" value="100000"/>
<beans:property name="cookiePath" value="web/cookie"/>
</beans:bean>
속성 | 기본값 | 설명 |
---|---|---|
cookieName | classname+locale | 저장할 쿠키명 |
cookieMaxAge | -1 | -1은 브라우저를 닫으면 지움 |
cookiePath | / | 경로를 지정할 수 있음 |
만약 저장된 쿠키값이 없어서 특정값으로 세팅하고자 한다면 defaultLocale
를 추가하면 된다.
<beans:property name="defaultLocale" value="ko" />
SessionLocaleResolver나 CookieLocaleResolver에 defaultLocale이 없다면 브라우저의 언어설정을 따르게 된다.
LocaleChangeInterceptor
는 사용자가 url를 통해서 언어를 변경할 경우 사용한다.
만약 홈경로가 http://localhost/home
이라고 하면 ?lang=언어값을 붙여서 사용한다.
- http://localhost/home/?lang=ko
- http://localhost/home/?lang=en
- http://localhost/home/?lang=ja
그렇게 되면 링크를 통해 언어변환처리를 할 수 있다.
<mvc:interceptors></mvc:interceptors>
로 감싸면 Spring MVC에서 controller를 통해서 접근시 가로채서 LocaleChangeInterceptor를 적용하게 된다.
servlet-context.xml의 최종소스이다.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.andwise.home" />
<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basenames" value="locale/messages"/>
</beans:bean>
<beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<beans:property name="defaultLocale" value="ko" />
</beans:bean>
<!--
<beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" >
<beans:property name="defaultLocale" value="ko" />
<beans:property name="cookieName" value="home-lang"/>
<beans:property name="cookieMaxAge" value="-1"/>
<beans:property name="cookiePath" value="/"/>
</beans:bean>
-->
<mvc:interceptors>
<beans:bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang" />
</beans:bean>
</mvc:interceptors>
</beans:beans>