美文网首页我爱编程
实现拦截器功能

实现拦截器功能

作者: aorld | 来源:发表于2018-06-21 12:22 被阅读0次

    1.拦截器概述

    什么是拦截器?

    拦截器主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。

    流程图


    5.jpg
    HandlerInterceptor接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。

    preHandle(): 这个方法在业务处理器处理请求之前被调用,SpringMVC 中的Interceptor是链式调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。

    postHandle():这个方法在当前请求进行处理之后,也就是Controller方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行。

    afterCompletion():该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。afterCompletion方法被调用的方向和perHandle也是相反的,先声明的Interceptor的afterCompletion方法后执行。

    2.项目结构

    22.jpg

    3.代码实现

    spring-mvc.xml:配置拦截器.

    (1)用于拦截用户是否登录,但是用户访问登录页面和注册页面时就不需要拦截了,这时就需要用到这个标签了 <mvc:execlude-mapping />。

    (2)设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法。

    <mvc:resources mapping="/views/**" location="/WEB-INF/views/"/>
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.ssm.util.TimeInterceptor">
                <property name="startTime" value="8"/>
                <property name="endTime" value="19"/>
            </bean>
        </mvc:interceptor>
        <!--/** 表示所有的url,包括子url路径-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <!--不拦截某个请求-->
            <mvc:exclude-mapping path="/login"/>
            <mvc:exclude-mapping path="/implAdd"/>
            <bean class="com.ssm.util.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
    

    UserController创建Session对象,拦截器获取对象进行判断。

    (1)request.getParameter():是一种取参数的方法。把jsp文件中的数据读取到出来。然后就可以封装利用起来。如果有重复的名,则返回第一个的值 . 接收一般变量

    (2)request.getSession().setAttribute(key,value). 在其他地方通过request.getSession().getAttribute(key) 获取数据。

    public int login(String login_name, String password,HttpServletRequest request) {
        String lgName = request.getParameter("login_name");
        request.getSession().setAttribute("lgName", lgName);
    }
    

    TimeInterceptor拦截器: 没有在特定的时间访问网页,跳转到指定站点。

    public class TimeInterceptor extends HandlerInterceptorAdapter {
    
    private int startTime;
    
    private int endTime;
    
    public int getStartTime() {
        return startTime;
    }
    
    public void setStartTime(int startTime) {
        this.startTime = startTime;
    }
    
    public int getEndTime() {
        return endTime;
    }
    
    public void setEndTime(int endTime) {
        this.endTime = endTime;
    }
    
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) throws Exception {
       // System.out.println("我是TimeInterceptor的preHandle");
        super.afterCompletion(request, response, object, ex);
    }
    
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView modelAndView) throws Exception {
       // System.out.println("我是TimeInterceptor的postHandle");
        super.postHandle(request, response, object, modelAndView);
    }
    
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
        //System.out.println("我是TimeInterceptor的preHandle");
        Calendar cal = Calendar.getInstance();
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        if (startTime <= hour && hour < endTime) {
            return true;
        } else {
            response.sendRedirect("http://www.baidu.com");
            return false;
        }
    }
    }
    

    LoginInterceptor拦截器:当你没有登录时,自动跳转到登录页面。

    (1)request.getRequestURI():返回除去host(域名或者ip)部分的路径

    (2)JSP中页面跳转response.sendRedirect()和request.getRequestDispatcher()的区别:https://blog.csdn.net/tuke_tuke/article/details/47282125

    public class LoginInterceptor extends HandlerInterceptorAdapter {
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object obj, Exception ex) throws Exception {
       // System.out.println("我是LoginInterceptor的afterCompletion");
        super.afterCompletion(request, response, obj, ex);
    }
    
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView modelAndView) throws Exception {
       // System.out.println("我是LoginInterceptor的postHandle");
        super.postHandle(request, response, obj, modelAndView);
    }
    
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
        String url = request.getRequestURI();
       // System.out.println("我是LoginInterceptor的preHandle");
        System.out.println("走拦截器:" + url + ":" + url.contains("/login"));
        if (url.contains("/login")) {
            return true;
        }
        if (url.contains("/toAdd")) {
            return true;
        }
        //获取Session
        HttpSession session = request.getSession();
        String lgName = (String) session.getAttribute("lgName");
        if (lgName != null) {
            return true;
        } else {
            //不符合条件的,跳转到登录界面
           // request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);
            response.sendRedirect("/login");
            return false;
        }
    }
    

    4.截图

    http://localhost:8080/login

    8.jpg

    http://localhost:8080/userList

    7.jpg

    没有登录时,重定向到localhost:8080/login 。登录后保存Session对象,可以直接访问localhost:8080/userList 。

    GIF.gif

    相关文章

      网友评论

        本文标题:实现拦截器功能

        本文链接:https://www.haomeiwen.com/subject/zgyqyftx.html