私はJavaのResourceBundle
を使って私のリソースプロパティでUTF-8を使う必要があります。プロパティファイルに直接テキストを入力すると、mojibakeと表示されます。
私のアプリはGoogle App Engine上で動作します。
誰かが私に例をあげてもらえますか?私はこの仕事を手に入れることができません。
ResourceBundle#getBundle()
は、.properties
ファイルが指定されている場合に PropertyResourceBundle
を使用してカバーします。これは、デフォルトで 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-エンコードUTF-8 text_utf8.properties text.properties
Eclipseなどの健全なIDEを使用する場合、Javaベースのプロジェクトで.properties
ファイルを作成し、Eclipse独自のエディターを使用すると、これは既に自動的に行われます。 Eclipseは、ISO-8859-1の範囲を超える文字を透過的に\uXXXX
形式に変換します。以下のスクリーンショットも参照してください(下部の[プロパティ]タブと[ソース]タブに注意してください。クリックすると大きくなります)。
または、カスタムの ResourceBundle.Control
実装を作成することもできます。この実装では、 InputStreamReader
を使用してUTF-8としてプロパティファイルを明示的に読み取り、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から作成できます。
作成時に、Readerのエンコーディングを指定できます。
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);
これがお役に立てば幸いです。
たとえば、プロパティファイルがcp1251文字セットを使用している場合、UTF-8のResourceBundle.Control
および新しいStringメソッドは機能しません。
だから私は一般的な方法を使用することをお勧めします:Unicode記号で書きます。このため:
IDEA - 特別な " 透明なネイティブからASCIIへの変換 "オプション([設定]> [ファイルエンコーディング])。
Eclipse - プラグインがあります " Properties Editor "。それは別々のアプリケーションとして動作することができます。
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);
}
}
}
}
UTF-8のリソースを含むresources.utf8ファイルを作成し、以下を実行するための規則を設定します。
native2ascii -encoding utf8 resources.utf8 resources.properties
この問題はついに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のファイルを再読み込みします。
注意:JavaプロパティファイルはISO 8859-1でエンコードする必要があります。
ISO 8859-1文字エンコードこのエンコーディングで直接表現できない文字は、Unicodeエスケープを使って書くことができます。エスケープシーケンスに使用できるのは、単一の「u」文字だけです。
@seeプロパティJava Doc
それでもこれをやりたいのであれば、以下を見てください。 EclipseでのJavaプロパティーUTF-8エンコード - いくつかのコード・サンプルがあります
http://sourceforge.net/projects/Eclipse-rbe/
既に述べたように、プロパティファイルはISO 8859-1でエンコードされるべきです。
あなたはあなたのためにUnicode変換をするためにEclipse IDEのための上記のプラグインを使うことができます。
これは、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
}
ある人が示唆したように、私はリソースバンドルの実装を経験しました..しかしバンドルはen_USロケールの下でいつも呼ばれていたのでそれは助けになりませんでした。コントロールがen_USで呼び出されていました...ログメッセージを書き込もうとし、デバッグのステップを実行し、実行時にxhtmlおよびJSF呼び出しでロケールを変更した後に別のローカル呼び出しが行われていないか...それから私は私のサーバー(Tomcatサーバー)でファイルを読むためにutf8にシステムセットデフォルトをしようとしました..しかしそれはすべての私のクラスライブラリがutf8の下でコンパイルされなかったのでTomlecatは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
設定/設定ダイアログを開きます(Ctrl + Alt + S)をクリックしてから、「エディタとファイルのエンコード」をクリックします。
次に、一番下に、プロパティファイルのデフォルトのエンコーディングを入力します。エンコードの種類を選択してください。
あるいは、リソースバンドルでテキストの代わりにUnicodeのシンボルを使用することもできます(たとえば、"ів"
は\u0456\u0432
と等しくなります)。
私は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");