티스토리 뷰

Daylogs/Java

Resource Bundle

ohgyun 2008. 10. 9. 11:08
원문: http://jcjang.tistory.com/entry/ResourceBundle%EC%9D%98-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

properties 파일은 classes 아래 폴더를 하나 생성하여 관리하는 게 좋겠다.


===================================================================================================


ResourceBundle의 사용하기

1. API 위치
java.util.ResourceBundle

JDK 1.1 부터 지원

2. 역할
프로그램 배포시 고정된 자원과 변화하는 자원이 있다. 게시판 배포를 예로 든다면 안에 소스는 대부분 고정된 자원이다. 하지만 사용자마다 database의 설정 등은 수정해서 사용해야 하는 부분이다. 이러한 값들은 프로그램의 알고리즘과 상관없는 부분으로 따로 관리해야 하는 자원들이다. 이러한 자원은 파일로 저장해서 관리하는 것이 보편적 추세로 ResourceBundle을 이용 할 수 있다.

ResourceBundle을 사용하면 java.util.Properties 클래스를 이용할 경우 properties 파일의 경로를 가져오고 파일의 내용을 Properties 객체에 저장하는 수고를 줄일 수 있다. 또한 국제화 과정에서의 리소스 관리를 편리하게 할 수 있다.

3. 주요 메소드
static ResourceBundle
  getBundle(String baseName)
주어진 값으로 해당 자원을 가지는 ResourceBundle객체를 만든다.

Object
  getObject(String key)
키값에 해당되는 객체를 반환한다.

String
  getString(String key)
키값에 해당되는 문자열을 반환한다.

4. 사용예
java.util.ResourceBundle resource = java.util.ResourceBundle.getBundle("MyResource");
String jdbc_url = resource.getString("jdbc_url");

위의 간단한 코드는 모든 클래스패스에서 MyResource.properties 파일 등(파일명 검색 규칙은 다음절 참고)이 있는지 찾아서 그 정보를 Resourcebundle 객체(resource)에 저장한다.

JSP 파일에서는 다음과 같은 방법으로 사용 가능하다.

MyResource.properties 파일 등은 WEB-INF/classes 아래나 jar 파일에 위치해야 한다.

(자원파일명 규칙 및 디렉토리는 다음 절을 참조)

<%@ page contentType="text/html;charset=MS949"%>
<%@ page import="java.util.ResourceBundle" %>
<%@ page import="java.util.Enumeration" %>
<%
    ResourceBundle bundle = null;
    try {
        bundle = ResourceBundle.getBundle("MyResource");
        Enumeration enum = bundle.getKeys();
        for (; enum.hasMoreElements(); ) {
            String name = (String)enum.nextElement();
            String value = bundle.getString(name);
            out.println(name + " : " + value);
            out.println("<BR>");
        }
    } catch (Exception e) {
        out.println("Err: "+e.toString());
    }
%>

5. 자원 파일


properties 검색 규칙
properties 파일은 Text 파일이며 ResourceBundle는 다음과 같은 이름의 파일을 검색한다.

<Resource명> "_" language1 "_" country1 "_" variant1
<Resource명>  "_" language1 "_" country1
<Resource명>  "_" language1
<Resource명>  

따라서 다음과 같은 형태의 이름들을 가질 수 있다.

Resource_ko_KR_IBMeucKR.properties
MyResource_ko_KR.properties
MyResource_ko.properties
MyResource_en_US.properties
MyResource_en.properties
MyResource.properties

즉, 자동으로 JVM의 Locale 정보를 찾아서 위 순서대로 프로퍼티 파일을 순차적으로 찾는다.

Locale 옵션을 주지 않으면, Locale.getDefault()를 한다.

System.out.println(Locale.getDefault()) 해 보시면 확인이 가능하며, 이 값은

"file.encoding" 이라는 System Property 값에 의해 영향을 받으며, 이것은 다시

