关于HttpServletResponseWrapper导致HttpServletResponse的输出流下载文件比原文件大接近一倍且打开异常的问题

代码如下:

//filePath 是服务器存放文件的路径
File file = new File(filePath + File.separator + fileName);
            
inputStream = new FileInputStream(file);

outputStream = resp.getOutputStream();
//采用工具类,复制输入流IO对象数据至响应输出流。
//IOUtils.copy(inputStream, outputStream);
int size = 0;
int available = inputStream.available();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
       outputStream.write(buffer, 0, len);
       size += len;
       }
           
logger.info("源文件大小:{},下载文件大小:{}", available, size);
outputStream.flush();

原文件118332字节

可以看到在输入流写入到输出流之后,其大小还是正常的。 但是下载之后的大小就不正常了,保存出来也不正确且打开异常。变成205KB了。

 

我查了很多,大部分是说因为写入输出流的时候没有定义长度len,导致每次写入的长度都是定值1024,导致多了一些字符,但明显不不能解决我的问题。最后我把问题想到了框架上,因为这个功能确实是一个很简单的功能,代码看上去也没有错误,不应该。

最终我发现了问题。

public class ResponseWrapper extends HttpServletResponseWrapper {
    private ByteArrayOutputStream buffer = null;
    
    private ServletOutputStream out = null;
    
    private PrintWriter writer = null;
    
    public ResponseWrapper(HttpServletResponse resp)
        throws IOException {
        super(resp);
        /**
         * 替换默认的输出端,作为response输出数据的存储空间(即真正存储数据的流)
         */
        buffer = new ByteArrayOutputStream();
        /**
         * response输出数据时是调用getOutputStream()和getWriter()方法获取输出流,再将数据输出到输出流对应的输出端的。
         * 此处指定getOutputStream()和getWriter()返回的输出流的输出端为buffer,即将数据保存到buffer中。
         */
        out = new WapperedOutputStream(buffer);
        writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding()));
    }

..........
}

因为重写了HttpServletResponseWrapper ,导致在过滤器里,可以获取倒HttpServletResponse的内容,从而框架获取了输出流进行了处理(框架对出入参的规范化处理或集中加解密等方式)

只需要在过滤器里判断请求的url进行放行,就可以了。

String url = request.getRequestURI();
if (url.contains("download")) {
            chain.doFilter(request, response);
            return;
        }

至此,问腿解决了。真实的巨坑啊。我一直以为是自己写错了,换了N种写法都没有解决,最后突发奇想看看是不是框架对我的数据做了二次加工,结果真的是这个问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值