在使用Filter过滤器时,有些请求会报java.lang.IllegalStateException: getWriter() has already been called for this response错误。
这里贴上我所碰到的异常信息:
根据异常信息仅找出异常来自于Filter自定过滤器内部。困扰许久,最后找出原因是由于getWriter()对象创建的位置不合理导致报错无法正常运行。
此处是报错时的部分代码:
根据异常找出原因后修改的代码如下:
两段代码唯一的区别就是PrintWriter out = response.getWriter();位置不一样,但效果坐实不错,解决了异常。
下面描述我的使用环境,Easyui框架下datagrid组件初始化时无法正常进行数据初始化显示。为下图这个组件:
简单描述它的datagrid的特点:页面初始化时,datagrid往后台发起请求填充表格,有点类似相当于ajax。
好那么说重点,在普通的一个url请求中莫非有两种方式响应,如(登陆从login.jsp ->> UserServlet中的login方法时):
- 登陆成功,直接通过转发or重定向,跳入到main.jsp页面当中完成登陆。
- 登陆成功,通过ajax的方式请求,会返回一串json格式字符,根据返回结果处理后,跳入到main.js完成登陆
- 后台显示登陆成功,而此方法返回一个字符串,由于没使用ajax请求,最后会将返回的字符串直接显示在新的页面当中如下:
在1跟3无论结果如何,都会通过一个新的页面用于响应请求信息,此时无论response.getWriter()对象在何处实例化, 都并不影响程序的正常运行。
而在2中的ajax跟上述Easuui使用情境下response.getWriter();实例的位置则显得很关键,由于请求后相应需要返回原页面,而PrintWriter的实例会与之生冲突。
试想 一下, 在使用ajax时,从A.jsp --> BServlet 时被中途创建response.getWriter()拦下来,那么程序到底是将结 果返回到原ajax呢?还是根据PrintWriter对象重定向或者转发到新的页面呢? 所以此时将会冲突,程序则报异常信息。这时也与异常java.lang.IllegalStateException:getWriter()has already been called for this res ponse相吻合,所以遇到这种错误的时候只需要思考一下这个请求如何让他不冲突则可解决问题。
结论:
- 一个请求无论如何都会是有始有终.