struts2 下载时报java.lang.IllegalStateException
-----------------------------------------struts2 下载时报java.lang.IllegalStateException------------------------------------------------------------- 抛出java.lang.IllegalStateException异常,终于发现原因之所在:
我们在做文件上传或者下载,用到页面的输出流. 在action中使用下载的方法:
//文件下载
public String downFile() throws IOException{
String msg=null;
response.setCharacterEncoding("gb2312");
response.setContentType("text/html");
javax.servlet.ServletOutputStream ou = response.getOutputStream(); //文件名
String filename=new String(request.getParameter("filename").getBytes("ISO8859_1"),"utf-8").toString(); //路径
String filepath=ServletActionContext.getServletContext().getRealPath("/upload/"+filename);
java.io.File file = new java.io.File(filepath);
if (!file.exists()) {
System.out.println(file.getAbsolutePath() + " 文件不能存在!");
msg="抱歉,文件可能过期了!";
super.addActionError(msg);
return null;
}
// 读取文件流
java.io.FileInputStream fileInputStream = new java.io.FileInputStream(file); // 下载文件
// 设置响应头和下载保存的文件名
if (filename != null && filename.length() > 0) {
response.setContentType("application/x-msdownload");//弹出下载的框
response.setContentLength((int) file.length());//下载统计文件大小的进度
response.setHeader("Content-Disposition", "attachment; filename=" + new String(filename.getBytes("gb2312"),"iso8859-1") + "");
//response.setHeader("Content-Length", file.length()); //下载框的信息
if (fileInputStream != null) {
int filelen = fileInputStream.available(); //文件太大时内存不能一次读出,要循环
byte a[] = new byte[filelen];
fileInputStream.read(a);
ou.write(a);
}
fileInputStream.close();
ou.close();
}
return SUCCESS;
}
抛出异常:java.lang.IllegalStateException
原因分析:
这是web容器天生的servlet代码中有out.write(””),
这个和JSP中调用的response.getOutputStream()产生冲突.
即Servlet规范说明,
不能既调用 response.getOutputStream(),又调用response.getWriter(),无论先调用哪一个,
在调用第二个时候应会抛出 IllegalStateException,
解决: action方法:
public String downTest(){
try {
name =new String(getFilename().getBytes("iso-8859-1"),"utf-8");
tname=java.net.URLEncoder.encode(name,"utf-8");
String path=ServletActionContext.getServletContext().getRealPath("/upload/"+name);
File file=new File(path);
inputStream=new FileInputStream(file);
response.setContentLength((int) file.length());//下载统计文件大小的进度
} catch (Exception e) {
e.printStackTrace();
} return SUCCESS;
}
struts2.xml:
<!-- 下载中心控制器 -->
<action name="download" class="downloadAction">
<result name="success" type="stream"> <!-- 设置输入流 -->
<param name="inputstream">inputStream</param>
<!-- 设置下载的方式及文件名 -->
<param name="contentDisposition">attachment;filename=${tname}</param>
</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>