你认为http协议混合字符流与字节流不是一个好设计

时间:2011-09-25 13:33:48

标签: java http protocols implementation

首先,当我说 http协议混合带字节流的字符流时,我的意思是请求头是字符流请求体是字节流(由content-length指定),它们由空行分隔。

这种设计使http实现更加困难。例如,如果使用java实现http服务器,则不能使用此类代码,因为BufferedReader将缓冲一些字节以读取一行。< / p>

InputStream   stream=socket.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(stream));
String line;
while( !(line=reader.readLine()).equals("") ){
    //do something with line
}
//from stream to read content-length bytes
stream.read(...)

如果使用前两个字节到指定的请求头长度而不是使用空行,那么实现http协议会更容易。

2 个答案:

答案 0 :(得分:1)

这不仅仅是糟糕的设计......它已经破碎了。很有可能BufferedReader会将请求主体的第一部分读入其缓冲区。因此,当你最后从流中读到时,你将无法获得所有的身体。

一旦你包裹了一个InputStream,就不应该直接使用它......尤其是当包装器进行缓冲时。


实现此目的的最佳方法是使用现有的HTTP Server端实现。 Apache HTTP Components库是一个很好的选择。

如果您必须自己实现,那么简单的解决方案就是:

  1. InputStream换成BufferedInputStream
  2. 使用BufferedInputStream一次读取一个字节的标题行并构建行并自行转换为字符串。
  3. 使用BufferedInputStream阅读正文。

  4.   

    我觉得HTTP协议的愚蠢设计会使java.io库变得无用。

    我不会这么说。问题是HTTP协议可能要求客户端切换它在消息中途解释请求或响应消息的字符/字节的方式。但如果你考虑一下,这不是一件不合理的事情。替代方案是:

    • 发送会增加协议开销的单独消息,或
    • 编码并将请求/响应行和标题作为字节而不是字符发送。

    我们真正拥有的是一个棘手的用例,它太不寻常,无法在通用java.io库中得到支持。协议支持库会处理这个...如果你能够使用它。

答案 1 :(得分:0)

是的,但也会更容易产生损坏的消息。