상세 컨텐츠

본문 제목

Jakarta Struts 강좌 6 - 국제화 지원 및 자바지기가 생각하는 한글문제 해결방법

프로그래밍/JAVA

by 라제폰 2009. 3. 6. 19:23

본문

Jakarta Struts 강좌 6 - 국제화 지원 및 자바지기가 생각하는 한글문제 해결방법

Summary : 스트러츠를 이용하여 애플리케이션을 개발하면서 한글문제를 좀 더 쉽게 해결할 수 있는 방법에 몇달동안 찾은 해결책을 제시한다. 자바지기 사이트를 방문한 많은 개발자들을 통해 좋은 결과를 찾을 수 있었다. 한글문제의 해결과 더불어 스트러츠에서 지원하는 국제화(Internationalization : I18N)에 대하여 살펴본다. 지금까지 국문,영문을 지원하는 애플리케이션을 개발하기 위해서는 별도의 애플리케이션을 개발하는 사례가 많았다. 스트러츠를 이용하면 하나의 애플리케이션을 통해 다양한 언어로 서비스할 수 있는 방법에 대하여 살펴본다.

스트러츠의 국제화 지원

초기의 웹 애플리케이션은 단일 언어만 지원해도 되는 환경에서 개발되었다. 그러나 점차 웹 애플리케이션을 통하여 무수히 많은 비지니스가 이루어 지고 있으며, 단일 국가내에서뿐만 아니라 다양한 국가, 다양한 언어로 서비스할 필요가 점차 증가하고 있다. 필자도 최근 개발한 애플리케이션에서 국문과 영문으로 서비스하려는 고객의 요구가 발생했다. 그러나 별 생각없이 기존 방식대로 국문과 영문으로 나누어 개발했다. 먼저 국문을 개발한 다음 똑같은 내용의 페이지들을 영문으로 개발하는 일이 발생했다.

이럴 경우 개발을 담당하는 개발자들도 단순작업이 반복되기 때문에 일하는데 짜증이 발생하기 마련이며, 작업 속도 또한 생각보다 많이 소요된다. 또한 고객이 국문, 영문외에 중국어로 서비스를 하고자 한다면 개발자들은 똑같은 작업을 다시 한번 반복해야 한다.

애플리케이션을 개발할 때 국어, 영어, 중국어등 다양한 언어로 서비스하게 될 때의 차이점을 살펴보자. 실질적으로 애플리케이션의 비지니스로직상에 다른 점은 없다. 단지 서비스할 때 발생하는 메세지와 이미지등이 해당 고객에 맞는 언어로 서비스 될 수 있다면 문제는 해결할 수 있다. 따라서 스트러츠에서는 자바의 Locale클래스를 이용하여 이러한 문제점을 해결할 수 있도록 하였다.

스트러츠에서는 애플리케이션에서 사용하는 모든 메세지와 이미지등의 정보를 properties파일에 저장하여 국제화 지원을 가능하도록 하였다. 즉 지금까지 강좌에서 사용했던 MessageResources.properties와 같이 properties파일에 모든 메세지정보를 저장한다. 추후 다른 언어로 서비스할 필요가 발생할 때는 properties의 내용을 해당 언어로 바꾸기만하면 서비스가 가능한 상태로 구현할 수 있다.

위에서 언급한 바와 같이 하나의 애플리케이션에서 다양한 언어로 서비스가 가능하다고 하였다. 그러나 위와같이 하나의 properties만을 이용할 경우에는 하나의 언어로만
서비스가 가능하다. 따라서 스트러츠에서는 자바의 Locale클래스를 이용하여 다음과 같은 규칙으로 properties파일로 서비스가 가능하도록 하였다.

MessageResources.properties : 애플리케이션의 디폴트언어에 대한 메세지.

MessageResources_en.properties : 영어를 위한 메세지.

MessageResources_ko.properties : 국어를 위한 메세지.

위와 같이 국어와 영어를 위한 메세지를 담고 있는 properties파일이 있을 경우 접근하는 클라이언트의 언어에 따라 해당하는 언어로 서비스할 수 있도록 지원하고 있다.

스트러츠는 애플리케이션에서 사용할 메세지 번들을 struts-config.xml에서 다음과 같이 정의한다.

스트러츠에서 국제화를 지원하는 예제를 보이기 위하여 지난번 강좌까지 개발했던 사용자관리 예제에서 MessageResources.properties를 MessageResources_en.properties, MessageResources_ko.properties에 각각 영어, 국어로 메세지를 따로 저장하여 클라이언트의 언어에 따라 해당 언어로 서비스되는 과정을 살펴보도록하겠다.

