Spring 다국어

R c·2023년 9월 29일
0

서론

여러 나라에서 서비스가 되는 사이트를 개발하게 된다면 서비스 되는 나라의 언어에 맞추는건 어찌 생각해보면 당연한 일 일텐데 어떻게 해야할까?


구현방법

Spring 기능중에 LocaleResolver를 사용하여 locale에서 사용중인 언어 객체를 찾아 활용하여 message.propeties를 사용하여 다국어 활용

LocaleResolver란?
resolverLocale() 메서드는 요청과 관련된 Locale을 리턴한다. DispatcherServlet은 등록되어 있는 LocaleResolver의 resolverLocale() 메서드를 호출해서 웹 요청을 처리할 때 사용할 Locale을 구한다.
setLocale() 메서드는 Locale을 변경할 때 사용된다.
스프링은 LocaleResolver 인터페이스의 다양한 구현체들을 제공한다.

LocaleResolver종류

클래스설명
AcceptHeaderLocaleResolver웹 브라우저가 전송한 헤더의 Accept-Language 값을 기반으로 Locale을 선택한다.setLocale() 메서드를 지원하지 않는다.
SessionLocaleResolver세션으로부터 Locale 정보를 구한다.setLocale() 메서드는 세션에 Locale 정보를 저장한다.
CookieLocaleResolver쿠키를 이용해서 Locale 정보를 구한다.setLocale() 메서드는 쿠키에 Locale 정보를 저장한다.
FixedLocaleResolver웹 요청에 상관없이 특정한 Locale로 설정한다.setLocale() 메서드를 지원하지 않는다.

작성자는 SessionLocalResolver를 사용하여 개발하였다.

해당 글에는 매우 심플하게 구현되어 있으므로 이대로만 사용하기엔 무리가 있다고 느끼고 실제 실무에 사용된다면 많이 더 손을 봐야 할거같다.


<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />
<!-- 쿠키를 이용한 Locale 이용시 
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/> 
-->

전자정부 프레임워크(이하 egov)로 기본 프로젝트 생성시 지정된 LocaleResolver를 그대로 사용하였다.

기본 제공되는 message-common.properties를 보게 되면 기본인 common과 ko, en이 존재한다.

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
		<property name="basenames">
			<list>
				<value>classpath:/egovframework/message/message-common</value>
				<value>classpath:/egovframework/rte/fdl/idgnr/messages/idgnr</value>
				<value>classpath:/egovframework/rte/fdl/property/messages/properties</value>
			</list>
		</property>
		<property name="cacheSeconds">
			<value>60</value>
		</property>
	</bean>

설정 역시 egov에서 기본 설정된 값을 그대로 사용하였다.


LocaleResolver 영역에서 local의 정보 꺼내오기

LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if (localeResolver != null) {
    Locale locale = localeResolver.resolveLocale(request);		    
    String language = locale.getLanguage();
}

이처럼 LocalResolver를 사용하여 local의 language를 꺼내 활용이 가능하다. 이 안에 값을 수정하면 물론 해당 message-common도 바꿔 사용이 가능하다.


jsp페이지에서 local의 language를 수정하는 버튼을 만들고 controller를 만들어 수정해보자.
<script>
$(document).on("click", "#lang-kor", function(){
	alert("kor클릭");
	$.ajax({
		url:"/langKor.do",
		success: function(){
			location.reload();
		}
	})
});
$(document).on("click", "#lang-eng", function(){
	alert("eng클릭");
	$.ajax({
		url:"/langEng.do",
		success: function(){
			location.reload();
		}
	})
});
</script>

lang-kor, lang-eng 라는 ID의 버튼을 누르면 비동기 ajax통신으로 특정 url로 이동한 뒤 reload되는 방식이다.


@ResponseBody
@RequestMapping(value = "langEng.do")
public void langEng (HttpServletRequest request, HttpServletResponse response) throws Exception {
	String language = "en";
	Locale locale = new Locale(language);
	LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
	localeResolver.setLocale(request, response, locale);
}

@ResponseBody
@RequestMapping(value = "langKor.do")
public void langKor (HttpServletRequest request, HttpServletResponse response) throws Exception {
	String language = "ko";
	Locale locale = new Locale(language);
	LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
	localeResolver.setLocale(request, response, locale);
}

위의 각각의 url로 이동을 하게 되는데 이때 controller가 view로 이동하는 것이 아니므로 @ResponseBody를 사용하였고 해당 구문 안에는 language를 변수로 만들고 locale 객체에 담은 뒤 session에 저장된 LocaleResolver를 객체로 만들어 setLocale한 모습이 보인다.


이제 이렇게 locale에 저장된 language를 사용하여 message에 지정된 값들을 화면에 뿌려주면 된다.
user.lang=한국어 사용
user.where=나는 회사에 있다.
user.img=/images/ko.png
user.lang=use to Eng
user.where=I'm in comp
user.img=/images/eng.png

이처럼 다른 message파일에 같은 이름의 변수에 각자 언어에 맞는 값을 저장한 뒤 language에 따라 어떤 것을 보여줄지 결정하면 된다.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

<spring:message code="user.lang" />
<spring:message code="user.where" />
<spring:message code="user.img" />

이렇게 표현이 가능하다.


이번 글에는 spring의 다국어에 대해 간단하게 정리해 봤는데 다른 블로그들처럼 상세하게 다루지 않아서 내용이 많이 부족하지만 감을 잡는정도로 이정도면 충분하다고 느꼇다. 나중에 실제 업무에 사용될 때는 좀 도 session뿐만 아니라 다양한 방식으로 구현을 해봐야겠다.

0개의 댓글