![](/img/trans.png)
[英]Jakarta commons HTTPClient can't send a post request on my apache server with php
[英]Why do I get empty request from the Jakarta Commons HttpClient?
我在Jakarta Commons HttpClient中遇到問題。
在我自己寫的HttpServer收到真正的請求之前,有一個請求是完全空的。
那是第一個問題。
第一個問題解決了。 這是由不必要的URLConnection引起的!
第二個問題是,有時請求數據在http請求的第三或第四行之后結束:
POST / HTTP/1.1
User-Agent: Jakarta Commons-HttpClient/3.1
Host: 127.0.0.1:4232
為了進行調試,我使用了Axis 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();
找到了一種處理流的新方法。 我讀取了所有標頭參數,並使用“ content-length”讀取了發布數據。
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 (byteIn != -1 && is.ready());
如果發送方發送數據的速度不夠快,則接收方可以在發送下一個數據包之前調用is.ready()
。 這將導致is.ready()
返回false
,這將導致循環停止。
最小的解決方法是將該行更改為:
} while (byteIn != -1);
編輯
但是實際上,您需要按照@simonlord的答案重寫方法。 一次讀取一個字節的無緩沖流是一個非常糟糕的主意。 您最終會為每個read
調用進行系統調用,這效率極低。
編輯2
刪除is.ready()
導致延遲的原因是因為您沒有適當注意HTTP協議。 問題在於HttpClient代碼使TCP連接的請求端保持打開狀態,以允許連接被重用。 簡單(但次優)的解決方案是將HttpClient配置為關閉連接的請求端。 您的代碼將立即看到EOF。 您實際上所做的是另一種解決方案。
坦白地說,除非您准備深入了解整個HTTP規范並如實實現,否則您甚至不應該嘗試實現服務器端HTTP協議。 有可能的是,現有的實現方式將比您可以組合在一起的任何方式更快,更可靠。 實施規范子集的問題在於,您的服務器可能需要與使用您不費吹灰之力實現/測試的部分規范的真實瀏覽器對話。
這可能與while循環中的第二個條件有關,當下一次讀取可能阻塞時,isReady()方法可能返回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];
}
現在您應該獲得整個請求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.