寻求一些帮助,我目前已经编写了一个HTTP服务器。它目前正在处理GET请求。然而,在使用POST时,缓冲的阅读器似乎挂了。当请求停止时,通过缓冲读取器读取其余输入流。我在谷歌上发现了一些东西。我已经尝试将CRLF和协议版本从1.1更改为1.0(浏览器自动发出请求为1.1)任何想法或帮助将不胜感激。感谢
答案 0 :(得分:7)
我同意汉斯的意见,你应该使用一个经过良好测试的标准库来完成这项工作。但是,如果您正在编写服务器以了解HTTP,请参阅以下有关您要执行的操作的信息。
你真的不能使用BufferedReader,因为它会缓冲输入并可能从套接字中读取太多字节。这就是你的代码挂起的原因,BufferedReader试图读取比套接字上可用的更多的字节(因为POST数据没有行结束),并且它正在等待更多的字节(永远不可用)
简单解析POST请求的过程是直接使用InputStream
对于标题中的每一行 一次读取一个字节,直到得到'\ r',然后是'\ n'
查找以“Content-Length:”开头的行,提取该行末尾的数字。
当您的标题行为空时,您已完成标题。
现在准确读取来自Content-Length标头的字节数。
现在你可以写下你的回复了。
答案 1 :(得分:2)
不会编写我自己的实现。如果需要,请查看以下现有组件:
答案 2 :(得分:1)
这不安全!但是展示了如何在初始HTTP标头之后的输入流中获取POST数据。
这也适用于以“example = true& bad = false”等形式出现的POST数据。
private HashMap hashMap = new HashMap();
private StringBuffer buff = new StringBuffer();
private int c = 0;
private String[] post; public PostInputStream(InputStream in) {
try {
//Initalizes avaliable buff
if (in.available() != 0) {
this.buff.appendCodePoint((this.c = in.read()));
while (0 != in.available()) {
//Console.output(buff.toString());
buff.appendCodePoint((this.c = in.read()));
}
this.post = buff.toString().split("&");
for (int i = 0; i < this.post.length; i++) {
String[] n = this.post[i].split("=");
if (n.length == 2) {
hashMap.put(URLDecoder.decode(n[0], "UTF-8"), URLDecoder.decode(n[1], "UTF-8"));
} else {
Console.error("Malformed Post Request.");
}
}
} else {
Console.error("No POST Data");
}
} catch (Exception e) {
e.printStackTrace();
}
}
答案 3 :(得分:0)
正如karoroberts所说,你必须检查POST中发送的内容的长度。但你仍然可以使用BufferedReader。
只需检查Content-Length标头的大小,读完所有标题后,您可以设置该大小的字符数组,并读取POST内容:
char [] buffer = new char [contentLength]; request.read(缓冲液);
其中request是BufferedReader。 如果需要字符串中的POST内容,可以使用:String.valueOf(buffer);
注意:BufferedReader.read返回一个已加入字符的int,因此您可以检查Content-Length标头是否存在不一致。