[Spring] Locale 처리


Locale 처리


스프링 제공하는 <spring:message> 커스텀 태그는 웹 요청과 관련된 언어 정보를 이용해서 알맞은 언어의 메시지를 출력한다.

웹 브라우저의 언어 설정을 한국어(ko_kr)로 했을 때와 영어(en_us)로 했을 때 <spring:message> 커스텀 태그가 언어에 따라 알맞은 메시지를 출력해 주는 결과 화면을 보여주고 있다.


실제로, 스프링 MVC는 LocaleResolver를 이용해서 웹 요청과 관련된 Locale을 추출하고, 이 Locale 객체를 이용해서 알맞은 언어의 메시지를 선택하게 된다.

본 절에서는 스프링이 제공하는 LocaleResolver를 사용해서 Locale을 변경하는 방법에 대해서 살펴보도록 하겠다.


1. LocaleResolver 인터페이스

org,springframework.web.serlvet.LocaleResolver 인터페이스는 다음과 같이 정의 되어 있다.


package org.springframework.web.servlet;

import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


public interface LocaleResolver{

Locale resolveLocale(HttpServletRequest request);

void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale);

}

resolveLocale() 메서드는 요청과 관련된 Locale을 리턴한다. DispatcherServlet은 등록되어 있는 LocaleResolver의 resolveLocale() 메서드를 호출해서 웹 요청을 처리할 때 사용할 Locale을 구한다.

setLocale() 메서드는 Locale을 변경할 때 사용된다. 예를 들어, 쿠키나, 쿠기나 HttpSession에 Locale 정보를 저장할 때에 이 메서드가 사용된다.


2. LocaleResolver의 종류

스프링이 기본적으로 제공하는 LocaleResolver 구현 클래스는 다음과 같다.


※ 스프링이 제공하는 LocaleResolver 구현 클래스

 클래스

 설 명

 AcceptHeaderLocaleResolver

 웹 브라우저가 전송한 Accept-Language 헤더로부터 Locale 선택한다. setLocale() 메서드를 지원  하지 않는다.

 CookieLocaleResolver

 쿠키를 이용해서 Locale 정보를 구한다. setLocale() 메서드는 쿠키에 Locale 정보를 저장한다.

 SessionLocaleResolver

 세션으로부터 Locale 정보를 구한다. setLocale() 메서드는 세션에 Locale 정보를 저장한다.

 FixedLocaleResolver

 웹 요청에 상관없이 특정한 Locale로 설정한다. setLocale() 메서드를 지원하지 않는다.


(1) AcceptHeaderLocaleResolver

LocaleResolver를 별도로 설정하지 않을 경우 AcceptHeaderLocaleResolver를 기본 LocalResolver로 사용한다.

AcceptHeaderLocaleResolver는 AcceptLanguage 헤더로부터 Locale 정보를 추출한다.

헤더로부터 Locale 정보를 추출하기 때문에, setLocale() 메서드를 이용해서 Locale 설정을 변경할 수 없다.


(2) CookieLocaleResolver

CookieLocaleResolver는 쿠키를 이용해서 Locale 정보를 저장한다. setLocale() 메서드를 호출하면 Locale 정보를 담은 쿠키를 생성하고, resolveLocale() 메서드는 쿠기로부터 Locale 정보를 가져와 Locale 정보를

담은 쿠키가 존재하지 않을 경우, defaultLocale 프로퍼티의 값을 Locale로 사용한다. defaultLocale 프로퍼티의 값이 null인 경우에는 Accept-Language 헤더로부터 Locale 정보를 추출한다.

CookieLocaleResolver는 쿠티와 관련해서 별도 설정을 필요로 하지 않지만. 생성할 쿠키 이름, 도메인, 경로 등의 설정을 직접하고 싶다면 프로퍼티에 알맞게 설정해주면 된다.


※ CookieLocaleResolver의 쿠키 설정 관련 프로퍼티

프로퍼티 

설 명  

 cookieName

 사용할 쿠키 이름

 cookieDomain

 쿠키 도메인

 cookiePath

 쿠키 경로, 기본값은 "/"이다.

 cookieMaxAge

 쿠키 유효 시간

 cookieSecure

 보안 쿠키 여부, 기본값은 false 이다.


(3) SessionLocaleResolver

