なぜか空からの要請にジャカルタ-コモンズHttpClient?
-
18-09-2019 - |
質問
私は問題はジャカルタ-コモンズHttpClient. 前に私の自己記述利得の請求が要求を完全に空になります。この問題です。 最初の問題は解決しました。から生じる不要なURLConnection! 第二の問題は、時には依頼データは、目線のhttpリクエスト:
POST / HTTP/1.1
User-Agent: Jakarta Commons-HttpClient/3.1
Host: 127.0.0.1:4232
デバッグを使用してい軸TCPMonitor.あべいものですが、空い。
かのストリーム:
StringBuffer requestBuffer = new StringBuffer();
InputStreamReader is = new InputStreamReader(socket.getInputStream(), "UTF-8");
int byteIn = -1;
do {
byteIn = is.read();
if (byteIn > 0) {
requestBuffer.append((char) byteIn);
}
} while (byteIn != -1 && is.ready());
String requestData = requestBuffer.toString();
た新しい工程のストリームです。読んだすべてのヘッダーパラメータと使用のコンテンツの長さ'を読み込むためのポストデータです。
InputStream is = mySocket.getInputStream();
if (is == null) {
return;
}
BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8"));
// Read the request line
// ...
// ...
// Parse the header
Properties header = new Properties();
if (st.hasMoreTokens()) {
String line = in.readLine();
while (line != null && line.trim().length() > 0) {
int p = line.indexOf(':');
header.put(line.substring(0, p).trim().toLowerCase(), line.substring(p + 1).trim());
line = in.readLine();
}
}
// If the method is POST, there may be parameters
// in data section, too, read it:
String postLine = "";
if (method.equalsIgnoreCase("POST")) {
long size = 0x7FFFFFFFFFFFFFFFl;
String contentLength = header.getProperty("content-length");
if (contentLength != null) {
try {
size = Integer.parseInt(contentLength);
} catch (NumberFormatException ex) {
}
}
postLine = "";
char buf[] = new char[512];
int read = in.read(buf);
while (read >= 0 && size > 0 && !postLine.endsWith("\r\n")) {
size -= read;
postLine += String.valueOf(buf, 0, read);
if (size > 0) {
read = in.read(buf);
}
}
postLine = postLine.trim();
decodeParms(postLine, parms);
}
どのようにして送要請:
client.getParams().setSoTimeout(30000);
method = new PostMethod(url.getPath());
method.getParams().setContentCharset("utf-8");
method.setRequestHeader("Content-Type", "application/xml; charset=utf-8");
method.addRequestHeader("Connection", "close");
method.setFollowRedirects(false);
byte[] requestXml = getRequestXml();
method.setRequestEntity(new InputStreamRequestEntity(new ByteArrayInputStream(requestXml)));
client.executeMethod(method);
int statusCode = method.getStatusCode();
していだいかこれらの問題を解決する問題なのでしょうか。
アレックス
解決
この第二の条件にごwhileの代理店は募集()メソッドがfalseを返す場合、次の読み込みがブロックがうまでブロックなので、できるだけを削除することができます(お問い合わせください。 http://java.sun.com/j2se/1.5.0/docs/api/java/io/InputStreamReader.html#ready%28%29 ).に変更してみてくださいここに:
byte[] buf = new byte[500];
while((is.read(buf))>-1){
requestBuffer.append(new String(buf).trim());
buf = new byte[500];
}
今必要なの全体ます。
他のヒント
最初の問題についてはわかりませんが、2 番目の問題は次のことが原因だと思います。
} while (byteIn != -1 && is.ready());
送信者が十分に早くデータを送信できない場合、受信者は呼び出しを行うことがあります。 is.ready()
次のパケットが送信される前に。これにより、 is.ready()
戻る false
これによりループが停止します。
最小限の修正は、その行を次のように変更することです。
} while (byteIn != -1);
編集
しかし実際には、@simonlord の答えに従ってメソッドを書き直す必要があります。バッファリングされていないストリームを一度に 1 バイトずつ読み取るのは非常に悪い考えです。結局、それぞれに対してシステムコールを実行することになります。 read
これは恐ろしく非効率的です。
編集2
削除する理由は、 is.ready()
遅延の原因は、HTTP プロトコルに適切な注意を払っていなかったためです。問題は、HttpClient コードが、接続の再利用を可能にするために TCP 接続のリクエスト側を開いたままにしていたことでした。単純な (ただし次善の) 解決策は、接続のリクエスト側を閉じるように HttpClient を構成することでした。そうすれば、コードはすぐに EOF を認識することになります。あなたが実際にやったことは別の解決策でした。
率直に言って、そうすべきではありません 試しています HTTP 仕様全体を深く理解し、忠実に実装する準備ができていない限り、サーバー側 HTTP プロトコルを実装することはできません。おそらく、既存の実装は、他のものを組み合わせたものよりも高速で信頼性が高くなります。仕様のサブセットを実装する場合の問題は、サーバーが、わざわざ実装/テストしていない仕様の部分を使用する実際のブラウザと通信する必要がある可能性があることです。