3

HttpURLConnection (Java 1.6 から) と Jetty (6.1.26) を使用して、xml のブロックをリクエストとして POST し、xml のブロックを応答として受け取る自家製のプロトコルがあります。xml の量は約です。5KB。

世界のさまざまな場所にある Linux EC2 インスタンスで送信側と受信側の両方を実行すると、リクエストの約 0.04% で、Jetty ハンドラーが xml リクエスト (投稿本文) を空の文字列と見なすことがわかりました。私がチェックしたところ、クライアントは一貫して正しい (> 0 長さ) xml 要求文字列を送信しようとしていることが出力されました。

また、ローカル (Win 8) ボックスで JUnit テストをループすることで、これを再現しました。

エラーは次のようなものでなければならないと思います:

  • バッファの誤用
  • HttpURLConnection のバグ
  • ネットワーク エラー
  • 桟橋のバグ
  • 私がコードで行ったランダムな頭の平手打ちの愚かなこと

関連するコードは次のとおりです。

クライアント

        connection = (HttpURLConnection) (new URL (url)).openConnection();
        connection.setReadTimeout(readTimeoutMS);
        connection.setConnectTimeout(connectTimeoutMS);
        connection.setRequestMethod("POST");
        connection.setAllowUserInteraction(false);
        connection.setDoOutput(true);

        // Send request
        byte[] postBytes = requestXML.getBytes("UTF-8");
        connection.setRequestProperty("Content-length", "" + postBytes.length);
        OutputStream os = connection.getOutputStream();
        os.write(postBytes);
        os.flush();
        os.close();

        // Read response
        InputStream is = connection.getInputStream();
        StringWriter writer = new StringWriter();
        IOUtils.copy(is, writer, "UTF-8");
        is.close();
        connection.disconnect();
        return writer.toString();

SERVER (桟橋ハンドラー)

    public void handle(java.lang.String target, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, int dispatch) {
        InputStream is = request.getInputStream();
        StringWriter writer = new StringWriter();
        IOUtils.copy(is, writer, "UTF-8");
        is.close(); 
        String requestXML = writer.toString();
        // requestXML is 0 length string about 0.04% of time

空の文字列としてリクエストをランダムに取得する理由を誰でも考えられますか?

ありがとう!

編集

さらにトレースを導入し、エラーが発生したときに getContentLength() が -1 を返しますが、クライアントの出力には、適切な量のバイトが送信されていることが示されています。

4

2 に答える 2

2

空の文字列を取得する理由がわかりません。コードは正しいようです。空の文字列をチェックするようにコードを更新し、見つかった場合はリクエストの content-length と transfer-encoding を報告すると、原因を特定するのに役立ちます。ネットワーク データの Wireshark トレースも有効です。

しかし、残念なことに、jetty-6 は実際にはサポートが終了しており、更新する予定はありません。今日コードを書いているのであれば、本当に jetty-7 か 8 を使うべきです。勇気があれば、おそらく jetty-9 マイルストーン リリースでさえも。もしあなたがjetty-9でそのようなエラーを見つけたら、私はあなたのためにそれを修正しようとして発疹のようにいたるところにいるでしょう!

于 2012-11-01T21:20:19.280 に答える
1

connection.setRequestProperty("Content-Type", "application/xml"); Content-type なしで POST データが破棄される可能性があることを確認してください。これは、(Grails に埋め込まれた Tomcat インスタンスに対して) 問題をローカルに複製した場合で、これを提供することで修正されました。

于 2012-11-07T17:23:04.477 に答える