0

IIS サーバーに HTTP 要求を行う Java アプリケーションでエンコードの問題が発生しています。

URLConnectionオブジェクトのヘッダーを繰り返し処理すると、次の (関連する) ヘッダーが表示されます。

Transfer-Encoding: [chunked]
Content-Encoding: [utf-8]
Content-Type: [text/html; charset=utf-8]

このURLConnection.getContentEncoding()メソッドは、ドキュメントのエンコーディングとして utf-8 を返します。

これは私のHTTPリクエストとストリームの読み取りが行われている方法です:

OutputStreamWriter sw = null;
BufferedReader br = null;
char[] buffer = null;
URL url;
url = new URL(this.URL);
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
sw = new OutputStreamWriter(connection.getOutputStream());
sw.write(postData);
sw.flush();
br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF8"));
StringBuilder totalResponse = new StringBuilder();
String line;

while((line = br.readLine()) != null) {
    totalResponse.append(line);
}
buffer = totalResponse.toString().toCharArray();
if (sw != null)
    sw.close();

if (br != null)
    br.close();

return buffer;

ただし、サーバーから送信された次の文字列「ããção」は、クライアントによって「�����o」として受信されます。

私は何を間違っていますか?

4

4 に答える 4

1

コメントに基づいて、IIS サーバーから FIX メッセージを受信しようとしており、FIX は ASCII を使用しています。他のエンコーディングをサポートするタグの小さなサブセットのみがあり、特別な方法で処理する必要があります (標準 FIX 仕様の非 ASCII タグは 349,351,353,355,357,359,361,363,365 です)。そのようなタグが存在する場合、エンコーディング (UTF-8 など) を指定する値を持つタグ 347 を取得し、各タグの前に、次のエンコードされた値の長さを示すタグが続きます (タグ 349 の場合、整数値で常に最初に 348 を取得します)

あなたの場合、サーバーがカスタム タグ 10411 (10xxx 範囲) を他のエンコーディングで送信しているようです。慣例により、前のタグ 10410 は 10411 の値の長さを示すはずですが、代わりに「0000」が含まれており、これには別の意味がある場合があります。

FIX メッセージは非常に読みやすいですが、バイナリ データとして扱う必要があることに注意してください。タグと値はほとんどが ASCII 文字ですが、区切り文字 (SOH) は 0x01 であり、前述のように、特定のタグは別のエンコーディングでエンコードされる場合があります。IIS サービスは、application/octet-stream適切に受信できるように、実際にデータを返す必要があります。text/htmlトラブルを求めているようにそれを返そうとしています:)。

于 2014-10-03T05:28:04.667 に答える
0

正しい順序で、いくつかの修正を行います。

    URLConnection connection = url.openConnection();
    connection.setDoOutput(true);
    connection.connect();
    try (Writer sw = new OutputStreamWriter(connection.getOutputStream(),
                StandardCharsets.UTF_8)) {
        sw.write(postData);
        sw.flush();

        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(connection.getInputStream(),
                StandardCharsets.UTF_8))) {
            StringBuilder totalResponse = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                totalResponse.append(line).append("\r\n");
            }
            return totalResponse.toString().toCharArray();
        } // Close br.
    } // Close sw.

多分:

postData =  ... + "Accept-Charset: utf-8\r\n" + ...;

受け取っtotalResponse.toString()たら、すべて正しく読んでいる必要があります。

しかし、再度表示すると、文字列/文字が再びバイトに変換され、エンコードが失敗しますたとえば、おそらく Windows エンコーディングが使用されているため、 System.out.println は機能しません。

バイトをダンプすることで文字列をテストできます。

String s = totalResponse.toString();
Logger.getLogger(getClass().getName()).log(Level.INFORMATION, "{0}",
    Arrays.toString(s.getBytes(StandardCharsets.UTF_8)));

まれに、フォントに特殊文字が含まれていないことがあります。

于 2014-10-02T12:11:48.287 に答える
0

サーバーが実際に「UTF-8」の Content-Encoding を送信する場合、サーバーは非常に混乱します。http://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7231.html#header.content-encodingを参照してください。

于 2014-10-02T11:32:13.843 に答える
0

ストリームをリクエスト属性の一部として配置し、クライアント側で出力してみてください。リクエスト属性は、エンコードの問題なしでそのまま受信されます

于 2014-10-07T06:22:51.980 に答える