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。

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

你可能感兴趣的:(java,readFully,EOFException,Content-Length,DataInputStream)