환경변수 "LANG" 값에 영향을 받는다.

이 기능을 이용하여, Locale 값이 무엇이냐에 따라 서로 다른 문자열을 프로그램내에서

제공할 수 있다.

즉, 아래와 같은 서로 다른 이름의 resource 파일을 두게 되면, 영어와 한글 문자열을

Locale 값에 따라 서로 다르게 제공할 수 있다.

MyResource_ko.properties

MyResource_en.properties

MyResource.properties (기타의 경우)


아래의 코드와 같이 명시적으로 로케일 지정도 가능하다.

java.util.Locale locale = new java.util.Locale("ko", "");

java.util.ResourceBundle resource2 = java.util.ResourceBundle.getBundle("MyResource", locale);

String DB_SERVER2 = resource.getString("jdbc_url");

현재 VM의 로케일 확인 다음과 같은 코드로 확인 가능하다.

System.out.println(java.util.Locale.getDefault());

디렉토리 검색 순서
properties 파일을 검색할 때 클래스 패스에 지정된 순으로 검색한다.

만약 CLASSPATH=/usr/local/java/lib;/usr/local/tomcat/lib;./ 와 같이 클래스패스가 설정되어 있을 경우 첫 번째 /usr/local/java/lib에서 찾고 두번 째 /usr/local/tomcat/lib에서 찾고 마지막으로 현재 디렉토리에서 properties 파일을 검색한다. 당연히 먼저 발견되는 properties 파일을 읽어 들인다. properties 파일을 JAR 파일에 포함시켜서 배포도 가능하다.

만약, package 로 구분된 sub directory 에 두었다면, 반드시 full path를 주어야 한다.

ResourceBundle resource = ResourceBundle.getBundle("com.where.somewhere.MyResource");

그리고, MyResource_??_??.properties 파일들은 com/where/somewhere/ 하부 디렉토리에 놓여 있어야 한다.

해당 properties 파일들은 jar 파일 내에 함께 묶어 두어도 된다.

6. properties 포멧
1. key = value_string 으로 기술된다.

2. Comment 는 '#'으로 시작되면 되나, 문자열 중간에 있는 '#'기호는 Comment로

   인식하지 않는다.

3. '=' 대신 ' '(공백)을 사용해도 된다.

   (즉 첫번째 나오는 공백이 key와 vlaue string를 나누는 구실도 한다.

4. 3번의 이유로 인하여 key에는 중간에 공백이 허용되지 않는다.

5. 반면, value string에는 공백이 허용된다.

6. value string를 사용할 때 한글이 지원된다. 그러나 key는 한글지원이 안된다.

7. 두 줄 이상을 사용하려면 라인의 끝에 '\' 문자를 사용하면 된다.

   '\'문자 자체가 필요할 땐 '\' 대신 '\\'을 사용하라.

8. 7번의 이유로 인하여 Windows 환경에서 디렉토리 구분은 '\'가 아니라 '\\' 이다.

7. 기타
한글은 8859_1 캐릭터 셋으로만 읽혀 집니다. 따라서, JVM의 인코딩이 8859_1 이 아니라면, 다음처럼 변환하여야 한다. file.encoding 이 "KSC5601" 이라면,

ResourceBundle resource = ResourceBundle.getBundle("resource.MyResource");

System.out.println(new String(resource.getString("name").getBytes("8859_1"),"KSC5601"));

내부적으로 ClassLoader.getResourceAsStream(filename); 의 형태로 읽혀 들이기 때문이다. 보다 자세한 사항은 해당 클래스의 API 문서와 JDK 소스를 직접 읽어보기 바람. ^^

8. 참고:
1. http://java.sun.com/j2se/1.3/docs/api/java/util/ResourceBundle.html

2. http://blog.naver.com/knbawe.do?Redirect=Log&logNo=100006012503

3. http://blog.naver.com/bumworld.do?Redirect=Log&logNo=140009093610

반응형
댓글
공지사항