今天小编在使用springmvc interceptor拦截器时,当用户登录失败的时候出现“Cannot call sendRedirect() after the response has been committed”错误,具体的错误如下所示,看看吧!
严重: Servlet.service() for servlet [english] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed] with root cause
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:483)
at com.voavoice.english.controller.LoginInterceptor.postHandle(LoginInterceptor.java:28)
at org.springframework.web.servlet.HandlerExecutionChain.applyPostHandle(HandlerExecutionChain.java:151)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:974)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
错误分析:
先看看小编的代码,小编自定义了一个spring mvc拦截器类,并继承了HandlerInterceptorAdapter拦截器,主要作用是当拦截用户是否登录,当用户没有登录时则跳转到登录页面,部分代码如下:
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { String urlStr = request.getRequestURI(); Users user = (Users)request.getSession().getAttribute("LOGIN_USER"); if(user == null && !urlStr.equals("/admin/user/login")){ response.sendRedirect(request.getContextPath()+"/admin/user/login"); } }
上面这段代码就是从session中获取用户信息,如果为null或者不是登录页面,则跳转到登录页面,正常情况下如果用户的用户名与密码都输入正确的话,是不会进入if方法里面的。
而如果用户登录失败,则user=null的时候,就会进入到这个if方法里面的,这个时候就会报“Cannot call sendRedirect() after the response has been committed”错误了。
结论:
因为小编的登录方法如“/admin/user/doLogin”是post请求的,而sendRedirect(/admin/user/login)方法跳转到的页面是get请求,所以就会出现上面这样的错误。
解决方案:
过滤掉doLogin这个Post登录请求即可,将上方的if部分代码改成如下所示:
if(user == null && !urlStr.equals("/admin/user/login") && !urlStr.equals("/admin/user/doLogin")){ response.sendRedirect(request.getContextPath()+"/admin/user/login"); }
备注:这个错误的中心思想就是不要在doPost请求之后再来发送一个sendRedirect的get请求。