2007년 2월 14일 수요일

ResourceBundle 작성시 한글 깨짐 현상 해결하기

기존에 나와 있는 방식들로는 죄다 native2ascii.exe를 실행시킴으로서 모든 문자셋을 UTF-8로 바꾸는 것이였다. 이렇게 작성된 ResourceBundle은 관리하기가 어렵고 또한 그 해독성도 떨어진다.

이런 문제점에 대비하여 struts에서 MessageResourceBundle을 추가시 필터링을 하여 ISO-8859-1 문자셋을 일괄적으로 UTF-8로 바꾸어주는것이다. 또한 MessageResourceBundle파일 자체도 UTF-8로 인코딩이 되여진 상태여야 한다. 구체적인 방법론을 적는다면

1. struts-config.xml에서 아래와같이 ResourceBundle을 선언한다.

<!-- Message Resources Configuration -->
  <message-resources parameter="com.nanumsem.nnserp.struts.ApplicationResources"
  factory="com.nanumsem.nnserp.common.util.NativePropertyMessageResourcesFactory"/>

2. NativePropertyMessageResourcesFactory.java 클래스와 NativePropertyMessageResources.java 클래스를 만든다. 소스는 아래와 같다.
NativePropertyMessageResources.java

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Locale;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.util.MessageResourcesFactory;
import org.apache.struts.util.PropertyMessageResources;

/**
 * @author Leegun
 *
 * TODO Refactorying the messageResources
 */

public class NativePropertyMessageResources extends PropertyMessageResources {
 /**
  *
  */
 private static final long serialVersionUID = -3090742115238775114L;
 Log log = LogFactory.getLog(NativePropertyMessageResources.class);

 /**
  * 
  */
 public NativePropertyMessageResources(MessageResourcesFactory factory,
   String config) {
  super(factory, config);
 }

 /**
  * 
  */
 public NativePropertyMessageResources(MessageResourcesFactory factory,
   String config, boolean returnNull) {
  super(factory, config, returnNull);
 }

 /**
  * Load the messages associated with the specified Locale key. For this
  * implementation, the config property should contain a fully qualified
  * package and resource name, separated by periods, of a series of property
  * resources to be loaded from the class loader that created this
  * PropertyMessageResources instance. This is exactly the same name format
  * you would use when utilizing the java.util.PropertyResourceBundle class.
  *
  * @param localeKey
  *            Locale key for the messages to be retrieved
  */
 @SuppressWarnings("unchecked")
 protected synchronized void loadLocale(String localeKey) {
  if (log.isTraceEnabled()) {
   log.trace("loadLocale(" + localeKey + ")");
  }

  // Have we already attempted to load messages for this locale?
  if (locales.get(localeKey) != null) {
   return;
  }

  locales.put(localeKey, localeKey);

  // Set up to load the property resource for this locale key, if we can
  String name = config.replace('.', '/');

  if (localeKey.length() > 0) {
   name += ("_" + localeKey);
  }

  name += ".properties";

  InputStream is = null;
  Properties props = new Properties();

  // Load the specified property resource
  if (log.isTraceEnabled()) {
   log.trace("  Loading resource '" + name + "'");
  }

  ClassLoader classLoader = Thread.currentThread()
    .getContextClassLoader();

  if (classLoader == null) {
   classLoader = this.getClass().getClassLoader();
  }

  is = classLoader.getResourceAsStream(name);

  if (is != null) {
   try {
    props.load(is);
   } catch (IOException e) {
    log.error("loadLocale()", e);
   } finally {
    try {
     is.close();
    } catch (IOException e) {
     log.error("loadLocale()", e);
    }
   }
  }

  if (log.isTraceEnabled()) {
   log.trace("  Loading resource completed");
  }

  // Copy the corresponding values into our cache
  if (props.size() < 1) {
   return;
  }

  synchronized (messages) {
   Iterator names = props.keySet().iterator();

   while (names.hasNext()) {
    String key = (String) names.next();

    if (log.isTraceEnabled()) {
     log.fatal("  Saving message key '"
       + messageKey(localeKey, key));
    }

    String convertedMessage = props.getProperty(key);

    try {
     convertedMessage = new String(convertedMessage
       .getBytes("ISO-8859-1"), "UTF-8");
    } catch (Exception e) {
     log.fatal("Invalid Encoding.." + e);
    }
    messages.put(messageKey(localeKey, key), convertedMessage);
   }
  }
 }

 /**
  * 
  */
 public String getMessage(String key) {
  String message = super.getMessage(key);
  try {
   Locale locale = new Locale("KOREAN");
   message = getMessage(locale, key);
  } catch (Exception e) {
   log.trace("" + e);
  }
  return message;
 }
}

NativePropertyMessageResourcesFactory.java

import org.apache.struts.util.MessageResources;
import org.apache.struts.util.PropertyMessageResourcesFactory;

/**
 * @author Leegun
 *
 * TODO
 */

public class NativePropertyMessageResourcesFactory extends
  PropertyMessageResourcesFactory {

 /**
  *
  */
 private static final long serialVersionUID = 2327883320430973180L;

 /**
  *
  */
 public NativePropertyMessageResourcesFactory() {
  super();
 }

 /* (non-Javadoc)
  * @see org.apache.struts.util.PropertyMessageResourcesFactory#createResources(java.lang.String)
  */
 public MessageResources createResources(String config) {
  return new NativePropertyMessageResources(this, config, this.returnNull);
 }

}

3. ResourceBundle파일의 문자열 인코딩 방식을 UTF-8로 설정한다.
사용자 삽입 이미지

댓글 없음:

댓글 쓰기