您的位置:首页 > 编程语言 > Java开发

异常处理---java.lang.IllegalStateException: getWriter() has already been called for this

2015-09-02 14:17 609 查看
异常:java.lang.IllegalStateException: getWriter() has already been called for this

异常描述:

   java.lang.IllegalStateException:getWriter() has already been called for this response

   java.lang.IllegalStateException:getOutputStream()has already been called for this response

产生原因:

   如果一次请求响应过程中已经获取PrintWriter out = response.getWriter();再次通过response.getWriter();或response.getOutputStream();获取输出流时将产生该异常。

解决方法:最直接有效的方法就是在一次请求响应中只在一个地方获取该输出流。

Eg:以下为本人在项目过程中遇到的问题,可以用作参考:

目的是希望实现用户在下载音频之前,通过ajax去请求Action判断语音资源对应的InputStream流是否为null;

把判断后的值写回浏览器端由ajax的回调函数success判断写回值;

写回值为true,则跳转到下载的action去下载语音;写回值为false,则在当前网页中alert出一下错误提示窗口。

其中有几个值得一提的点:

1).easyui的datagrid+json+ajax实现在后台动态生成下载的超链接浏览器端显示。

此时希望在<a>中添加触发javascript函数事件,在此事件中调用ajax。函数的参数是语音资源的路径,显然是一段很长的具有各种符号的路径。这个时候函数的参数应该这样写:

map.put("download", "<a onclick='return readyForDownLoad(""+downloadPath+"")'style='color:blue;'><img src='../images/downloads.png' width='18px' height='18px' border='0' />下载</a>");

当javascript函数的参数是字符串时,参数一定要用一对"括起来,不然你会发现各种千奇百怪的错误,这里就不列举了。

2).在浏览器前端的js要做的工作就是用户点击链接时,js函数使用ajax请求Action,在回调函数中获取在Action返回的值进行判断,资源是否存在;存在则下载,不存在则报错。

function readyForDownLoad(downLoadUrl){

var url =downLoadUrl;

$.ajax({

type: "POST",

url: url,

dataType: "text",

data: {"doExit":1},

success: function (data) {

if(data=="true"){

window.location.href=url; //执行下载操作

}else{

alert('下载错误,语音不存在!!');

}

},

error: function (fn) {

alert('操作错误!!');

}

});

return false;

}

3).那么在Action中怎么向ajax写入返回值呢?

public String execute() throws Exception {

mimeType = context.getMimeType(filename);

if(doExit==1){

HttpServletResponse response=ServletActionContext.getResponse();

PrintWriter out = response.getWriter();

inStream =getInStream();

if (inStream == null) {

out.print("Sorry,File not found !");

}else{

out.print("true");

}

out.close();

}

return SUCCESS;

}

public InputStream getInStream() {

File file = new File(getRootpath()+filename);

try {

inStream=new BufferedInputStream(new FileInputStream(file));

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return inStream;

}

就这一小段代码就让我吃了许多苦,经过多次尝试我只能说每句代码都找到了它最正确的位置才使得这个功能实现了。以下是必须要注意的几点,仅供参考。

a).判断InputStream 是否为空的语句不能写在getInStream()方法里面,一个方法只做一件事,而且如果inStream不为 null,此时判断写入了true..............可以想象

b).千万不要把

HttpServletResponse response=ServletActionContext.getResponse();

PrintWriter out = response.getWriter();

inStream =getInStream();

放到if判断语句之前,放到判断之前就意味着不管是否满足条件我都要执行,就是这几句的语序问题,我的程序就报了: java.lang.IllegalStateException: getWriter() has already been called for this 的错误,错误原因一开篇就提过了。

e).不得不提的最后一点就是千万不要忘了把流关闭,out.close()

到此为止应该差不多了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: