首页 > 代码库 > springMVC学习(12)-使用拦截器

springMVC学习(12)-使用拦截器

一、拦截器配置和测试:

1)定义两个拦截器,(要实现HandlerInterceptor接口)

HandlerInterceptor1:

技术分享
 1 package com.cy.interceptor;
 2 
 3 import javax.servlet.http.HttpServletRequest;
 4 import javax.servlet.http.HttpServletResponse;
 5 
 6 import org.springframework.web.servlet.HandlerInterceptor;
 7 import org.springframework.web.servlet.ModelAndView;
 8 
 9 public class HandlerInterceptor1 implements HandlerInterceptor{
10     
11     //进入 Handler方法之前执行
12     //用于身份认证、身份授权
13     //比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
14     @Override
15     public boolean preHandle(HttpServletRequest request,
16             HttpServletResponse response, Object handler) throws Exception {
17         System.out.println("HandlerInterceptor1--------------------preHandle");
18         
19         //return false表示拦截,不向下执行
20         //return true表示放行
21         return true;
22     }
23     
24     //进入Handler方法之后,返回modelAndView之前执行
25     //应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
26     @Override
27     public void postHandle(HttpServletRequest request,
28             HttpServletResponse response, Object handler,
29             ModelAndView modelAndView) throws Exception {
30         System.out.println("HandlerInterceptor1--------------------postHandle");
31     }
32     
33     //执行Handler完成执行此方法
34     //应用场景:统一异常处理,统一日志处理
35     @Override
36     public void afterCompletion(HttpServletRequest request,
37             HttpServletResponse response, Object handler, Exception ex)
38             throws Exception {
39         System.out.println("HandlerInterceptor1--------------------afterCompletion");
40     }
41 }
View Code

HandlerInterceptor2:

技术分享
 1 public class HandlerInterceptor2 implements HandlerInterceptor{
 2 
 3     @Override
 4     public boolean preHandle(HttpServletRequest request,
 5             HttpServletResponse response, Object handler) throws Exception {
 6         System.out.println("HandlerInterceptor2--------------------preHandle");
 7         return true;
 8     }
 9 
10     @Override
11     public void postHandle(HttpServletRequest request,
12             HttpServletResponse response, Object handler,
13             ModelAndView modelAndView) throws Exception {
14         System.out.println("HandlerInterceptor2--------------------postHandle");
15     }
16 
17     @Override
18     public void afterCompletion(HttpServletRequest request,
19             HttpServletResponse response, Object handler, Exception ex)
20             throws Exception {
21         System.out.println("HandlerInterceptor2--------------------afterCompletion");
22     }
23 }
View Code

2)配置拦截器:

springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。

配置如下:

