Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么从Jakarta Commons HttpClient获取空请求?_Java_Http_Axis_Apache Commons Httpclient - Fatal编程技术网

Java 为什么从Jakarta Commons HttpClient获取空请求?

Java 为什么从Jakarta Commons HttpClient获取空请求?,java,http,axis,apache-commons-httpclient,Java,Http,Axis,Apache Commons Httpclient,我对Jakarta Commons HttpClient有问题。在我自己编写的HttpServer获得真正的请求之前,有一个请求是完全空的。这是第一个问题。第一个问题解决了。这是由不必要的URL连接引起的!第二个问题是,有时请求数据在http请求的第三行或第四行之后结束: 对于调试,我使用Axis TCP监视器。除了空洞的要求,一切都很好 如何处理流: 找到了处理流的新方法。我读取所有标题参数,并使用“内容长度”读取帖子数据。 InputStream is = mySocket.getInp

我对Jakarta Commons HttpClient有问题。在我自己编写的HttpServer获得真正的请求之前,有一个请求是完全空的。这是第一个问题。第一个问题解决了。这是由不必要的URL连接引起的!第二个问题是,有时请求数据在http请求的第三行或第四行之后结束:

对于调试,我使用Axis TCP监视器。除了空洞的要求,一切都很好

如何处理流:

找到了处理流的新方法。我读取所有标题参数,并使用“内容长度”读取帖子数据。

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();
你们有谁知道如何解决这些问题吗


Alex我不知道第一个问题,但我认为你的第二个问题是由以下原因造成的:

} 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-但您并不真正关心它是否阻塞,因此我们可以简单地删除它(您可以在此处阅读更多内容:)。尝试更改为:

byte[] buf = new byte[500];
while((is.read(buf))>-1){
  requestBuffer.append(new String(buf).trim());
  buf = new byte[500];
}

现在您应该可以得到整个请求。

当我删除is.ready()时,读取时间太长了。大约需要20秒才能收到响应。当我删除is.ready()时,读取时间太长了。响应返回大约需要20秒。当您说“响应返回”时,您的意思是将请求xml读入requestbuffer需要20秒吗?整个请求在读取请求xml并发送响应时需要约20秒。好的,我认为这是由服务器实现的另一部分引起的-请尝试并用一些计时代码和一些打印语句包装主要部分(例如,接收请求、构建响应、发送响应)。e、 例如,长启动=System.currentTimeMillis()。。。接收请求。。。System.out.println(“任务blah take:”+(System.currentTimeMillis()-start)+“完成毫秒”);这应该可以帮助你确定你的应用程序中哪一部分花费的时间最多。这是我的错。问题是这条流并没有真正结束。我通过使用http头参数“content length”解决了这个问题。我在问题中添加了新的代码片段。编辑,现在我正在读取带有缓冲区的流。。。
} while (byteIn != -1);
byte[] buf = new byte[500];
while((is.read(buf))>-1){
  requestBuffer.append(new String(buf).trim());
  buf = new byte[500];
}