본문 바로가기

TroubleShooting/Spring

XML 기반의 Resource Bundle, PropertyPlaceHolder 사용하기

728x90

config 설정을 읽거나 다국어 지원를 위해 프로퍼티 파일 형식으로 처리한다.

이때 value 에 해당하는 부분이 긴 문자열이거나 문단일때는 "\n" 을 붙이는데, 일단 보기에도 어렵고 수정하려면 곤란한 경우가 생긴다. 이럴때 XML 형식으로 프로퍼티를 설정하면 작성한 형식으로 바로 출력이 가능하다.


예제 코드는 http://www.mkyong.com/spring/spring-resource-bundle-with-resourcebundlemessagesource-example/ 에 있는 샘플 코드를 참고해서 환경을 맞추고 편의상 수정했다.


그리고, 메시지 중간에 파라미터 형식으로 문자열을 넘겨서 동적으로 변경하기 위해 MessageFormat 클래스를 사용하는데, {0}, {1} 처럼 순서를 맞춰줘야 하는 문제점이 있지만 스프링에서 지원하는 PropertyPlaceHolder 클래스를 사용하면 {url} 같은 변수명 형식으로 변환이 가능하다.


- 기존의 key/value 방식

userName1=BB 님

userName2=BB 님\n~~~HI~~~~~\n

userName3=BB 님,\n${url} 여기로 접속


- XML 형식

. 한글 : message_ko_KR.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">

<properties>

<entry key="userName1">BB 님</entry>

<entry key="userName2">BB 님

~~~Hi~~~~

</entry>

<entry key="userName3"> BB 님, 

${url} 여기로 접속</entry>

</properties>


. 일본어 : message_JA.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">

<properties>

<entry key="userName1">BB様</entry>

<entry key="userName2">BB様

~~~Hi~~~~

</entry>

<entry key="userName3"> 様, 

${url} にて確認する

</entry>

</properties>


. 영어 : message_en.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">

<properties>

<entry key="userName1">Hi, BB.</entry>

<entry key="userName2">BB

~~~Hi~~~~

</entry>

<entry key="userName3"> BB, 

connect to ${url} </entry>

</properties>


- 스프링 빈 : locale.xml

<bean id="messageSource"

class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

<!-- class="org.springframework.context.support.ResourceBundleMessageSource"> -->

<property name="basename">

<value>locale\messages</value>

</property>

<property name="defaultEncoding" value="UTF-8" />

</bean>

* property defaultEncoding 를 UTF-8 로 지정하면 한글 메시지 파일이 제대로 보이기 위해 native2ascii 툴로 컨버팅 작업을 할 필요가 없다.


- 테스트하기 위해 사용한 코드

     @Test
	public void test() {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"locale.xml");

		String name1_ko = context.getMessage("userName1", null, Locale.KOREA);
		System.out.println("Customer name (Korean) : " + name1_ko);
		String name1_jp = context.getMessage("userName1", null, Locale.JAPAN);
		System.out.println("Customer name (Japan) : " + name1_jp);
		String name1_en = context.getMessage("userName1", null, Locale.ENGLISH);
		System.out.println("Customer name (English) : " + name1_en);

		String name2_ko = context.getMessage("userName2", null, Locale.KOREA);
		System.out.println("Customer name2 (Korean) : " + name2_ko);
		String name2_jp = context.getMessage("userName2", null, Locale.JAPAN);
		System.out.println("Customer name2 (Japan) : " + name2_jp);
		String name2_en = context.getMessage("userName2", null, Locale.ENGLISH);
		System.out.println("Customer name2 (English) : " + name2_en);

		String name3_en = context.getMessage("userName3", null, Locale.ENGLISH);
		Properties prop = new Properties();
		prop.setProperty("url", "http://www.naver.com");
		PropertyPlaceholderHelper propHelper = new PropertyPlaceholderHelper("${", "}");
		String aa = propHelper.replacePlaceholders(name3_en, prop);
		System.out.println("Conversion value : " + aa);
   }

* new PropertyPlaceholderHelper(prefix, postfix); 부분을 주의해서 사용하자. 변환하고자하는 문자열의 처음 규칙과 마지막 규칙 문자열을 입력해야 하는데, 아무 생각없이 둘다 null 을 넣고 했다가 무한루프에 빠지는 수가 있다.


- 출력 결과

Customer name (Korean) : BB 님

Customer name (Japan) : BB様

Customer name (English) : Hi, BB.

Customer name2 (Korean) : BB 님

~~~Hi~~~~

Customer name2 (Japan) : BB様

~~~Hi~~~~

Customer name2 (English) : BB

~~~Hi~~~~

Conversion value :  BB, 

connect to http://www.naver.com 



도움받은 사이트 :

http://www.mkyong.com/spring/spring-resource-bundle-with-resourcebundlemessagesource-example/

http://www.java2s.com/Tutorial/Java/0220__I18N/XMLresourcebundle.htm

http://docs.oracle.com/javase/6/docs/api/java/text/MessageFormat.html

http://docs.spring.io/spring/docs/3.0.x/javadoc-api/org/springframework/util/PropertyPlaceholderHelper.html