먼저 MessageResources_ko.properties에는 지금까지 개발해왔던 MessageResources.properties의 메세지를 그대로 복사한다. 그러나 지난 강좌와 같이 한글을 그대로 사용할 경우 한글이 깨지는 문제가 계속해서 발생하고 있다. 따라서 native2ascii 유틸리티를 이용하여 네이티브 문자열을 유니코드로 인코딩한다음 사용하도록 하겠다.

native2ascii 유틸리티를 사용하는 방법은 다음과 같다.

*native2ascii 입력파일이름 출력파일이름 *

예 : native2ascii MessageResources.properties MessageResources_ko.properties
과 같이 사용하면 된다.

login.title = Welcome to RegisterUser
login.login = \ub85c\uadf8\uc778
login.useradd = \ud68c\uc6d0\uac00\uc785
user.usermanager = \uc0ac\uc6a9\uc790 \uad00\ub9ac
user.useradd = \uc0ac\uc6a9\uc790 \ucd94\uac00
useradd.cancel = \ucde8\uc18c

prompt.id=\uc544\uc774\ub514 :
prompt.password=\ube44\ubc00\ubc88\ud638 :
prompt.name=\uc774\ub984 :
prompt.email=E-mail :

mainmenu.title=Main Page
mainmenu.presentation=\uc774 \ud398\uc774\uc9c0\ub294 Main Menuh2.


#\uc5d0\ub7ec \uba54\uc138\uc9c0
error.id.lengtherror=<li>\uc544\uc774\ub514\ub294 4\uc790\ub9ac \uc774\uc0c1, 10\uc790\ub9ac
\uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.</li>
error.password.lengtherror=<li>\ube44\ubc00\ubc88\ud638\ub294 4\uc790\ub9ac \uc774\uc0c1, 10\uc790\ub9ac
\uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.</li>

error.id.required=<li>\uc544\uc774\ub514\ub294 \uaf2d \uc785\ub825\ud574\uc57c \ub429\ub2c8\ub2e4.</li>
error.id.notexisted=<li>\uc874\uc7ac\ud558\uc9c0 \uc54a\ub294 \uc544\uc774\ub514\uc785\ub2c8\ub2e4.</li>
error.password.required=<li>\ube44\ubc00\ubc88\ud638\ub294 \uaf2d \uc785\ub825\ud574\uc57c
\ub429\ub2c8\ub2e4.</li>
error.password.match=<li>\ube44\ubc00\ubc88\ud638\uac00 \ud2c0\ub9bd\ub2c8\ub2e4.</li>

error.transaction.token=<li>Transaction\uc774 \uc774\ubbf8 \uc2e4\ud589\ub418\uc5c8\uc2b5\ub2c8\ub2e4.</li>

errors.header=<h3><font color="red">\ub85c\uadf8\uc778 \uc5d0\ub7ec</font></h3> 
                  You must correct the following error(s) before proceeding:<UL>
errors.footer=</ul><hr>

다음에 보게될 메세지는 한글로 된 메세지를 영어로 변환한 MessageResources_en.properties의 내용이다. 필자가 영어가 되지 않는 관계로 문맥상 맞지않는 부분도 있기 때문에 영어 문맥은 신경쓰지 말아주었으면 한다. 각각의 properties로 나누어서 메세지를 작성할 때 각 메세지의 키값을 같도록하면 해당 언어에 따라 메세지가 달라지게 된다.

다음 메세지를 위 한글메세지가 영어로 바뀐메세지이다.

login.title = Welcome to RegisterUser
login.login = login
login.useradd = Add User
user.usermanager = User Manager
user.useradd = Add User
useradd.cancel = Cancel

prompt.id=ID :
prompt.password=Password :
prompt.name=Name :
prompt.email=E-mail :

mainmenu.title=Main Page
mainmenu.presentation=This page is Main Menuh2.


#Error Messages
error.id.lengtherror=<li>ID is More Than 4, ID is Less Than 10.</li>
error.password.lengtherror=<li>Password is More Than 4, Password is Less Than 10.</li>

error.id.required=<li>ID must be required</li>
error.id.notexisted=<li>ID don't existed</li>
error.password.required=<li>Password must be required</li>
error.password.match=<li>Password is different</li>

error.transaction.token=<li>Transaction was executed already.</li>

