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{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
...
PrintWriter out = null;
...
out = resp.getWriter();
//判断是否已经登录,没登录返回登录url
if(user.notLogin()){
ReturnMsg msg = new ReturnMsg();
msg.setCode("111111");
msg.setMessage("用户未登录");
out.writer(JSON.toJSONString(msg));
out.close();
return;
}
...
chain.dofilter(req,resp);
}
@Override
public void destroy() {
}
}
【问题原因】
在上面的代码中,可以发现,只有当进入未登录的逻辑才会将流关闭,而如果登录之后,再次进入这个filter,就会出现以上异常。所以将代码修改了一版,如下:
public class LoginFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
...
PrintWriter out = null;
...
try {
//判断是否已经登录,没登录返回登录url
if(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);
}
@Override
public void destroy() {
}
}
【其他原因】
我遇到的情况是因为流未关闭,导致的上述异常,在查解决方案,还看到了可能有其他原因导致此异常。比如:getWriter() 和getOutputStream() 只能用一个,一个字符输出流,一个字节输出流,都获取后就会出现这个异常。
【总结】
很简单的一个filter,接二连三出现代码错误。最开始忘记写验证通过,放行chain.dofilter(req,resp)一行代码;接着出现这个异常,给老大的解释是自己从其他filter粘贴过来的代码,也没看写的什么内容,删删减减,没报错,留下需要的就提交了。
另外,也存在一些外部原因,test环境与pre环境配置不一样,test通过了,pre却出问题了,而pre的日志我们开发人员也不能随便查,所以定位问题也花费了不少时间。
在这个流程复杂严格而又混乱的团队,让我在一个月的时间里看到了凌晨四点的中关村,我想,生活就是,选择放弃可以有很多理由,而选择坚持下去一个就足够了。
还没有评论,来说两句吧...