Java를 사용하여 리소스 속성에 UTF-8을 사용해야 ResourceBundle
합니다. 텍스트를 속성 파일에 직접 입력하면 mojibake로 표시됩니다.
내 앱은 Google App Engine에서 실행됩니다.
누구든지 예를 들어 줄 수 있습니까? 이 작품을 얻을 수 없습니다.
java.util.ResourceBundle
아닌 님을 통해 읽는 것에 관한 것 java.util.Properties
입니다.
Java를 사용하여 리소스 속성에 UTF-8을 사용해야 ResourceBundle
합니다. 텍스트를 속성 파일에 직접 입력하면 mojibake로 표시됩니다.
내 앱은 Google App Engine에서 실행됩니다.
누구든지 예를 들어 줄 수 있습니까? 이 작품을 얻을 수 없습니다.
java.util.ResourceBundle
아닌 님을 통해 읽는 것에 관한 것 java.util.Properties
입니다.
답변:
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를 사용하는 경우 .properties
Java 기반 프로젝트에서 파일 을 작성하고 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());
StandardCharsets.UTF_8
Java 7 이상 을 사용하는 경우 주저하지 말고
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
입니다.
Properties
하고 있고 UTF-8
문자열 을 검색하고 싶다면 이것이 받아 들여야 합니다. 이것은 매력처럼 작동합니다. 그러나 ResourceBundle
언어 자원과 같은 경우 허용되는 대답은 우아합니다. 그럼에도 불구하고 대답이 투표되었습니다.
ResourceBundle rb = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"))
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
native2ascii
에서 얻 습니까? 방금 find / -name native2ascii*
결과를
jdk1.*.0_*/bin
.
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);
}
}
}
}
주의 : java 특성 파일은 ISO 8859-1로 인코딩해야합니다!
ISO 8859-1 문자 인코딩 이 인코딩에서 직접 표현할 수없는 문자는 유니 코드 이스케이프를 사용하여 작성할 수 있습니다. 이스케이프 시퀀스에는 단일 'u'문자 만 허용됩니다.
@ 참조 속성 Java Doc
여전히 정말로하고 싶다면 : Eclipse의 Java 속성 UTF-8 인코딩을 살펴보십시오. 일부 코드 샘플이 있습니다.
http://sourceforge.net/projects/eclipse-rbe/
이미 언급 한 것처럼 속성 파일은 ISO 8859-1로 인코딩해야합니다
Eclipse IDE 용 위 플러그인을 사용하여 유니 코드 변환을 수행 할 수 있습니다.
다음은 Guava의 우수한 지원 라이브러리 및 리소스와 함께 사용하는 구성을 사용하는 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
}
제안한 것처럼 리소스 번들의 구현을 겪었지만 도움이되지 않았습니다. 번들이 항상 en_US 로캘에서 호출되었으므로 기본 로캘을 다른 언어로 설정하고 여전히 리소스 번들의 구현을 시도했습니다. 제어가 en_US로 호출되었습니다 ... 로그 메시지를 넣고 디버그를 통해 단계를 시도했으며 xhtml 및 JSF 호출을 통해 런타임에 로케일을 변경 한 후 다른 로컬 호출이 수행되었는지 확인했습니다 ... ... 그런 다음 서버 (tomcat 서버)가 파일을 읽을 수 있도록 시스템 설정 기본값을 utf8로 설정하려고 시도했지만 모든 클래스 라이브러리가 utf8에서 컴파일되지 않고 Tomcat이 utf8 형식으로 읽히기 시작했을 때 문제가 발생했습니다. 서버가 제대로 실행되지 않았습니다 ... 그런 다음 xhtml 파일에서 호출 할 Java 컨트롤러의 메소드를 구현했습니다.그 방법으로 다음을 수행했습니다.
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 형식으로 저장했으며 응용 프로그램의 각 사용자에게 참조 로캘 기본 설정이 있으므로 정상적으로 작동합니다.
Properties prop = new Properties();
String fileName = "./src/test/resources/predefined.properties";
FileInputStream inputStream = new FileInputStream(fileName);
InputStreamReader reader = new InputStreamReader(inputStream,"UTF-8");
내 문제의 가치는 파일 자체의 인코딩이 잘못되었다는 것입니다. iconv를 사용하면 나를 위해 일했습니다.
iconv -f ISO-8859-15 -t UTF-8 messages_nl.properties > messages_nl.properties.new
iconv
. 내가 전에 들어 본 적이 있지만 콘솔로 입력 한 보라와 보라, 그것은 존재하는 일이다 (어쨌든,에 CentOS 6.)
Rod가 제공 한 접근 방식을 사용하려고했지만 모든 응용 프로그램에서 동일한 해결 방법을 반복하지 않는 BalusC 우려를 고려 하고이 클래스와 함께 제공되었습니다.
import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.ResourceBundle;
public class MyResourceBundle {
// feature variables
private ResourceBundle bundle;
private String fileEncoding;
public MyResourceBundle(Locale locale, String fileEncoding){
this.bundle = ResourceBundle.getBundle("com.app.Bundle", locale);
this.fileEncoding = fileEncoding;
}
public MyResourceBundle(Locale locale){
this(locale, "UTF-8");
}
public String getString(String key){
String value = bundle.getString(key);
try {
return new String(value.getBytes("ISO-8859-1"), fileEncoding);
} catch (UnsupportedEncodingException e) {
return value;
}
}
}
이것을 사용하는 방법은 일반적인 ResourceBundle 사용법과 매우 유사합니다.
private MyResourceBundle labels = new MyResourceBundle("es", "UTF-8");
String label = labels.getString(key)
또는 기본적으로 UTF-8을 사용하는 대체 생성자를 사용할 수 있습니다.
private MyResourceBundle labels = new MyResourceBundle("es");
설정 / 기본 설정 대화 상자 ( Ctrl+ Alt+ S)를 연 다음 편집기 및 파일 인코딩을 클릭하십시오.
그런 다음 하단에 속성 파일의 기본 인코딩을 핑합니다. 인코딩 유형을 선택하십시오.
또는 자원 번들에서 텍스트 대신 유니 코드 기호를 사용할 수 있습니다 (예 : "ів"
equals \u0456\u0432
)
Java 9부터 특성 파일을로드하기위한 기본값이 UTF-8로 변경되었습니다. https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9.htm