java jframe - ResourceBundle을 사용하여 리소스 속성에서 UTF-8을 사용하는 방법




title bar (13)

하나 제안, 내가 자원 번들의 구현을 통해 갔다 ..하지만 도움이되지 않았다 .. 번들은 항상 en_US 로케일 아래에 전화로 ... 나는 다른 언어로 내 기본 로케일을 설정하고 리소스 번들 제어가 en_US ...와 함께 호출되고있었습니다. 로그 메시지를 넣고 디버그를 통해 단계를 수행하고 xhtml 및 JSF 호출을 통해 런타임에 로케일을 변경 한 후에 다른 지역 호출이 작성되었는지 확인하려고했습니다 ... 그 일이 발생하지 않았습니다. ... 다음 시스템 (utcat) 서버에 의해 파일을 읽는 utf8 기본 설정하려고했는데 내 클래스 라이브러리가 utf8에서 컴파일되지 않았고 tomcat이 utf8 형식으로 읽었을 때 pronlem이 발생했습니다. 그리고 서버가 제대로 실행되지 않았다 ... 그럼 내가 내 Java 컨트롤러에서 xhtml 파일에서 호출 할 수있는 메서드를 구현하는 결국 .. 그 방법은 내가 다음 않았다 :

        public String message(String key, boolean toUTF8) throws Throwable{
            String result = "";
            try{
                FacesContext context = FacesContext.getCurrentInstance();
                String message = context.getApplication().getResourceBundle(context, "messages").getString(key);

                result = message==null ? "" : toUTF8 ? new String(message.getBytes("iso8859-1"), "utf-8") : message;
            }catch(Throwable t){}
            return result;
        }

내 응용 프로그램의 성능이 느려질 수로 특히 긴장했다 ... 그러나,이 구현 후 응용 프로그램이 더 빠른 것처럼 보이는 ... 나는 지금은 속성 대신 액세스하는 대신 있기 때문에 나는 생각합니다. JSF는 속성에 액세스하는 방법을 파싱 ... 내가 속성의 일부가 번역되지 않을 것이며 utf8 형식으로있을 필요가 없다는 것을 알고 있기 때문에 나는이 호출에서 부울 인수를 전달한다.

이제 UTF8 형식으로 내 속성 파일을 저장하고 내 응용 프로그램의 각 사용자가 로캘 환경을 참조하도록하여 제대로 작동합니다.

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

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

아무도 내게 모범을 줄 수 있습니까? 나는이 일을 할 수 없다.


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

속성은 InputStream에서 만들 수있는 Reader 객체를 인수로 허용합니다.

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

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

이 Reader를 load 메서드에 적용합니다.

prop.load(isr);

BTW : .properties 파일에서 스트림 가져 오기 :

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

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


설정 / 환경 설정 대화 상자 ( Ctrl + Alt + S )를 연 다음 편집기 및 파일 인코딩을 클릭하십시오.

그런 다음 아래쪽에 속성 파일의 기본 인코딩을 지정합니다. 인코딩 유형을 선택하십시오.

또는 리소스 번들에서 텍스트 대신 유니 코드 기호를 사용할 수 있습니다 (예 : "ів"\u0456\u0432 와 같음)


주의 : Java 속성 파일은 ISO 8859-1로 인코딩되어야합니다!

ISO 8859-1 문자 인코딩. 이 인코딩에서 직접 표현할 수없는 문자는 유니 코드 이스케이프를 사용하여 작성할 수 있습니다. 단일 'u'문자 만 이스케이프 시퀀스에 허용됩니다.

@see Properties 자바 문서

여전히 정말로 이것을하고 싶다면 : 자바 속성 UTF-8 인코딩 (Eclipse) - 코드 샘플이있다.


속성 파일에서 cp1251 charset을 사용하는 경우 UTF-8 및 새로운 String 메서드가있는 ResourceBundle.Control 이 작동하지 않습니다.

그래서 일반적인 방법을 사용하여 권장 : 유니 코드 기호로 작성하십시오. 이것을 위해 :

