web-dev-qa-db-ja.com

UTF-8エンコーディング;一部の日本語文字のみが変換されていません

Jersey Web Serviceからパラメーター値をパラメーターとして取得しています。これは日本語の文字です。

ここで、'japaneseString'は、日本語の文字を含むWebサービスパラメータです。

   String name = new String(japaneseString.getBytes(), "UTF-8");

ただし、いくつかのstingリテラルを正常に変換することはできますが、それらのいくつかは問題を引き起こしています。

以下は正常に変換されました。

 1) アップル
 2) 赤
 3) 世丕且且世两上与丑万丣丕且丗丕
 4) 世世丗丈

これらはそうではありませんが:

 1) ひほわれよう
 2) 存在する

さらに調べてみると、これら2つの文字列がいくつかのJUNK文字に変換されていることがわかりました。

 1) Input: ひほわれよう        Output : �?��?��?れよ�?�
 2) Input: 存在する            Output: 存在�?�る

一部の日本語の文字が正しく変換されない理由は何ですか?

ありがとう。

8
Janak

Tomcat(JVM)の起動時に、JVMパラメータfile.encodingで値UTF-8を設定してみてください。 E.x。:-Dfile.encoding = UTF-8

4
Nitul

ここでは概念を混ぜ合わせています。

Stringは単なる文字のシーケンス(chars)です。 String自体にはエンコードがまったくありません。その価値については、上記のcharactersを_carrier pigeons_に置き換えてください。同じこと。伝書鳩にはエンコーディングがありません。 charも同様です。 (1)

あなたがここでしていること:

_new String(x.getBytes(), "UTF-8")
_

「貧乏人のエンコード/デコードプロセス」です。 .getBytes()には2つのバージョンがあることに気付いたでしょう。1つは引数として文字セットを渡すもので、もう1つは渡さないものです。

そうしないと、それがここで発生することです。つまり、デフォルト文字セットを使用してエンコードプロセスの結果が得られます。次に、UTF-8を使用してこのバイトシーケンスを再デコードします。

そうしないでください。それが来るようにちょうどストリングを取りなさい。ただし、元のバイトストリームを文字列に読み込むのに問題がある場合は、間違った文字セットでReaderを使用していることを意味します。修正それ部分。

詳細については、 このリンク を参照してください。

(1)実際、charがUTF-16コード単位であるという事実は、この議論とは無関係です。

9
fge

@fgeに同意します。

説明

Java String/char/Reader/Writerハンドル(Unicode)テキストで、世界中のすべてのスクリプトを組み合わせることができます。

また、byte[]/InputStream/OutputStreamはバイナリデータであり、文字列に変換するにはエンコードを指定する必要があります。

あなたの場合、japaneseStingrはすでに正しい文字列であるか、元のbyte[]に置き換えられているはずです。

Javaでのトラップ

多くの場合、エンコーディングはオプションのパラメータであり、デフォルトでプラットフォームエンコーディングになります。あなたもその罠に陥った:

String s = "...";
byte[] b = s.getBytes(); // Platform encoding, non-portable.
byte[] b = s.getBytes("UTF-8"); // Explicit
byte[] b = s.getBytes(StandardCharsets.UTF_8); // Explicit,
                         //  better (for UTF-8, ISO-8859-1)

一般に、エンコーディングパラメータなしのオーバーロードされたメソッドは避けてください。これらは、現在のコンピュータのみのデータ用なので、移植できません。完全を期すために:クラスFileReader/FileWriterは、エンコーディングパラメータを提供しないため、避ける必要があります。

エラー

japaneseStringはすでに間違っています。だからあなたはその権利を読まなければなりません。 Windows-1252(Windows Latin-1)として誤って読み取られ、UTF-8に再コーディングするときに問題が発生した可能性があります。明らかにいくつかのケースだけがめちゃくちゃになります。

多分あなたは持っていた:

String japanesString = new String(bytes);

の代わりに:

String japanesString = new String(bytes, StandardCharsets.UTF_8);

最後に:

String name = japaneseString;

さらにヘルプが必要な場合は、japaneseStringを読み取るコードを表示します。

2
Joop Eggen