errors.header=<h3><font color="red">Login Error</font></h3> 
                  You must correct the following error(s) before proceeding:<UL>
errors.footer=</ul><hr>

아래 화면은 클라이언트의 언어에 따라 해당언어로 메세지를 뿌려주는 화면을 보여주고 있다. 클라이언트의 언어를 바꾸는 방법은 브라우저에서 바꿀 수 있다. 국내는 대부분 익스플로러를 웹브라우저로 사용하기 때문에 익스플로러를 기준으로 설명하겠다.

브라우저에서 도구 >> 인터넷옵션 >> 언어를 선택하면 아래 화면과 같이 한국어가 위에 위치해 있을 것이다. 한국어[ko]와 같이 ko가 뒤에 붙는 것을 확인할 수 있다. 익스플로러를 설치한후 언어설정을 바꾸지 않았다면 한국어가 제일 위에 있을 것이다. 만약 영어로 테스트를 해보고자 한다면 영어를 제일위로 올려 브라우저를 새로 띄운다음 예제소스에 접근해 보기 바란다. 영어로 된 메세지를 확인할 수 있을 것이다. 영어가 없는 경우에는 영어를 추가한다음 제일 위로 이동하여 브라우저의 디폴트언어로 설정한다.

아래 두 화면은 익스플로러에서 언어 설정을 한국어로 했을때와 영어로 했을 때 각각 보여지는 로그인화면이다.

위에서 본 바와 같이 스트러츠는 하나의 애플리케이션에서 다양한 언어로의 서비스가 가능하도록 지원하고 있다. 이 같이 개발할 경우 초기 개발시에는 많은 시간이 소요되지만 서비스중에 메세지를 수정하거나 다른 언어로 서비스하고자 할 때는 간단하게 properties의 메세지만을 수정해서 서비스가 가능하다. 위 예제에서는 없었지만 이미지의 경로도 properties에 저장하여 관리할 수 있다.

자바지기가 생각하는 스트러츠에서 한글문제의 해결책

스트러츠를 이용하여 애플리케이션을 개발하다보니 한글문제가 발생하였다. 발생하는 한글문제에 대하여 자바지기 게시판을 통하여 많은 개발자들의 의견을 수렴하는 과정을 가졌다. 필자 또한 다양한 개발자들의 조언과 의견으로 인해 스트러츠 프레임워크을 이용할 경우 발생하는 한글문제를 해결할 수 있는 최선의 해결책을 얻을 수 있었다. 이 해결책은 필자가 생각하는 한글의 해결책이다. 개발하는 환경에 따라 다양한 해결책이 있을 것으로 생각한다.

첫번째 한글문제는 위에서 살펴본 MessageResources.properties에 한글이 들어갈 경우 한글이 깨지는 문제이다.

두번째 한글문제는 입력폼에서 사용자가 한글을 입력할 경우 매번 한글로 변환하지 않기 위한 방법을 찾는 것이였다.

첫번째 한글문제에 대한 다양한 개발자들의 의견은 다음 URL을 보면 알 수 있다.

http://www.javajigi.net/servlet/JMBoard?tablename=struts_qna&mode=view&boardpage=1&searchword=&searchscope=&category=&no=93

properties에서 한글을 그대로 사용하기 위하여 다양한 방법을 시도해봤지만 다른 부분에서 한글이 깨지는 문제가 발생했다. 따라서 필자가 내린 최종 결론은 native2ascii 유틸리티를 사용하는 것이 최선의 방법으로 결론지었다. 그러나 문제는 propeties에 변경이 있을 때마다 native2ascii를 이용하여 유니코드로 변환하는 작업이 생각보다 짜증나는 작업일 것으로 생각된다.

대안으로 여러가지 방법이 있겠지만 필자는 다음 방법 중 하나로 해결하는 것이 좋을 것으로 생각된다.

첫째, ant 툴을 이용하여 빌드하는 방법에 익숙한 개발자들은 ant툴을 이용하여 native2ascii를 사용할 수 있다. 따라서 properties에 변경이 있을
경우 ant를 이용하여 새롭게 빌드를 해주는 방법이 있다.

둘째, ant에 익숙하지 않은 개발자들은 개발시에는 모든 메세지를 간단하에 영어로 먼저 작성한 다음 프로젝트가 완료되는 시점에 모든 메세지를 한글로 변환하는 것이 좋을 것으로 생각된다. 필자가 경험한 바에 의하면 모든 에러메세지나 사용자에게 보여지는 메세지를 프로젝트 막바지에 정리하는 시간이 있다. 이 때에 모든 메세지를 한글로 변환한다면 개발시에 한글 문제 때문에 native2ascii를 자주 실행할 필요가 없을 것으로 생각된다.

