Spring mvc Interceptor 解决Session超时配置流程

来源:互联网 发布:unity3d做2d游戏 编辑:程序博客网 时间:2024/05/19 12:29

最近公司内部框架中对Session超时这一功能未实现,由于采用iframe结构,Session超时后,当点击左侧系统菜单时,会在iframe的右侧再次弹出登陆框。

该问题是由于没有设置拦截器造成。

添加拦截器思路:当Session超时后,用户点击menu时,需要用Interceptor进行前项拦截,并判断此时session中是否还存在用户信息,如果不存在,将其指定登陆主页面。

如下代码:

1)首先在applicationContext-mvc.xml中加入mvc:interceptor标签。

[html] view plain copy
  1.      
  2.    <!-- session timeout interceptor -->  
  3. <mvc:interceptors>  
  4.     <mvc:interceptor>  
  5.         <mvc:mapping path="/*/*" />  
  6.         <bean class="com.lenovo.lstp.mam.interceptor.SessionTimeoutInterceptor" >  
  7.             <property name="allowUrls">    
  8.                 <list>    
  9.                   <value>/login/login.do</value>    
  10.                   <value>/common/language.do</value>    
  11.                 </list>    
  12.             </property>    
  13.         </bean>  
  14.     </mvc:interceptor>  
  15. </mvc:interceptors>  
  16.   
  17. <!-- exception handler -->  
  18.    <bean id="handlerExceptionResolver"  
  19.     class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" >  
  20.     <property name="exceptionMappings">  
  21.         <props>  
  22.             <prop key="com.lenovo.lstp.mam.exception.SessionTimeoutException">/blank</prop>  
  23.         </props>  
  24.     </property>  
  25.    </bean>  

上述代码中首先要在系统内部包中创建一个名为SessionTimeoutInterceptor的拦截器,并指定允许的访问的url为list中集合。

当用户从此地址登陆后,无需进行拦截。

SessionTimeoutException中为当拦截生效后,会throw出该异常。

并进入blank.jsp页面。

2)第二步则要进行拦截器SessionTimeoutInterceptor创建,代码如下:

[java] view plain copy
  1. /** 
  2.      * Session超时,拦截访问 
  3.      *  
  4.      */  
  5.     public boolean preHandle(HttpServletRequest request,  
  6.             HttpServletResponse response, Object handler) throws Exception {  
  7.         String requestUrl = request.getRequestURI();  
  8.           
  9.         for(String url : allowUrls) {  
  10.             if(requestUrl.endsWith(url)) {  
  11.                 return true;  
  12.             }  
  13.         }  
  14.           
  15.         String session = (String) WebUtils.getSessionAttribute(request,  
  16.                 "username");  
  17.         if(session != null) {  
  18.             return true;  
  19.         }else {  
  20.             throw new SessionTimeoutException();  
  21.         }  
  22.           
  23.     }  

除了被允许的Url,其他任何Url,只要没有检查到Session的存在,则会抛出SessionTimeoutException,用于去指向登陆页面,SessionTimeoutException中则无需写入任何操作。

3)由于iframe布局会造成登陆框内嵌问题,因此可以通过以下方式实现,代码如下:

[javascript] view plain copy
  1. var session = "${user}";  
  2. if("" == session){  
  3.     top.location = "transfer.jsp";  
  4. }  
  5. if (null == session) {  
  6.  top.location = "transfer.jsp";  
  7. }  
在blank.jsp中引入一个中转页transfer.jsp。这个页面用于进行post跳转,再次去请求login.do。

top.location为指定在主页面展示,而不是在内嵌的页面展示。

4)第四步则需要进行二次login.do的请求,代码如下:

[plain] view plain copy
  1. <script type="text/javascript">  
  2. $(document).ready(function(){  
  3.     document.transfer.submit();  
  4. });  
  5. </script>  
  6.   
  7.   
  8. <body>  
  9. <form name="transfer" action="login/login.do" method="post"></form>  
  10.   
  11. </body>  

当进入该页面,会自动提交login.do请求,但是之前由于页面允许了login.do的进入,该操作可以在loginControll中进行判断。

代码如下:

[java] view plain copy
  1. /* After session timeout, check dto's username, and return login.jsp. */  
  2.         if(dto.getUsername() == null) {   
  3.             ModelAndView mv = new ModelAndView("login");  
  4.             return mv;  
  5.         }  
  6.           

在login方法中引入该判断 ,对二次访问该Controll的信息进行判断,如果用户名没有的话,则自动跳回login.jsp页面重新输入。

此时,已大功告成,如果登陆页面有其他链接,可以在allowurl去进行配置。


以上转载自http://blog.csdn.net/fly2749/article/details/8702855


0 0