[java] ResourceBundle을 사용하여 자원 등록 정보에서 UTF-8을 사용하는 방법

Java를 사용하여 리소스 속성에 UTF-8을 사용해야 ResourceBundle합니다. 텍스트를 속성 파일에 직접 입력하면 mojibake로 표시됩니다.

내 앱은 Google App Engine에서 실행됩니다.

누구든지 예를 들어 줄 수 있습니까? 이 작품을 얻을 수 없습니다.



답변

ResourceBundle#getBundle()내부적으로 사용이 PropertyResourceBundle.properties파일이 지정됩니다. 이는 기본적 Properties#load(InputStream)으로 해당 특성 파일을로드하는 데 사용됩니다 . 당으로 javadoc에 , 그들은 ISO-8859-1과 같은 기본 읽기에 의해입니다.

public void load(InputStream inStream) throws IOException

입력 바이트 스트림에서 속성 목록 (키 및 요소 쌍)을 읽습니다. 입력 스트림은 load (Reader)에 지정된 간단한 행 지향 형식 이며 ISO 8859-1 문자 인코딩을 사용하는 것으로 가정합니다 . 즉, 각 바이트는 하나의 Latin1 문자입니다. Latin1이 아닌 문자 및 특정 특수 문자는 Java ™ 언어 스펙의 3.3 절에 정의 된대로 유니 코드 이스케이프를 사용하여 키 및 요소로 표시됩니다.

따라서 ISO-8859-1로 저장해야합니다. ISO-8859-1 범위를 벗어난 문자가 있고 \uXXXX맨 위를 사용할 수 없으므로 파일을 UTF-8로 저장 해야하는 경우 native2ascii 도구를 사용하여 UTF-8 저장 특성 파일을 ISO-8859-1 저장 특성 파일로 저장하십시오 (여기서 덮지 않은 모든 문자는 \uXXXX형식으로 변환 됨) 아래 예제는 UTF-8로 인코딩 된 속성 파일 text_utf8.properties을 유효한 ISO-8859-1로 인코딩 된 속성 파일로 변환합니다 text.properties.

native2ascii-인코딩 UTF-8 text_utf8.properties text.properties

Eclipse와 같은 정상 IDE를 사용하는 경우 .propertiesJava 기반 프로젝트에서 파일 을 작성하고 Eclipse 자체 편집기를 사용 하면 이미 자동으로 수행됩니다 . Eclipse는 ISO-8859-1 범위를 벗어난 문자를 \uXXXX형식으로 투명하게 변환 합니다. 아래 스크린 샷도 참조하십시오 (아래의 “속성”및 “소스”탭 참조).

"속성"탭 "소스"탭

또는을 사용 ResourceBundle.Control하여 속성 파일을 UTF-8로 명시 적으로 읽는 사용자 정의 구현을 작성 InputStreamReader하여 번거 로움없이 UTF-8로 저장할 수 있습니다 native2ascii. 시작 예는 다음과 같습니다.

public class UTF8Control extends Control {
    public ResourceBundle newBundle
        (String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
            throws IllegalAccessException, InstantiationException, IOException
    {
        // The below is a copy of the default implementation.
        String bundleName = toBundleName(baseName, locale);
        String resourceName = toResourceName(bundleName, "properties");
        ResourceBundle bundle = null;
        InputStream stream = null;
        if (reload) {
            URL url = loader.getResource(resourceName);
            if (url != null) {
                URLConnection connection = url.openConnection();
                if (connection != null) {
                    connection.setUseCaches(false);
                    stream = connection.getInputStream();
                }
            }
        } else {
            stream = loader.getResourceAsStream(resourceName);
        }
        if (stream != null) {
            try {
                // Only this line is changed to make it to read properties files as UTF-8.
                bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
            } finally {
                stream.close();
            }
        }
        return bundle;
    }
}

다음과 같이 사용할 수 있습니다.

ResourceBundle bundle = ResourceBundle.getBundle("com.example.i18n.text", new UTF8Control());

또한보십시오:


답변

ResourceBundle의 인스턴스가 있고 다음을 통해 String을 얻을 수 있다고 가정합니다.

String val = bundle.getString(key); 

일본어 디스플레이 문제를 다음과 같이 해결했습니다.

return new String(val.getBytes("ISO-8859-1"), "UTF-8");


답변

이것을보십시오 : http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html#load(java.io.Reader)

이 속성은 Reader 개체를 인수로 허용 하며 InputStream에서 만들 수 있습니다.

작성시 리더의 인코딩을 지정할 수 있습니다.

InputStreamReader isr = new InputStreamReader(stream, "UTF-8");

그런 다음이 리더를로드 방법에 적용하십시오.

prop.load(isr);

BTW : .properties 파일 에서 스트림을 가져옵니다 .

