DataInputStream.readFully EOFException

异常是DataInputStream.readFully 的197行抛出的EOFException,原因是流读取完了,然后缓存没有读满,触发的异常。实际内容比Content-Length短导致的

EOFException  if this input stream reaches the end before reading all the bytes.
public final void readFully(byte b[], int off, int len) throws IOException {
        if (len < 0)
            throw new IndexOutOfBoundsException();
        int n = 0;
        while (n < len) {
            int count = in.read(b, off + n, len - n);
            if (count < 0)
                throw new EOFException();//返回异常
            n += count;
        }
    }
    public  String body(HttpServletRequest hsr) throws IOException {
            String contentLength = hsr.getHeader("Content-Length");
            byte[] buffer= new byte[Integer.valueOf(contentLength)];
            DataInputStream dis = new DataInputStream(hsr.getInputStream());
            dis.readFully(buffer);
            return  new String(buffer,"UTF-8");
    }

那么是什么原因导致Content-Length长度与实际不符呢?我注意到以下两个属性


"Accept-Encoding":"gzip",
"Content-Type":"application/x-www-form-urlencoded",

application/x-www-form-urlencoded属于比较常用的POST 提交数据的方式。

gzip:使用 Lempel-Ziv 编码( LZ77 )的压缩格式,附带32位 CRC 。

引用官方文档的描述:

By default this implementation of HttpURLConnection requests that servers use gzip compression. Since getContentLength() returns the number of bytes transmitted, you cannot use that method to predict how many bytes can be read from getInputStream(). Instead, read that stream until it is exhausted: when read() returns -1. Gzip compression can be disabled by setting the acceptable encodings in the request header。

默认情况下,此HttpURLConnection实现请求服务器使用gzip压缩。由于getContentLength()返回传输的字节数,因此无法使用该方法预测可以从getInputStream()读取多少字节。相反,读取该流直到其耗尽:当read()返回-1时。可以通过在请求头中设置可接受的编码来禁用Gzip压缩

两者叠加,使的虽然是字符的方式传递的参数依然会被gzip方式压缩,从而使Content-Length长度大于实际长度,从而导致触发 EOFException。

问题虽然解决了,但让我不解的是,如果读完了,直接返回就好,为什么非要抛出这个异常

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值