`

java.lang.IllegalStateException: Cannot call sendError() after the response has

阅读更多

异常出现的场景:

(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等),结果证明没有这个参数;

2bis.read的第三个参数刚开始以为是索引,结果发现是长度(读取的字节);

3while中比较时,应该是readAlreadyLengthcontentLength进行比较。 

参阅附件中com.http.util.HttpSocketUtil  .附件中的项目是使用maven 构建的。

注意读取BufferedInputStream时 使用while循环是必要的。

  • 大小: 18.4 KB
2
5
分享到:
评论
5 楼 jimode2013 2013-08-19  
hw1287789687 写道
项目中出现过这个问题,项目有一个功能是上传zip压缩包,而后解压zip包,并且把zip包中的文件存储到数据库对应的表字段(Blob)中。在测试中发现使用java 解压zip包时不对,解压后的文件和原来文件MD5值不同。
解压zip包的java代码是公司大牛写的,有问题的代码如下:
public static byte[] getContent(final ZipFile zipFile, final ZipEntry zipEntry)
            throws IOException {
        InputStream inputStream = zipFile.getInputStream(zipEntry);
        int length = inputStream.available();
        byte[] bytes = new byte[length];
        inputStream.read(bytes);
        inputStream.close();
        return bytes;
    }

jimode2013 写道
hw1287789687 写道
呵呵,初学者一般会觉得bis.read(receData, offset, contentLength);就够了,就可以一次性读取成功。这在一般情况下行得通,但是有时候会有问题,建议你关注一下read(x,y,z)的返回值

jimode2013 写道
说句实话,有点莫名其妙的
 readLength = bis.read(receData, offset, contentLength);  
        // 已读取的长度  
        int readAlreadyLength = readLength;  
        while (readAlreadyLength < contentLength) {  
            readLength = bis.read(receData, readAlreadyLength, contentLength  
                    - readAlreadyLength);  
            readAlreadyLength = readAlreadyLength + readLength;  
        }

上面怎么写是什么意思?可不可以直接这样写
		bis.read(receData, offset, contentLength);
		return receData;

请问有时候是指什么情况下?生成过程中有实际出现的情况么?请问有相关这方面的资料么?

谢谢不吝赐教
4 楼 hw1287789687 2013-08-18  
项目中出现过这个问题,项目有一个功能是上传zip压缩包,而后解压zip包,并且把zip包中的文件存储到数据库对应的表字段(Blob)中。在测试中发现使用java 解压zip包时不对,解压后的文件和原来文件MD5值不同。
解压zip包的java代码是公司大牛写的,有问题的代码如下:
public static byte[] getContent(final ZipFile zipFile, final ZipEntry zipEntry)
            throws IOException {
        InputStream inputStream = zipFile.getInputStream(zipEntry);
        int length = inputStream.available();
        byte[] bytes = new byte[length];
        inputStream.read(bytes);
        inputStream.close();
        return bytes;
    }

jimode2013 写道
hw1287789687 写道
呵呵,初学者一般会觉得bis.read(receData, offset, contentLength);就够了,就可以一次性读取成功。这在一般情况下行得通,但是有时候会有问题,建议你关注一下read(x,y,z)的返回值

jimode2013 写道
说句实话,有点莫名其妙的
 readLength = bis.read(receData, offset, contentLength);  
        // 已读取的长度  
        int readAlreadyLength = readLength;  
        while (readAlreadyLength < contentLength) {  
            readLength = bis.read(receData, readAlreadyLength, contentLength  
                    - readAlreadyLength);  
            readAlreadyLength = readAlreadyLength + readLength;  
        }

上面怎么写是什么意思?可不可以直接这样写
		bis.read(receData, offset, contentLength);
		return receData;

请问有时候是指什么情况下?生成过程中有实际出现的情况么?请问有相关这方面的资料么?
3 楼 jimode2013 2013-08-16  
hw1287789687 写道
呵呵,初学者一般会觉得bis.read(receData, offset, contentLength);就够了,就可以一次性读取成功。这在一般情况下行得通,但是有时候会有问题,建议你关注一下read(x,y,z)的返回值

jimode2013 写道
说句实话,有点莫名其妙的
 readLength = bis.read(receData, offset, contentLength);  
        // 已读取的长度  
        int readAlreadyLength = readLength;  
        while (readAlreadyLength < contentLength) {  
            readLength = bis.read(receData, readAlreadyLength, contentLength  
                    - readAlreadyLength);  
            readAlreadyLength = readAlreadyLength + readLength;  
        }

上面怎么写是什么意思?可不可以直接这样写
		bis.read(receData, offset, contentLength);
		return receData;

请问有时候是指什么情况下?生成过程中有实际出现的情况么?请问有相关这方面的资料么?
2 楼 hw1287789687 2013-08-16  
呵呵,初学者一般会觉得bis.read(receData, offset, contentLength);就够了,就可以一次性读取成功。这在一般情况下行得通,但是有时候会有问题,建议你关注一下read(x,y,z)的返回值

jimode2013 写道
说句实话,有点莫名其妙的
 readLength = bis.read(receData, offset, contentLength);  
        // 已读取的长度  
        int readAlreadyLength = readLength;  
        while (readAlreadyLength < contentLength) {  
            readLength = bis.read(receData, readAlreadyLength, contentLength  
                    - readAlreadyLength);  
            readAlreadyLength = readAlreadyLength + readLength;  
        }

上面怎么写是什么意思?可不可以直接这样写
		bis.read(receData, offset, contentLength);
		return receData;
1 楼 jimode2013 2013-08-16  
说句实话,有点莫名其妙的
 readLength = bis.read(receData, offset, contentLength);  
        // 已读取的长度  
        int readAlreadyLength = readLength;  
        while (readAlreadyLength < contentLength) {  
            readLength = bis.read(receData, readAlreadyLength, contentLength  
                    - readAlreadyLength);  
            readAlreadyLength = readAlreadyLength + readLength;  
        }

上面怎么写是什么意思?可不可以直接这样写
		bis.read(receData, offset, contentLength);
		return receData;

相关推荐

Global site tag (gtag.js) - Google Analytics