java.lang.IllegalStateException: Cannot call sendError() after the response has 博客分类: JavaJava Web struts下载stream下载报错sendError
程序员文章站
2024-02-24 18:46:16
...
异常出现的场景:
(1)ssh项目,提供下载功能。项目使用tomcat部署;
(2)写了一个测试类来测试下载功能,执行时报异常:
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
下载类在struts中的配置(截取):
<action name="downloadOneFile" class="downloadOneFileAction"> <result type="stream" name="success"> <param name="inputName">downloadFile</param> <param name="contentType"></param> <param name="contentDisposition">attachment;filename=${filename}</param> <param name="bufferSize">4096</param> </result> </action>
在测试代码中使用 HttpURLConnection模拟浏览器发送http请求,读取应答体的部分代码如下:
上述代码是有问题的,本来bis中有1k的字节,结果我试图读取2k的字节,所以就报错了,原因找到了,怎么解决呢?
修改为:
private static byte[] readDataFromLength2(HttpURLConnection huc, int contentLength) throws Exception { InputStream in = huc.getInputStream(); BufferedInputStream bis = new BufferedInputStream(in); // 数据字节数组 byte[] receData = new byte[contentLength]; int readLength = 0; // 数据数组偏移量 int offset = 0; readLength = bis.read(receData, offset, contentLength); // 已读取的长度 int readAlreadyLength = readLength; while (readAlreadyLength < contentLength) { readLength = bis.read(receData, readAlreadyLength, contentLength - readAlreadyLength); readAlreadyLength = readAlreadyLength + readLength; } return receData; }
解决问题的过程:
1,刚开始以为是编码的问题,怀疑BufferedInputStream bis = new
BufferedInputStream(in);中BufferedInputStream的构造方法的第二个参数是编码(如GBK,UTF-8等),结果证明没有这个参数;
2,bis.read的第三个参数刚开始以为是索引,结果发现是长度(读取的字节);
3,while中比较时,应该是readAlreadyLength和contentLength进行比较。
参阅附件中com.http.util.HttpSocketUtil .附件中的项目是使用maven 构建的。
注意:读取BufferedInputStream时 使用while循环是必要的。