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文字エンコードを使用すると想定されています。つまり、各バイトは1つのLatin1文字です。Latin1にない文字と特定の特殊文字は、Java™言語仕様のセクション3.3で定義されているように、Unicodeエスケープを使用してキーと要素で表されます。
したがって、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を使用する場合.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");
次に、このReaderをloadメソッドに適用します。
prop.load(isr);
ところで:.propertiesファイルからストリームを取得します:
InputStream stream = this.class.getClassLoader().getResourceAsStream("a.properties");
ところで:からリソースバンドルを取得します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と新しいStringメソッドは機能しません。
だから私は一般的な方法を使用することをお勧めしました:ユニコード記号で書く。このため:
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*
私はそれが... JDKのほんの一部ではないと仮定して、そして何の結果を得ていない
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文字エンコード。このエンコーディングで直接表現できない文字は、Unicodeエスケープを使用して記述できます。エスケープシーケンスでは1つの「u」文字のみが許可されます。
@seeプロパティJavaドキュメント
それでも本当にこれを実行したい場合: EclipseでのJavaプロパティUTF-8エンコーディング -いくつかのコードサンプルがあります
http://sourceforge.net/projects/eclipse-rbe/
すでに述べたように、プロパティファイルはISO 8859-1でエンコードする必要があります。
Eclipse IDEの上記のプラグインを使用して、Unicode変換を行うことができます。
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
}
1つ示唆されたように、リソースバンドルの実装を行いましたが、それは役に立ちませんでした。バンドルは常にen_USロケールで呼び出されたためです...デフォルトのロケールを別の言語に設定しようとしましたが、まだリソースバンドルの実装を試みましたen_USでコントロールが呼び出されました...ログメッセージを出力してデバッグのステップを実行し、xhtmlおよびJSF呼び出しを介して実行時にロケールを変更した後に別のローカル呼び出しが行われているかどうかを確認しようとしました...発生しませんでした...次に、サーバー(tomcatサーバー)でファイルを読み取るためにシステムをデフォルトでutf8に設定しようとしましたが、すべてのクラスライブラリがutf8でコンパイルされておらず、tomcatがutf8形式で読み取っていたため、問題が発生しましたそしてサーバーが適切に実行されていなかった...その後、私は私のhtmlコントローラーに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形式で保存しましたが、アプリケーションの各ユーザーが参照ロケール設定を持っているため、問題なく機能しています。
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)を開き、「エディターとファイルのエンコーディング」をクリックします。
次に、下部で、プロパティファイルのデフォルトのエンコーディングを指定します。エンコーディングタイプを選択します。
または、リソースバンドルでテキストの代わりにUnicode記号を使用することもできます(たとえば、"ів"
equals \u0456\u0432
)
Java 9から、プロパティファイルをロードするデフォルトがUTF-8に変更されました。https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9.htm