SessionLocaleResolver HttpSessio에 Locale 정보를 저장한다. setLocale() 메서드를 호출하면 Locale 정보를 세션에 저장하고, resolveLocale() 메서드는 세션으로부터 Locale을 가져와 웹 요청의 Locale을 설정한다.

만약 Locale 정보가 세션에 존재하지 않으면, defaultLocale 프로퍼티의 값을 Locale로 사용한다. defaultLocale 프로퍼티의 값이 null인 경우에는 Accept-Language 헤더로부터 Locale 정보를 추출한다.


(4) FixedLocaleResolver

FixedLocaleResolver는 웹 요청에 상관없이 defaultLocale 프로퍼티로 설정한 값을 웹 요청을 위한 Locale로 사용한다. FixedLocaleResolver는 setLocale() 메서드를 지원하지 않는다.

setLocale() 메서드를 호출할 경우 UnsupportedOperationException 예외를 발생시킨다.


3. LocaleResolver를 이용한 Locale 변경

LocaleResolver를 빈으로 등록했다면, 컨트롤러에서 LocaleResolver를 이용해서 Locale을 변경할 수 있게 된다. 예를 들어 다음과 같이 LocaleResolver를 설정했다고 하자.


<bean class="madvirus.spring.chap07.controller.LocaleChangeController">

<property name="localeResolver" ref="localeResolver" />

</bean>

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


이 경우, 컨트롤러 클래스는 다음과 같이 LocaleResolver의 setLocale() 메서드를 호출해서 클라이언트의 웹 요청을 위한 Locale을 변경할 수 있다.

import org.springframework.web.servlet.LocaleResolver;


@Controller

public class LocaleChangeController {


private LocaleResolver localeResolver;


@RequestMapping("/changeLanguage")

public String change(@RequestParam("lang") String language, HttpServletRequest request, HttpServletResponse response) {

Locale locale = new Locale(language);

localeResolver.setLocale(request, response, locale);

return "redirect:/index.jsp";

}


public void setLocaleResolver(LocaleResolver localeResolver) {

this.localeResolver = localeResolver;

}

}


LocaleResolver를 이용해서 Locale을 변경하면, 이후 요청에 대해서는 지정한 Locale을 이용해서 메시지 등을 로딩하게 된다.

ResolverContextUtils 클래스는 웹 요청과 관련된 LocaleResolver를 구할 수 있는 메서드를 제공하고 있으므로, 위 코드를 다음과 같이 변경할 수도 있다.

@Controller

public class LocaleChangeController2 {


@RequestMapping("/changeLanguage2")

public String change(@RequestParam("lang") String language, HttpServletRequest request, HttpServletResponse response) {

Locale locale = new Locale(language);

LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);

localeResolver.setLocale(request, response, locale);

return "redirect:/index.jsp";

}

}


4. LocaleChangeInterceptor를 이용한 Locale 변경

Locale을 변경하기 위해 별도의 컨트롤러 클래스를 개발한다는 것은 다소 성가신 일이다.

이 경우, 스프링이 제공하는 LocaleChangeInterceptor 클래스를 사용하면 웹 요청 파라미터를 이용해서 손쉽게 Locale을 변경할 수 있다.


LocaleChangeInteceptor 클래스는 handlerInterceptor로서 다음과 같이 HandlerMapping의 intercaptors 프로퍼티에 등록만 하면 설정이 완료된다. 아래 코드는 설정 예이다.

<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"

p:paramName="language" />


<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">

<property name="interceptors">

<list>

<ref bean="localeChangeInterceptor" />

</list>

</property>

</bean>

paramName 프로퍼티는 Locale을 설정할 때 사용할 파라미터 이름을 명시한다. 예를 들어, 위 코드에서는 paramName 프로퍼티의 값으로 language를 설정했는데,

이 경우 language 요청 파라미터를 사용해서 Locale을 변경할 수 있다.


http://localhost:8080/chap07/jsp/login/login.do?language=en

LocaleChangeInterceptor는 paramName 프로퍼티로 설정한 요청 파라미터가 존재할 경우, 파라미터의 값을 이용해서 Locale을 생성한 뒤 LocaleResolver를 이용해서 Locale을 변경한다.

이후, 요청에서는 변경된 Locale이 적용된다.