SSH框架,使用Filter判断Session是否过期,过期则转到SessionTimeOut.jsp页面,此页面会自动转到登录页面。
SessionTimeOutFilter.java如下:
public class SessionTimeOutFilter implements Filter {
public void destroy() {}
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpSession session = request.getSession();
String currentPage = request.getRequestURI().replace(request.getContextPath(), "");
currentPage = currentPage.replace("/", "");
if(currentPage != null && !"login.do".equals(currentPage) 
&& session.getAttribute(Constants.LOGIN_SESSION_NAME) == null){
servletRequest.getRequestDispatcher("/SessionTimeOut.jsp").forward(servletRequest, servletResponse);
return;
}

chain.doFilter(servletRequest, servletResponse);
}
public void init(FilterConfig filterConfig) throws ServletException {}
}web.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 <filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter> 
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext-*.xml</param-value>
</context-param>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>sessionTimeoutFilter</filter-name>
<filter-class>com.****.web.filter.SessionTimeOutFilter</filter-class>
 </filter>
 <filter-mapping>
<filter-name>sessionTimeoutFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  <servlet>
           <servlet-name>log4j-init</servlet-name>
           <servlet-class>com.besttone.common.util.Log4jInit</servlet-class>
           <init-param>
             <param-name>log4j</param-name>
             <param-value>WEB-INF/conf/log4j.properties</param-value>
           </init-param>
           <load-on-startup>1</load-on-startup>
   </servlet>
  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <init-param>
      <param-name>debug</param-name>
      <param-value>3</param-value>
    </init-param>
    <init-param>
      <param-name>detail</param-name>
      <param-value>3</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
   <!-- DWR -->
  <servlet>
    <servlet-name>dwr-invoker</servlet-name>
    <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
    <init-param>
      <description>
      </description>
      <param-name>debug</param-name>
      <param-value>true</param-value>
    </init-param>    
  </servlet>
  <servlet-mapping>
    <servlet-name>dwr-invoker</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
  </servlet-mapping>
  <session-config>   
    <session-timeout>30</session-timeout>   
  </session-config> 
  </web-app>大部分情况下,过滤器是没有问题的,但是有时会出现NullPointerException,经判断是因为chain.doFilter(servletRequest, servletResponse)这行代码中chain为null导致,如果重新刷新一下页面,这个异常也许就没啦,只是偶尔会碰到这个异常。不知道问题出现在哪里?该如何解决,请各位指点。

解决方案 »

  1.   

    servletRequest, servletResponse
    检查一下这两个变量了,确定一下它们什么时候会变成null、。
      

  2.   

    chain 为 null 没理由
      

  3.   


    servletRequest, servletResponse这两个变量一直没有null,出现异常的时候,调试发现是chain变成null了,所以才出错
      

  4.   


    我也很纳闷,chian怎么会null了,不过从异常日志看,确实是chain变成null了,而且这个异常出现机率比较小,本机调试跟踪不到,所以也找不出问题出在哪里了。
      

  5.   

    这个是出错时的异常信息:
    javax.servlet.ServletException
        at org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:523)
        at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
        at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
        at com.××××.web.filter.SessionTimeOutFilter.doFilter(SessionTimeOutFilter.java:39)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)
        at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)
        at java.lang.Thread.run(Thread.java:595) 
    SessionTimeOutFilter.java:39行的代码为:chain.doFilter(servletRequest, servletResponse);
      

  6.   

    如果真是chain为空引起,那就有可能是框架引起的,那你只能用时判定一下chain是否为空啦,不为空时才做chain.doFilter(servletRequest, servletResponse); 
      

  7.   

    org.apache.catalina.core.ApplicationFilterChain.doFilter?
    不使用的servlet的包?改用servlet的包式一下吧
      

  8.   

    这样做可以避免NullPointerException,但如果chain为空,请求不能顺着链继续处理下去,也就得不到正确的结果,说明系统还是有问题存在,所以感觉这种做法不是正常解决之道
      

  9.   

    ApplicationFilterChain应该在catalina.jar包里,而SessionTimeOutFilter是实现servlet-api.jar包里的javax.servlet.Filter,这样应该没有问题吧?你说的改用servlet包,具体怎么改用呢?
      

  10.   

    javax.servlet.ServletException 
        at org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:523) 
        at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421) 
        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224) 
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194) 
        at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) 
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:710) 
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) 
        at com.××××.web.filter.SessionTimeOutFilter.doFilter(SessionTimeOutFilter.java:39) 
    这个说明根本不是chain为null问题,可以说不是你的Filter问题,它已经正确处理了请求了。只是可能是你后面调用的代码出错你应该看下面一段的错误才是真正的异常