IDEA - 특별한 " 투명한 네이티브 - ASCII 변환 " 옵션 (설정> 파일 인코딩)이 있습니다.

Eclipse - 플러그인 " Properties Editor "가 있습니다. 그것은 별도의 응용 프로그램으로 작동 할 수 있습니다.


Properties prop = new Properties();
String fileName = "./src/test/resources/predefined.properties";
FileInputStream inputStream = new FileInputStream(fileName);
InputStreamReader reader = new InputStreamReader(inputStream,"UTF-8");

ResourceBundle의 인스턴스가 있고 String을 다음과 같이 얻을 수 있습니다.

String val = bundle.getString(key); 

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

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

ResourceBundle#getBundle().properties 파일이 지정 될 때 PropertyResourceBundle 커버를 사용합니다. 이 Properties#load(InputStream) 은 기본적으로 Properties#load(InputStream) 를 사용하여 해당 속성 파일을로드합니다. Properties#load(InputStream) , 그들은 기본적으로 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 -encoding UTF-8 text_utf8.properties text.properties

Eclipse와 같은 정상적인 IDE를 사용할 때 이것은 Java 기반 프로젝트에서 .properties 파일을 만들고 Eclipse의 자체 편집기를 사용할 때 이미 자동으로 수행됩니다. Eclipse는 ISO-8859-1 범위를 벗어나는 문자를 투명하게 \uXXXX 형식으로 변환합니다. 스크린 샷 (하단의 "속성"및 "소스"탭을 참고하십시오. 큰 것을 보려면 아래 참조)도 참조하십시오.

또는 InputStreamReader 사용하여 속성 파일을 명시 적으로 읽는 사용자 정의 ResourceBundle.Control 구현을 만들 수도 있습니다. 그러면 native2ascii 로 번거 로움없이 UTF-8로 저장할 수 있습니다. 다음은 킥오프 예제입니다.

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());

참조 :


Guava의 뛰어난 지원 라이브러리와 try-with-resources 구조를 사용하는 Java 7 솔루션이 있습니다. 가장 단순한 전반적인 경험을 위해 UTF-8을 사용하여 속성 파일을 읽고 씁니다.

속성 파일을 UTF-8로 읽으려면 다음과 같이하십시오.

File file =  new File("/path/to/example.properties");

// Create an empty set of properties
Properties properties = new Properties();

if (file.exists()) {

  // Use a UTF-8 reader from Guava
  try (Reader reader = Files.newReader(file, Charsets.UTF_8)) {
    properties.load(reader);
  } catch (IOException e) {
    // Do something
  }
}

UTF-8로 특성 파일을 작성하려면 다음을 수행하십시오.

File file =  new File("/path/to/example.properties");

// Use a UTF-8 writer from Guava
try (Writer writer = Files.newWriter(file, Charsets.UTF_8)) {
  properties.store(writer, "Your title here");
  writer.flush();
} catch (IOException e) {
  // Do something
}

내 문제가 가치있는 일은 파일 자체가 잘못된 인코딩에 있다는 것입니다. 나를 위해 일한 iconv 사용하기

iconv -f ISO-8859-15 -t UTF-8  messages_nl.properties > messages_nl.properties.new

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 <[email protected]> 
 */  
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);  
            }  
        }  
    }  
}  

이 문제는 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 Runtime는 ISO-8859-1에있는 파일을 자동적으로 읽어들입니다.


필요한 것보다 오랫동안 물건을 잡고 있는지 알아야합니다. 첫 번째 단계는 사례에 대한 프로파일 러를 가져 와서 힙을보고 오브젝트가 수집되지 않는 이유를 확인하는 것입니다.

JVM 1GB를 제공했지만, 많은 개체가 매우 빨리 생성되어 너무 빨리 제거되지 않는 오래된 세대로 강제로 보내지면 젊은 세대가 너무 작을 수 있습니다.

GC 튜닝에 대한 유용한 정보 : tune





java google-app-engine utf-8 internationalization resourcebundle