위 두가지 방법 외에도 개발자들의 요구에 따라 효율적인 방법을 찾을 수 있을 것으로 생각된다.

두번째 한글문제에 대한 다양한 개발자들의 의견은 다음 URL을 보면 알 수 있다.

http://www.javajigi.net/servlet/JMBoard?tablename=struts_qna&mode=view&boardpage=1&searchword=&searchscope=&category=&no=99

위 글을 자세히 읽어보면 알겠지만 대부분의 개발자들이 Servlet2.3에서 제공하는 Filter기능을 이용하여 한글문제를 해결하는 것이 가장 좋은 해결책으로 제시하고 있다. Filter를 이용하여 한글 문제를 해결할 경우 Servlet2.3을 지원하는 애플리케이션 서버여야 한다. 그러나 실제 현업에서 사용하고 있는 대부분의 애플리케이션 서버는 아직까지 Servlet2.3을 지원하지 않는 경우가 많다. 따라서 필자는 스트러츠에서 제공하는 Filter와 같은 기능을 이용하여 이 문제를 해결했다.

스트러츠의 RequestProcessor클래스를 보면 processPreprocess라는 메써드가 있다. 이 메써드의 역할이 Servlet2.3에서 제공하는 Filter와 같은 기능을 제공할 수 있다. 메써드 이름에서도 알 수 있듯이 다른 작업이
이루어지기 전에 미리 설정할 작업들을 여기서 설정 할 수 있다. 따라서 RequestProcessor를 상속하는 새로운 클래스를 만들어 한글문제를 해결할 수 있다. 필자가 processPreprocess에서 구현한 내용은 Servlet Filter에서 구현한 내용과 동일하다.

package net.javajigi.mall.processor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.javajigi.mall.Constants;
import org.apache.struts.action.RequestProcessor;

public class ZigiMallRequestProcessor extends RequestProcessor {

	protected boolean processPreprocess(
		HttpServletRequest request,
		HttpServletResponse response) {
		
		try {
			request.setCharacterEncoding(Constants.MALL_ENCODING);			
			
			return true;
		} catch (Exception e) {
			System.out.println("Exception is created : " + e.getMessage());
			return false;			
		}
	}
}

스트러츠는 디폴트로 RequestProcessor를 사용하기 때문에 RequestProcessor를 상속하는 새로운 클래스를 추가하기 위해서는 다음과 같이 struts-config.xml의 controller엘리먼트에서 설정해 주어야 한다.

<controller

contentType="text/html;charset=euc-kr"

debug="3"

locale="true"

nocache="true"

processorClass="net.javajigi.mall.processor.ZigiMallRequestProcessor"/>

지금까지의 강좌 JSP에서 아래와 같이 사용한 부분을

<%@ page language="java"%>

<% response.setContentType("text/html"); %>

=>

<%@ page contentType="text/html;charset=EUC-KR"%>

로 바꾸어 주어야 한다.

위 방법으로 간단하게 한글 문제를 해결할 수 있다. 만약 Servlet 2.3을 지원하는 애플리케이션 서버라면 Filter기능을 이용해서 한글문제를 해결할 수 있다. 개발자들의 개발환경에 따라 선택적으로 사용할 수 있다. 그러나 서버의 버전에 상관없이 개발하고자 하는 개발자들은 위 방법을 이용하여 개발하는 것이 최선의 해결책으로 생각된다.

이번 강좌에 첨부되는 예제소스는 계속되는 강좌를 위하여 user 디렉토리에 있던 jsp파일을 /아래로 이동하였다. 다른 부분의 변경은 없기 때문에 소스를 이해하는데는 큰 문제는 없을 것으로 생각된다.

이번 절에서 설명한 한글문제 해결방법이 최상의 해결책은 아니다. 더 좋은 해결책도 있을 것으로 생각된다. 각 프로젝트의 상황에 따라 다른
해결방법을 찾는 것이 가장 좋은 해결책이라고 생각한다.

강좌에 대하여

작성자 : [자바지기](박재성)
작성일 : 2005년 2월 20일

문서이력 :

  • 2005년 2월 20일 박재성 문서 최초 생성

참고 자료



관련글 더보기