定义拦截器,实现HandlerInterceptor
接口。接口中提供三个方法。java
public class HandlerInterceptor1 implements HandlerInterceptor{ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //return false表示拦截,不向下执行 //return true表示放行 return false; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
能够从名称和参数看出各个接口的顺序和做用:web
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
springmvc拦截器针对HandlerMapping进行拦截设置,若是在某个HandlerMapping中配置拦截,通过该HandlerMapping映射成功的handler最终使用该拦截器。spring
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="handlerInterceptor1"/> <ref bean="handlerInterceptor2"/> </list> </property> </bean> <bean id="handlerInterceptor1" class="com.tianlang.intercapter.HandlerInterceptor1"/> <bean id="handlerInterceptor2" class="com.tianlang.intercapter.HandlerInterceptor2"/>
通常不推荐使用。session
springmvc配置相似全局的拦截器,springmvc框架将配置的相似全局的拦截器注入到每一个HandlerMapping中。mvc
<!--拦截器 --> <mvc:interceptors> <!--多个拦截器,顺序执行 --> <mvc:interceptor> <!-- /**表示全部url包括子url路径 --> <mvc:mapping path="/**"/> <bean class="com.tianlang.interceptor.HandlerInterceptor1"></bean> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.tianlang.interceptor.HandlerInterceptor2"></bean> </mvc:interceptor> </mvc:interceptors>
测试多个拦截器各个方法执行时机app
访问/items/queryItems.action
框架
DEBUG [http-apr-8080-exec-1] - DispatcherServlet with name 'springmvc' processing GET request for [/ssm1/items/queryItems.action] DEBUG [http-apr-8080-exec-1] - Looking up handler method for path /items/queryItems.action DEBUG [http-apr-8080-exec-1] - Returning handler method [public org.springframework.web.servlet.ModelAndView com.iot.learnssm.firstssm.controller.ItemsController.queryItems(javax.servlet.http.HttpServletRequest,com.iot.learnssm.firstssm.po.ItemsQueryVo) throws java.lang.Exception] DEBUG [http-apr-8080-exec-1] - Returning cached instance of singleton bean 'itemsController' DEBUG [http-apr-8080-exec-1] - Last-Modified value for [/ssm1/items/queryItems.action] is: -1 HandlerInterceptor1...preHandle HandlerInterceptor2...preHandle DEBUG [http-apr-8080-exec-1] - Fetching JDBC Connection from DataSource DEBUG [http-apr-8080-exec-1] - Registering transaction synchronization for JDBC Connection DEBUG [http-apr-8080-exec-1] - Returning JDBC Connection to DataSource HandlerInterceptor2...postHandle HandlerInterceptor1...postHandle DEBUG [http-apr-8080-exec-1] - Rendering view [org.springframework.web.servlet.view.JstlView: name 'items/itemsList'; URL [/WEB-INF/jsp/items/itemsList.jsp]] in DispatcherServlet with name 'springmvc' DEBUG [http-apr-8080-exec-1] - Added model object 'itemtypes' of type [java.util.HashMap] to request in view with name 'items/itemsList' DEBUG [http-apr-8080-exec-1] - Added model object 'itemsQueryVo' of type [com.iot.learnssm.firstssm.po.ItemsQueryVo] to request in view with name 'items/itemsList' DEBUG [http-apr-8080-exec-1] - Added model object 'org.springframework.validation.BindingResult.itemsQueryVo' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'items/itemsList' DEBUG [http-apr-8080-exec-1] - Added model object 'itemsList' of type [java.util.ArrayList] to request in view with name 'items/itemsList' DEBUG [http-apr-8080-exec-1] - Forwarding to resource [/WEB-INF/jsp/items/itemsList.jsp] in InternalResourceView 'items/itemsList' HandlerInterceptor2...afterCompletion HandlerInterceptor1...afterCompletion DEBUG [http-apr-8080-exec-1] - Successfully completed request
总结:preHandle方法按顺序执行,postHandle和afterCompletion按拦截器配置的逆向顺序执行。jsp
2.拦截器1放行,拦截器2不放行post
DEBUG [http-apr-8080-exec-8] - DispatcherServlet with name 'springmvc' processing GET request for [/ssm1/items/queryItems.action] DEBUG [http-apr-8080-exec-8] - Looking up handler method for path /items/queryItems.action DEBUG [http-apr-8080-exec-8] - Returning handler method [public org.springframework.web.servlet.ModelAndView com.iot.learnssm.firstssm.controller.ItemsController.queryItems(javax.servlet.http.HttpServletRequest,com.iot.learnssm.firstssm.po.ItemsQueryVo) throws java.lang.Exception] DEBUG [http-apr-8080-exec-8] - Returning cached instance of singleton bean 'itemsController' DEBUG [http-apr-8080-exec-8] - Last-Modified value for [/ssm1/items/queryItems.action] is: -1 HandlerInterceptor1...preHandle HandlerInterceptor2...preHandle HandlerInterceptor1...afterCompletion DEBUG [http-apr-8080-exec-8] - Successfully completed request
总结:测试
3.两个拦截器都不放
DEBUG [http-apr-8080-exec-9] - DispatcherServlet with name 'springmvc' processing GET request for [/ssm1/items/queryItems.action] DEBUG [http-apr-8080-exec-9] - Looking up handler method for path /items/queryItems.action DEBUG [http-apr-8080-exec-9] - Returning handler method [public org.springframework.web.servlet.ModelAndView com.iot.learnssm.firstssm.controller.ItemsController.queryItems(javax.servlet.http.HttpServletRequest,com.iot.learnssm.firstssm.po.ItemsQueryVo) throws java.lang.Exception] DEBUG [http-apr-8080-exec-9] - Returning cached instance of singleton bean 'itemsController' DEBUG [http-apr-8080-exec-9] - Last-Modified value for [/ssm1/items/queryItems.action] is: -1 HandlerInterceptor1...preHandle DEBUG [http-apr-8080-exec-9] - Successfully completed request
总结:
4.拦截器1不放行,拦截器2放行
DEBUG [http-apr-8080-exec-8] - DispatcherServlet with name 'springmvc' processing GET request for [/ssm1/items/queryItems.action] DEBUG [http-apr-8080-exec-8] - Looking up handler method for path /items/queryItems.action DEBUG [http-apr-8080-exec-8] - Returning handler method [public org.springframework.web.servlet.ModelAndView com.iot.learnssm.firstssm.controller.ItemsController.queryItems(javax.servlet.http.HttpServletRequest,com.iot.learnssm.firstssm.po.ItemsQueryVo) throws java.lang.Exception] DEBUG [http-apr-8080-exec-8] - Returning cached instance of singleton bean 'itemsController' DEBUG [http-apr-8080-exec-8] - Last-Modified value for [/ssm1/items/queryItems.action] is: -1 HandlerInterceptor1...preHandle DEBUG [http-apr-8080-exec-8] - Successfully completed request
和两个拦截器都不行的结果一致,由于拦截器1先执行,没放行
根据测试结果,对拦截器应用。
好比:统一日志处理拦截器,须要该拦截器preHandle必定要放行,且将它放在拦截器连接中第一个位置。
好比:登录认证拦截器,放在拦截器连接中第一个位置。权限校验拦截器,放在登录认证拦截器以后。(由于登录经过后才校验权限,固然登陆认证拦截器要放在统一日志处理拦截器后面)
@Controller public class LoginController { // 登录 @RequestMapping("/login") public String login(HttpSession session, String username, String password) throws Exception { // 在session中保存用户身份信息 session.setAttribute("username", username); // 重定向到商品列表页面 return "redirect:/items/queryItems.action"; } // 退出 @RequestMapping("/logout") public String logout(HttpSession session) throws Exception { // 清除session session.invalidate(); // 重定向到商品列表页面 return "redirect:/items/queryItems.action"; } }
/** * 登录认证拦截器 */ public class LoginInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //获取请求的url String url = request.getRequestURI(); //判断url是不是公开地址(实际使用时将公开 地址配置配置文件中) if(url.indexOf("login.action")>=0){ //若是进行登录提交,放行 return true; } //判断session HttpSession session = request.getSession(); //从session中取出用户身份信息 String username = (String) session.getAttribute("username"); if(username != null){ //身份存在,放行 return true; } //执行这里表示用户身份须要认证,跳转登录页面 request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response); return false; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("LoginInterceptor...postHandle"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("LoginInterceptor...afterCompletion"); } }
<!--拦截器 --> <mvc:interceptors> <!--多个拦截器,顺序执行 --> <!-- 登录认证拦截器 --> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.tianlang.interceptor.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>