 InputStream stream = this.class.getClassLoader().getResourceAsStream("a.properties");

BTW : 다음 에서 리소스 번들 가져 오기 InputStreamReader:

ResourceBundle rb = new PropertyResourceBundle(isr);

이것이 당신을 도울 수 있기를 바랍니다!


답변

ResourceBundle.Control 예를 들어 속성 ​​파일이 cp1251 문자 세트를 사용하는 경우 UTF-8 및 새로운 문자열 메소드가 작동하지 않습니다.

그래서 나는 일반적인 방법 으로 유니 코드 기호로 쓰는 것이 좋습니다. 이를 위해 :

IDEA는 – 특별한있다 투명 기본 – 투 – ASCII 변환 옵션 (설정> 파일 인코딩).

Eclipse – 플러그인 속성 편집기 “가 있습니다. 별도의 응용 프로그램으로 작동 할 수 있습니다.


답변

이 문제는 마침내 Java 9에서 수정되었습니다.
https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9

특성 파일의 기본 인코딩은 이제 UTF-8입니다.

UTF-8과 ISO-8859-1은 ASCII 문자에 대해 동일한 인코딩을 가지며 사람이 읽을 수있는 비 ASCII ISO-8859-1 인코딩은 유효한 UTF-8이 아닙니다. 유효하지 않은 UTF-8 바이트 시퀀스가 ​​감지되면 Java 런타임은 ISO-8859-1의 파일을 자동으로 다시 읽습니다.


답변

자원을 UTF-8로 포함하는 resources.utf8 파일을 작성하고 다음을 실행하는 규칙이 있습니다.

native2ascii -encoding utf8 resources.utf8 resources.properties


답변

package com.varaneckas.utils;

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

/**
 * UTF-8 friendly ResourceBundle support
 *
 * Utility that allows having multi-byte characters inside java .property files.
 * It removes the need for Sun's native2ascii application, you can simply have
 * UTF-8 encoded editable .property files.
 *
 * Use:
 * ResourceBundle bundle = Utf8ResourceBundle.getBundle("bundle_name");
 *
 * @author Tomas Varaneckas <tomas.varaneckas@gmail.com>
 */
public abstract class Utf8ResourceBundle {

    /**
     * Gets the unicode friendly resource bundle
     *
     * @param baseName
     * @see ResourceBundle#getBundle(String)
     * @return Unicode friendly resource bundle
     */
    public static final ResourceBundle getBundle(final String baseName) {
        return createUtf8PropertyResourceBundle(
                ResourceBundle.getBundle(baseName));
    }

    /**
     * Creates unicode friendly {@link PropertyResourceBundle} if possible.
     *
     * @param bundle
     * @return Unicode friendly property resource bundle
     */
    private static ResourceBundle createUtf8PropertyResourceBundle(
            final ResourceBundle bundle) {
        if (!(bundle instanceof PropertyResourceBundle)) {
            return bundle;
        }
        return new Utf8PropertyResourceBundle((PropertyResourceBundle) bundle);
    }

    /**
     * Resource Bundle that does the hard work
     */
    private static class Utf8PropertyResourceBundle extends ResourceBundle {

        /**
         * Bundle with unicode data
         */
        private final PropertyResourceBundle bundle;

        /**
         * Initializing constructor
         *
         * @param bundle
         */
        private Utf8PropertyResourceBundle(final PropertyResourceBundle bundle) {
            this.bundle = bundle;
        }

        @Override
        @SuppressWarnings("unchecked")
        public Enumeration getKeys() {
            return bundle.getKeys();
        }

        @Override
        protected Object handleGetObject(final String key) {
            final String value = bundle.getString(key);
            if (value == null)
                return null;
            try {
                return new String(value.getBytes("ISO-8859-1"), "UTF-8");
            } catch (final UnsupportedEncodingException e) {
                throw new RuntimeException("Encoding not supported", e);
            }
        }
    }
}