本文主要是介绍filter中流未关闭引发的问题getWriter() has already been called for this response,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【引言】
在上一篇博客中,写了Spring MVC和Spring Boot框架中如何实现自定义filter,文章结尾提到了filter中遇到的问题,如下:
IllegalStateException: getWriter() has already been called for this response
【问题代码】
public class LoginFilter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {...PrintWriter out = null;...out = resp.getWriter();//判断是否已经登录,没登录返回登录urlif(user.notLogin()){ReturnMsg msg = new ReturnMsg();msg.setCode("111111");msg.setMessage("用户未登录");out.writer(JSON.toJSONString(msg));out.close();return;}...chain.dofilter(req,resp);}@Overridepublic void destroy() {}
}
【问题原因】
在上面的代码中,可以发现,只有当进入未登录的逻辑才会将流关闭,而如果登录之后,再次进入这个filter,就会出现以上异常。所以将代码修改了一版,如下:
public class LoginFilter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {...PrintWriter out = null;...try {//判断是否已经登录,没登录返回登录urlif(user.notLogin()){ReturnMsg msg = new ReturnMsg();msg.setCode();msg.setMessage();out = resp.getWriter();out.writer(JSON.toJSONString(msg));out.close();return;}} finally {if(out!=null){out.flush();out.close();}}...chain.dofilter(req,resp);}@Overridepublic void destroy() {}
}
【其他原因】
我遇到的情况是因为流未关闭,导致的上述异常,在查解决方案,还看到了可能有其他原因导致此异常。比如:getWriter() 和getOutputStream() 只能用一个,一个字符输出流,一个字节输出流,都获取后就会出现这个异常。
【总结】
很简单的一个filter,接二连三出现代码错误。最开始忘记写验证通过,放行chain.dofilter(req,resp)一行代码;接着出现这个异常,给老大的解释是自己从其他filter粘贴过来的代码,也没看写的什么内容,删删减减,没报错,留下需要的就提交了。
另外,也存在一些外部原因,test环境与pre环境配置不一样,test通过了,pre却出问题了,而pre的日志我们开发人员也不能随便查,所以定位问题也花费了不少时间。
在这个流程复杂严格而又混乱的团队,让我在一个月的时间里看到了凌晨四点的中关村,我想,生活就是,选择放弃可以有很多理由,而选择坚持下去一个就足够了。
这篇关于filter中流未关闭引发的问题getWriter() has already been called for this response的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!