zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    【域控】获取域控用户
    【MongoDB】开启认证权限
    【MongoDB】 安装为windows services
    【 Quartz】使用 JobListener (任务监听器可实现) 我想在一个任务执行后在执行第二个任务怎么办呢
    【多路复用】I/O多路复用
    静态类和静态类成员
    C#
    response.redirect和server.Transfer的差别详解
    DataReader
    受管制的代码和强类型系统
  • 原文地址:https://www.cnblogs.com/tenWood/p/6338018.html
Copyright © 2011-2022 走看看