简体   繁体   English

在doFilter方法中获取IllegalStateException

[英]getting IllegalStateException within the doFilter method

When i create a servlet filter in Spring MVC, I am getting the following exception. 当我在Spring MVC中创建servlet过滤器时,出现以下异常。

 [javax.servlet.ServletException: java.lang.IllegalStateException: Cannot create a session after the response has been committed] with root cause

when i put the sysout i could understand that the exception occurs at the redirect line, but didn't understand why 当我将sysout放进去时,我可以理解异常发生在重定向行,但不明白为什么

can anyone please tell me some solution for this 谁能告诉我一些解决方案

SessionFilter.java SessionFilter.java

public class SessionFilter implements Filter {

    private ArrayList<String> urlList;

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String url = request.getServletPath();
        boolean allowedRequest = false;

        if(urlList.contains(url)) {
            allowedRequest = true;
        }

        if (!allowedRequest) {
            HttpSession session = request.getSession(false);
            if (null == session) {
                System.out.println("preparing for redirect");
                response.sendRedirect("index.jsp");
            }
        }

        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        System.out.println("entered init");
        String urls = config.getInitParameter("avoid-urls");
        StringTokenizer token = new StringTokenizer(urls, ",");

        urlList = new ArrayList<String>();

        while (token.hasMoreTokens()) {
            urlList.add(token.nextToken());

        }
    }

web.xml web.xml中

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>SpringMVCHibernate</display-name>

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>


    <filter>
        <filter-name>SessionFilter</filter-name>
        <filter-class>com.common.dao.SessionFilter</filter-class>
        <init-param>
            <param-name>avoid-urls</param-name>
            <param-value>index.jsp</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>SessionFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
:
:
:

To simple and short Answer for your Question: 为了简单而简短地回答您的问题:

To avoid this , you should have a return statement , or avoid redirecting or forwarding request , or these kind of things should be done by the last filter in the filter chain. 为了避免这种情况,您应该有一个return语句,或者避免重定向或转发请求,或者这些事情应该由过滤器链中的最后一个过滤器来完成。

For More Details Explanation you can read below : 有关更多详细信息,您可以阅读以下内容:

This Exception occurs when you try to send response again when the response is already committed and flushed to user. 当您已经提交了响应并将其刷新给用户时,尝试再次发送响应时,会发生此异常。 For Example : 例如 :

Here in below example code ,first the request will be forwarded to index_test.jsp and response will be flushed to user , then the control will again come back to filter and try to send another response (redirect)to user , and it will fail. 在下面的示例代码中,首先将请求转发到index_test.jsp并将响应刷新给用户,然后控件再次回到过滤器并尝试向用户发送另一个响应(重定向),它将失败。

Usually we check multiple conditions in filter and accordingly forward and redirect , if two conditions are met , then it will create a problem . 通常我们在过滤器中检查多个条件并相应地转发和重定向,如果满足两个条件,就会产生问题。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 

  request.getRequestDispatcher("index_test.jsp").forward(request, response);
  ((HttpServletResponse)response).sendRedirect("new.jsp");
  chain.doFilter(request, response);
 }

Solution for your case : 您的情况的解决方案:

To avoid this , you should have a return statement , or avoid redirecting or forwarding request , or these kind of things should be done by the last filter in the filter chain. 为了避免这种情况,您应该有一个return语句,或者避免重定向或转发请求,或者这些事情应该由过滤器链中的最后一个过滤器来完成。

So you could change your code as : 因此,您可以将代码更改为:

public class SessionFilter implements Filter {

    private ArrayList<String> urlList;

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String url = request.getServletPath();
        boolean allowedRequest = false;

        if(urlList.contains(url)) {
            allowedRequest = true;
        }

        if (!allowedRequest) {
            HttpSession session = request.getSession(false);
            if (null == session) {
                System.out.println("preparing for redirect");
                response.sendRedirect("index.jsp");
                return;
            }
        }

        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        System.out.println("entered init");
        String urls = config.getInitParameter("avoid-urls");
        StringTokenizer token = new StringTokenizer(urls, ",");

        urlList = new ArrayList<String>();

        while (token.hasMoreTokens()) {
            urlList.add(token.nextToken());

        }
    }

Its Obvious right : 其明显的权利:

System.out.println("preparing for redirect");
   response.sendRedirect("index.jsp");
   return; 

We are have return after that statement. 那句话之后,我们已经回来了。 So further execution wont happen so u are not getting exception. 因此不会再执行任何操作,因此您不会出现异常。

See we cant involve both filtering and Redirect or Forward in same block it will give IllegalStateException because : This Exception occurs when you try to send response again when the response is already committed and flushed to user 看到我们不能在同一块中同时涉及过滤和重定向或转发,它将提供IllegalStateException,因为:当您已经提交了响应并将其刷新给用户时,尝试再次发送响应时,将发生此异常

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM