SpringMVC学习笔记10——拦截器

SpringMVC 中的 Interceptor 拦截器作用是拦截指定的用户请求(对请求作判断处理),并进行相应的预处理与后处理,需要实现 HandlerInterceptor 接口;拦截器是全局的,一个项目中可以有零个或多个拦截器,可以对多个Controller进行拦截

注意和过滤器的区别:过滤器是用户过滤请求参数,设置编码字符集等工作;拦截器是用于拦截用户请求,做请求的判断处理的
拦截器常用于:用户登陆处理,权限检查,记录日志
使用步骤:
1. 定义类实现 HandlerInterceptor 接口
2. 在springmvc配置文件中声明拦截器,让框架知道拦截器的存在
拦截器执行时间:
1. 在controller类中方法执行之前(请求处理之前)执行拦截器
2. 在控制器方法执行后也可以执行拦截器
3. 在请求处理完成后也会执行拦截器

一个拦截器的程序

实现步骤:

  1. 创建控制器类
@Controller
public class Mycontroller {

    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(String name,Integer age){

        System.out.println("我是控制器方法");

        ModelAndView mv=new ModelAndView();

        mv.addObject("msg",name);
        mv.addObject("fun",age);

        mv.setViewName("show");

        return mv;
    }

}
  1. 创建一个普通类作为拦截器使用
    1. 实现 HandlerInterceptor 接口
    2. 实现接口中的三个方法
public class MyInterceptor implements HandlerInterceptor {//拦截器类:拦截用户请求

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器的preHandle执行。。。");
        //给浏览器一个返回结果
        request.getRequestDispatcher("/tips.jsp").forward(request,response);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("拦截器的postHandle执行。。。");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("拦截器的afterCompletion执行。。。");
    }
}
  • preHandle:预处理方法
    参数:Object handler,被拦截的对象
    返回值boolean:truefalse
    特点:
    1. 方法在控制器方法前执行,用户的请求首先到达此方法
    2. 在这个方法中可以获取请求信息,验证请求是都符合要求,可以验证用户是否登陆,验证用户是否有权限访问某个连接请求(url);验证成功===>可以放行请求,此时控制器方法才能执行,验证失败===>可以阶段请求,请求不能被处理

  • postHandle:后处理方法
    参数:ModelAndView modelAndView,处理器方法的返回值
    特点:
    1. 在处理器方法之后执行
    2. 能够获取处理器方法的返回值modelAndView,可以修改modelAndView中的数据和视图,可以影响最后的执行结果
    3. 主要时对原来的执行结果做二次修正

  • afterCompletion:最后执行的方法
    参数:Exception ex,程序中发生的异常
    特点:
    1. 在请求处理完成后执行的,框架中规定时当你的视图处理完成后(对视图执行了forward),就认为请求处理完成
    2. 一般做资源回收的工作,程序请求过程中创建了一些对象,在这里可以将其删除,把占用的内存回收

  1. 创建jsp
  2. 创建springmvc配置文件
    1. 组件扫描器
    2. 声明拦截器,并指定拦截的请求uri地址

    
        
        
            
            
            
            
        
    
运行结果
在index页面输入信息后,结果页面

SpringMVC学习笔记10——拦截器_第1张图片

我们可以在控制台看到方法执行的顺序(此时preHandle返回true)

执行的顺序:preHandle–>控制器方法–>postHandle–>afterCompletion
SpringMVC学习笔记10——拦截器_第2张图片
preHandle返回false,再来一遍

结果页面

SpringMVC学习笔记10——拦截器_第3张图片

控制台

SpringMVC学习笔记10——拦截器_第4张图片
可以看到,当postHandle返回false时,请求会被拦截,项目只执行了postHandle方法,所以我们要在postHandle中写判断的逻辑语句,对请求进行拦截;可以把拦截器看作是多个Controller中公用的功能,集中到拦截器统一处理,使用的aop的思想
SpringMVC学习笔记10——拦截器_第5张图片


postHandle和afterCompletion

postHandle

我们可以在postHandle中试着修改返回值modelAndView(记得把返回值改回true和把转发语句去掉 )

