Struts2 에서의 국제화

Struts2 의 국제화는 Struts2의 TextProvider에 의해 이루어진다. 내부적으로는 PropertyResourceBundle 을 사용하고 있어서 기본적으로는 한글을 사용할 수가 없다.

Java의 properties 파일은 ISO-8859-1 인코딩을 사용하고 있기 때문이다. properties 파일의 인코딩을 UTF-8로 바꾼다 해도 내부적으로 ISO-8859-1로 취급해버린다.

Struts의 소스 코드를 건드리지 않고 한글을 제대로 출력할 수 없을까 하고 생각해보았다.

또한 Struts2 i18n layout에 익숙한 사용자도 있을 것이기 때문에 xml 로 resource bundle을 바꾸기도 좀 그렇기 때문에 기존의 properties 파일을 사용하는 방법으로 고민해보았다.

<s:text>태그에서는 Action Class 의 getText() method를 호출하기 때문에 getText() method를 바꾸기로 하였다.

각 Action 에서는 다음 class 를 상속하여 구현하고, properties 파일의 인코딩을 UTF-8로 바꾸면 국제화에 문제가 없을 것이다.

AbstractAction.java

package com.fguy.action;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import com.fguy.util.UTF8ResourceBundle;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

@SuppressWarnings("unchecked")
public abstract class AbstractAction extends ActionSupport {
	private static final long serialVersionUID = 5107762886506915539L;

	@Override
	public String getText(String textName) {
		return convertResource(super.getText(textName));
	}

	@Override
	public String getText(String textName, List args) {
		return convertResource(super.getText(textName, args));
	}

	@Override
	public String getText(String key, String defaultValue, List args,
			ValueStack stack) {
		return convertResource(super.getText(key, defaultValue, args, stack));
	}

	@Override
	public String getText(String textName, String defaultValue, List args) {
		return convertResource(super.getText(textName, defaultValue, args));
	}

	@Override
	public String getText(String textName, String defaultValue, String obj) {
		return convertResource(super.getText(textName, defaultValue, obj));
	}

	@Override
	public String getText(String key, String defaultValue, String[] args,
			ValueStack stack) {
		return convertResource(super.getText(key, defaultValue, args, stack));
	}

	@Override
	public String getText(String key, String defaultValue, String[] args) {
		return convertResource(super.getText(key, defaultValue, args));
	}

	@Override
	public String getText(String textName, String defaultValue) {
		return convertResource(super.getText(textName, defaultValue));
	}

	@Override
	public String getText(String key, String[] args) {
		return convertResource(super.getText(key, args));
	}

	@Override
	public ResourceBundle getTexts() {
		return new UTF8ResourceBundle((PropertyResourceBundle) super.getTexts());
	}

	@Override
	public ResourceBundle getTexts(String bundleName) {
		return new UTF8ResourceBundle((PropertyResourceBundle) super
				.getTexts(bundleName));
	}

	/**
	 * Convert localized string from properties file
	 *
	 * @param text
	 * @return
	 */
	private static final String convertResource(String text) {
		String result = text;
		try {
			result = new String(result.getBytes("ISO-8859-1"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
		return result;
	}
}

UTF8ResourceBundle.java

package com.fguy.util;

import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

@SuppressWarnings("unchecked")
public class UTF8ResourceBundle extends ResourceBundle {
	PropertyResourceBundle bundle;

	public UTF8ResourceBundle(PropertyResourceBundle bundle) {
		this.bundle = bundle;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.util.ResourceBundle#getKeys()
	 */
	public Enumeration getKeys() {
		return bundle.getKeys();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.util.ResourceBundle#handleGetObject(java.lang.String)
	 */
	protected Object handleGetObject(String key) {
		String value = (String) bundle.handleGetObject(key);
		try {
			return new String(value.getBytes("ISO-8859-1"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			// Shouldn't fail - but should we still add logging message?
			throw new RuntimeException(e);
		}
	}
}
This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

7 Responses to Struts2 에서의 국제화

  1. 정원희 says:

    전 그냥 native2ascii 로 돌려버리…

  2. 말라 says:

    휴. native2ascii돌려서 유니코드로 바꿔도 안먹어서 ㅠㅠ
    별짓 다 하다가 이방법대로 하니깐 되네요
    감사합니다 퍼갈께요..

  3. ohgyun says:

    아. properties 파일의 utf-8로의 인코딩 때문에 고민하고 있었는데,
    덕분에 바로 해결했습니다.^^
    좋은 정보 감사합니다.

  4. 열혈개발 says:

    사알짝 퍼 가요~

  5. Struts2 공부하는 학생 says:

    Struts2 로 게시판을 만들었는데 검색어, 페이징 을 해주었는데,한글 검색을 하면 되는데, 한글 검색후 페이지 이동을 하면 검색어 칸에 한글이 깨져서 페이지 검색이 안되는 현상이 있는데 어떻게 해야하는지… euc-kr 로 하는건 되는데 utf-8로 하면 저런 현상이 일어 나서..조언 부탁드려요..

  6. 삽질대마왕 says:

    삽질삽질삽질만 하다 여기 있는대로 해서 성공했습니다.
    너무 감사합니다.

    해를 넘기나 고민했는데
    다행히 2008년에 해결해서 너무 감사드립니다.

    복 받으실 겁니다.

    2009년 행복하세요

  7. jongwon says:

    해결은 되겠지만, 매번 메시지를 호출할때마다 인코딩을 수정해 주어야 하므로…
    제 생각엔 native2ascii 방법이 훨씬 훌륭한 듯 보입니다.
    native2ascii 변환은 Eclipse의 properties Editor 플러그인을 사용하시면 편리합니다.

댓글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

Gravatar
WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. Log Out / 변경 )

Twitter picture

Twitter의 계정을 사용하여 댓글을 남깁니다. Log Out / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. Log Out / 변경 )

%s에 연결하는 중