在与第三方合作的过程中,响应报文是xml格式的。最开始没有进行处理,对方收到的报文是chunked模式。对方说目前不支持这个模式,于是我就去寻找了什么叫chunked模式,以及怎么去避免使用这种模式。
简单介绍一下chunked:
Transfer-Encoding: chunked 表示输出的内容长度不能确定,普通的静态页面、图片之类的基本上都用不到这个。
但动态页面就有可能会用到,但我也注意到大部分asp,php,asp.net动态页面输出的时候大部分还是使用Content-Length,没有使用Transfer-Encoding: chunked。
不过如果结合:Content-Encoding: gzip 使用的时候,Transfer-Encoding: chunked还是比较有用的。
记得以前实现:Content-Encoding: gzip 输出时,先把整个压缩后的数据写到一个很大的字节数组里(如 ByteArrayOutputStream),然后得到数组大小 -> Content-Length。
如果结合Transfer-Encoding: chunked使用,就不必申请一个很大的字节数组了,可以一块一块的输出,更科学,占用资源更少。
这在http协议中也是个常见的字段,用于http传送过程的分块技术,原因是http服务器响应的报文长度经常是不可预测的,使用Content-length的实体搜捕并不是总是管用。
分块技术的意思是说,实体被分成许多的块,也就是应用层的数据,TCP在传送的过程中,不对它们做任何的解释,而是把应用层产生数据全部理解成二进制流,然后按照MSS的长度切成一分一分的,一股脑塞到tcp协议栈里面去,而具体这些二进制的数据如何做解释,需要应用层来完成,所以在这之前,一快整体应用层的数据需要等它分成的所有TCP segment到达对方,重新组装后,应用程序才使用自己的解码方法还原它们。
HTTP1.1采用了持久的连接,也就是一次TCP的连接不马上释放,允许许多的请求跟响应在一个TCP的连接上发送,所以客户机与服务器需要某种方式来标示一个报文在哪里结束和在下一个报文在哪里开始。简单的方法是使用呢content-length,但这只有当报文长度可以预先判断的时候才起作用,而对于动态的内容或者在发送数据前不能判定长度的情况下,可以使用分块的方法来传送编码。
简而言之:在httpresponse传输过程中,不知道要传输的内容的具体大小,所以就采用chunked(分块)模式,这样,有点类似于流媒体的赶脚。一段一段的传输。
那么,根据这个含义,想要去掉chunked模式,我们只需要把要传输的内容的大小告诉httpresponse即可了,就是:
response.setContentLength(1000);
response.setContentType("text/html;charset=UTF-8");// 解决中文乱码
response.setCharacterEncoding("UTF-8");//设置字符集编码
response.setContentLength(rspString.length());//设置传输内容大小(注意:要在printWriter = response.getWriter();之前)
//以下是将内容进行传输了
printWriter = response.getWriter();
printWriter.print(rspString);
printWriter.flush();
printWriter.close();