//对原来的方法进行调整
        if(modelAndView != null){
            //修改数据
            modelAndView.addObject("mydate",new Date());
            //修改视图
            modelAndView.setViewName("other");
        }

SpringMVC学习笔记10——拦截器_第6张图片


afterCompletion

我们用这个方法计算整个拦截器执行的时间
首先设置一个全局变量保存执行时间private long btime=0;
postHandle 中给btime赋值当前时间btime=System.currentTimeMillis();
afterCompletion 设置结束的当前时间long etime=System.currentTimeMillis();

运行结果

SpringMVC学习笔记10——拦截器_第7张图片

多个拦截器

返回true:再创建一个拦截器类,然后在配置文件中再声明多一个拦截器,要注意,这里使用的是ArrayList来保存拦截器的声明,有顺序,先声明的先执行;两个返回值都为true


        
        
            
            
        
        
        
            
            
        
    
运行结果

SpringMVC学习笔记10——拦截器_第8张图片
我们可以看到,先执行第一个拦截器,再执行第二个拦截器,然后执行控制器方法,然后反过来执行拦截器
SpringMVC学习笔记10——拦截器_第9张图片

1-拦截器为true,2-拦截器为false时:执行结果顺序: 1-preHandle==>2-preHandle==>1-afterCompletion
1-拦截器为false,2-拦截器为 true | false 时:执行结果顺序: 1-preHandle

拦截器执行链

SpringMVC学习笔记10——拦截器_第10张图片


拦截器和过滤器的区别

  1. 过滤器是servlet中的对象, 拦截器是框架中的对象
  2. 过滤器实现Filter接口的对象, 拦截器是实现HandlerInterceptor
  3. 过滤器是用来设置requestresponse的参数,属性的,侧重对数据过滤的。
    拦截器是用来验证请求的,能截断请求。
  4. 过滤器是在拦截器之前先执行的。
  5. 过滤器是tomcat服务器创建的对象,拦截器是springmvc容器中创建的对象
  6. 过滤器是一个执行时间点,拦截器有三个执行时间点
  7. 过滤器可以处理jsp,js,html等等
    拦截器是侧重拦截对Controller的对象。 如果你的请求不能被DispatcherServlet接收, 这个请求不会执行拦截器内容
  8. 拦截器拦截普通类方法执行,过滤器过滤servlet请求响应

权限拦截器举例

简单使用拦截器模拟验证登陆用户是否有权限访问系统,这里只展示新增的代码,其他代码和配置和前面一致

创建login.jsp模拟登陆(将用户信息放入session)
<%
  session.setAttribute("name","zs");
%>
创建logout.jsp模拟退出系统(从session删除数据)
<%
 session.removeAttribute("name");
%>
创建拦截器,从session中获取yoghurt登陆信息数据,验证是否能访问系统
public class MyInterceptor implements HandlerInterceptor {//拦截器类:拦截用户请求

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //验证登陆用户的信息,正确返回true,错误返回false
        System.out.println("1111-拦截器的preHandle执行。。。");
        String loginName="";
        //从session获取name的值
        Object attr=request.getSession().getAttribute("name");
        if(attr != null){
            loginName= (String) attr;
        }
        //判断登陆的账号是否符合要求
        if(!"zs".equals(loginName)){
            //不能访问系统
            //给用户提示
            request.getRequestDispatcher("/tips.jsp").forward(request,response);
            return false;
        }
        //zs登陆
        return true;
    }
}

运行结果
在首页无论是否输入zs,都跳转到登陆失败

我们直接在地址栏输入login.jsp

SpringMVC学习笔记10——拦截器_第11张图片

返回首页,无论输入zs还是lisi都可顺利登陆

SpringMVC学习笔记10——拦截器_第12张图片
SpringMVC学习笔记10——拦截器_第13张图片

在地址栏访问logout.jsp,再返回首页,变回了无论输入zs还是lisi都无法登陆

条条:该学习笔记是记录了我的学习过程,学习自动力节点王鹤老师,有不对的地方欢迎指出

你可能感兴趣的:(自学,初学,过滤器,java,spring,jsp)