技术分享
 1 <!--拦截器 -->
 2     <mvc:interceptors>
 3         <!--多个拦截器,顺序执行 -->
 4         <mvc:interceptor>
 5             <!-- /**表示所有url包括子url路径 -->
 6             <mvc:mapping path="/**"/>
 7             <bean class="com.cy.interceptor.HandlerInterceptor1"></bean>
 8         </mvc:interceptor>
 9         <mvc:interceptor>
10             <mvc:mapping path="/**"/>
11             <bean class="com.cy.interceptor.HandlerInterceptor2"></bean>
12         </mvc:interceptor>
13     </mvc:interceptors>
View Code

另外配置的方法:

springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该拦截器。(一般不推荐使用)

技术分享
 1 <bean
 2     class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
 3     <property name="interceptors">
 4         <list>
 5             <ref bean="handlerInterceptor1"/>
 6             <ref bean="handlerInterceptor2"/>
 7         </list>
 8     </property>
 9 </bean>
10 <bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
11 <bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>
View Code

3)测试:

测试多个拦截器各个方法的执行时机:

两个拦截器HandlerInterceptor1、2都放行,打印结果:

HandlerInterceptor1...preHandle

HandlerInterceptor2...preHandle

 

HandlerInterceptor2...postHandle

HandlerInterceptor1...postHandle

 

HandlerInterceptor2...afterCompletion

HandlerInterceptor1...afterCompletion

总结:

preHandle方法按顺序执行,

postHandle和afterCompletion按拦截器配置的逆向顺序执行。

关于执行其实可以看图理解:

技术分享

拦截器应用举例:

比如:统一日志处理拦截器,需要该 拦截器preHandle一定要放行,且将它放在拦截器链接中第一个位置。

比如:登陆认证拦截器,放在拦截器链接中第一个位置。权限校验拦截器,放在登陆认证拦截器之后。(因为登陆通过后才校验权限)

 

 

二、拦截器实现登陆认证:

 需求:

1、用户请求url

2、拦截器进行拦截校验

 如果请求的url是公开地址(无需登陆即可访问的url),让放行

 如果用户session 不存在跳转到登陆页面

 如果用户session存在放行,继续操作。

LoginController:

技术分享
 1 package com.cy.controller;
 2 
 3 import javax.servlet.http.HttpSession;
 4 
 5 import org.springframework.stereotype.Controller;
 6 import org.springframework.web.bind.annotation.RequestMapping;
 7 
 8 @Controller 
 9 public class LoginController {
10     
11     @RequestMapping("/login")
12     public String login(HttpSession session, String username, String password) throws Exception{
13         // 调用service进行用户身份验证
14         // ...
15 
16         // 在session中保存用户身份信息
17         session.setAttribute("username", username);
18         
19         // 重定向到商品列表页面
20         return "redirect:items/findItems";
21     }
22     
23     // 退出
24     @RequestMapping("/logout")
25     public String logout(HttpSession session) throws Exception {
26 
27         // 清除session
28         session.invalidate();
29 
30         return "redirect:items/findItems";
31     }
32 }
View Code

LoginInterceptor:

技术分享
 1 package com.cy.interceptor;
 2 
 3 import javax.servlet.http.HttpServletRequest;
 4 import javax.servlet.http.HttpServletResponse;
 5 import javax.servlet.http.HttpSession;
 6 
 7 import org.springframework.web.servlet.HandlerInterceptor;
 8 import org.springframework.web.servlet.ModelAndView;
 9 
10 /**
11  * 登陆认证拦截器
12  * @author chengyu
13  *
14  */
15 public class LoginInterceptor implements HandlerInterceptor{
16 
17     @Override
18     public boolean preHandle(HttpServletRequest request,
19             HttpServletResponse response, Object handler) throws Exception {
20         
21         //获取请求的url
22         String url = request.getRequestURI();
23         
24         //判断url是否是公开 地址(实际使用时将公开 地址配置配置文件中)
25         //这里公开地址是登陆提交的地址
26         if(url.indexOf("login.action") >= 0){
27             //如果进行登陆提交,放行
28             return true;
29         }
30         
31         HttpSession session = request.getSession();
32         String username = (String) session.getAttribute("username");
33         if(username!=null){
34             return true;
35         }
36         
37         //执行这里表示用户身份需要认证,跳转登陆页面
38         request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
39         return false;
40     }
41     
42     @Override
43     public void postHandle(HttpServletRequest request,
44             HttpServletResponse response, Object handler,
45             ModelAndView modelAndView) throws Exception {
46     }
47     @Override
48     public void afterCompletion(HttpServletRequest request,
49             HttpServletResponse response, Object handler, Exception ex)
50             throws Exception {
51     }
52 }
View Code

LoginInterceptor配置:

技术分享
 1 <!--拦截器 -->
 2     <mvc:interceptors>
 3         <!--多个拦截器,顺序执行 -->
 4         <!-- 登陆认证拦截器 -->
 5         <mvc:interceptor>
 6             <mvc:mapping path="/**"/>
 7             <bean class="com.cy.interceptor.LoginInterceptor"></bean>
 8         </mvc:interceptor>
 9         <mvc:interceptor>
10             <!-- /**表示所有url包括子url路径 -->
11             <mvc:mapping path="/**"/>
12             <bean class="com.cy.interceptor.HandlerInterceptor1"></bean>
13         </mvc:interceptor>
14         <mvc:interceptor>
15             <mvc:mapping path="/**"/>
16             <bean class="com.cy.interceptor.HandlerInterceptor2"></bean>
17         </mvc:interceptor>
18     </mvc:interceptors>
View Code

login.jsp:

技术分享
 1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 3 <html>
 4 <head>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6 <title>系统登陆</title>
 7 </head>
 8 <body>
 9 <form action="${pageContext.request.contextPath }/login.action" method="post">
10 用户账号:<input type="text" name="username" /><br/>
11 用户密码 :<input type="password" name="password" /><br/>
12 <input type="submit" value="登陆"/>
13 </form>
14 </body>
15 </html>
View Code

 

springMVC学习(12)-使用拦截器