0

この主題は多くの議論の対象となっていますが、まだ新しい議論が見られます。私のシナリオは次のとおりです。

UTF-8 が JVM のデフォルトの文字エンコーディングである Linux サーバー上で実行される Java フレームワーク。このフレームワークは、処理対象の Tibco RV メッセージを受信するいくつかのサービスで構成されています。また、これらのメッセージの一部には非 ASCII 文字が含まれており、Windows サーバーから送信されます。メッセージの作成時に使用されるエンコーディングは ISO8859-1 です。さて、データが Tib rv メッセージから抽出されると、問題のあるフィールドが Java オブジェクトとして「到着」し、文字列にキャストする必要があります...そして、ここでは、非を含む ISO8859-1 文字列をまだ抽出できていませんASCII 文字 (スウェーデン語の「å」、「ä」、「ö」) を適切な方法で UTF-8 文字列に変換します。次の方法を使用してみました。

String isoStreet = new String(response.get("street").toString().getBytes(StandardCharsets.ISO_8859_1),java.nio.charset.StandardCharsets.UTF_8);

また、java.nio パッケージ内のエンコーダー/デコーダーを使用してみましたが、成功しませんでした。

また興味深いのは、PuttY を使用して、サービスがホストされ実行されているサーバーに接続していることです。そしてそこから、(tibcorvsend クライアントを使用して) シェルから直接 Tibco rv 要求を行う可能性があり、サインインする前に PuttY (Window_>Translation) でリモート文字セットを ISO8859-1 に設定する必要があるようです。サーバーとそのTib rvリクエストを作成します-これが完了すると、リモートLinuxサーバーで設定したエンコーディングに関係なく、ASCII以外の文字が応答で正しく表示されます。この場合、「export LC_ALL=en_US.UTF-8」または「export LC_ALL=sv_SE.iso88591」の使用は問題ではありません... PuttY で設定したリモートエンコーディングのみ...

これは、応答メッセージが正常であるように見え、少なくともシェルが適切な文字を出力できることを意味するはずです。しかし、Java VM 内で (Java サービスを使用して) 応答オブジェクトをデバッグして表示するときに (この文字列への変換を望んでいない)、応答フィールドが静かに文字列にプッシュされていると思います (この文字列への変換は望ましくありません)。 、そうでない場合は、必要に応じてより明確にしようとするかもしれません...

この問題に関するご意見、どなたでも

よろしく /R

4

1 に答える 1

1

文字エンコーディングは、文字で構成されるテキストをバイトに、またはその逆に変換する方法を指定します。ご存じのように、ASCII、ISO-8859-1、UTF-8 など、さまざまな文字エンコーディングがあります。

文字列は文字で構成されます。ある時点で、これらの文字をバイトに変換して、ネットワーク経由で送信したり、ファイルに保存したり、やりたいことが何でもできるようにしたいことがあります。文字エンコーディングを使用して、文字列をバイトに変換します。そして、バイトを受け取る反対側では、同じ文字エンコーディングを使用して、バイトを文字列内の文字に変換します。

あなたが投稿したような行が間違っている理由を見てみましょう。部分を説明できるように、最初に書き直しましょう。

String street = response.get("street").toString();
byte[] streetBytes = street.getBytes(StandardCharsets.ISO_8859_1);
String isoStreet = new String(streetBytes, StandardCharsets.UTF_8);

最初の行では、応答からいくつかのデータを取得し、それを文字列に変換します。(何をresponse.get("street")返しますか?)。

2 行目では、ISO-8859-1 文字セットを使用してその文字列をエンコードします。文字列内の文字の有効な ISO-8859-1 文字コードを含むバイト配列を取得します。

3 行目では、バイトを文字列に変換し、そのバイトが UTF-8 バイトであるかのように見せかけています。バイトは ISO-8859-1 データであり、UTF-8 データではないため、これは明らかに間違っています。これを行うと、間違った文字が返されたり、UTF-8 では有効な文字ではないバイト シーケンスがバイト配列に含まれている場合は例外が発生したりする可能性があります。

注意すべきことの 1 つは、文字列は文字だけで構成されているということです。文字列自体にはエンコーディングはありません。文字エンコーディングを使用して、文字列をバイトに、またはその逆に変換します。文字エンコーディングは単に文字列のプロパティではないため、「文字列の文字エンコーディングを変更する」ことはできません。数値が本質的に 10 進数でも 16 進数でもないのと同じように、これらは同じ数値を表す別の方法です。

あなたがしなければならないことは次のとおりです。

  • メッセージを書き込む時点で、正しい文字エンコーディングを使用して文字列をバイトに変換していることを確認してください。

  • メッセージを読む時点で、正しい文字エンコーディングを使用してバイトを文字列に変換していることを確認してください。

プラットフォームのデフォルトの文字エンコーディングを使用して何かを文字列に読み取ってから、「文字列を変換」しようとしないでください。それはうまくいきません。

于 2015-02-12T14:15:59.733 に答える