拦截器

Posted mrchengs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拦截器相关的知识,希望对你有一定的参考价值。

 

 在开发是可能会遇到:某些网站只能希望几个特定的用户浏览,对于这种访问权限控制需要使用拦截器。

 

1、拦截器的概述

 spring MVC的拦截器与java Servlet的过滤器类似,主要用于拦截用户的请求做出响应的处理

通常在权限验证、记录请求信息的日志、判断用户手否登陆功能上。

 

1、拦截器的定义

 在spring MVC框架中定义一个拦截器需要对拦截器进行定义和配置,定义一个拦截器可以通过两种方式:

①、通过实现HandlerInterceptor接口或者HandlerInterceptor接口来实现定义

②、实现WebRequestInterceptor接口或者继承WebRequestInterceptor接口实现来定义。

 

 实例:

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

preHandle:在控制器的处理请求方法前执行,其返回值表示是否中断后续操作,返回true表示继续向下执行,返回为false表示终端后续操作。

postHandle:在控制器的处理请求方法调用之后、解析视图执行之前执行,可以通过此方法对请求域中的模型和视图做进一步的修改。

afterCompletion:在控制器的处理请求完成过后执行,即视图渲染结束后,可以通过此方法来实现一些资源的清理,记录日志信息等工作。

 

 2、拦截器的配置

 让自定义的拦截器生效需要在spring mvc的配置文件中进行配置,配置代码如下:

    <!--配置拦截器-->
    <mvc:interceptors>
        
        <!--配置一个全局的拦截器,拦截所有请求 -->
        <bean class="Interceptor.MyInterceptorAll"></bean>

       <mvc:interceptor>
           <mvc:mapping path="/**"/>
           <!--配置不需要拦截的路径-->
           <mvc:exclude-mapping path="/"></mvc:exclude-mapping>
           <!--表示匹配路径下的请求才进行拦截-->
           <bean class="Interceptor.MyInterceptor"></bean>
       </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <!--配置不需要拦截的路径-->
            <mvc:exclude-mapping path="/"></mvc:exclude-mapping>
            <!--表示匹配路径下的请求才进行拦截-->
            <bean class="Interceptor.MyInterceptor1"></bean>
        </mvc:interceptor>

    </mvc:interceptors>

<mvc:interceptors>元素用于配置一组拦截器,子元素<bean>定义的时全局拦截器,即拦截所有的请求。

<mvc:interceptor>元素定义的是指定路径的拦截器,子元素<mvc:mapping>用于配置拦截器作用的路径,

        该路径在path属性中定义 /** 代表拦截所有的i请求

<mvc:exclude-mapping path="/">:请求中包含不需要拦截的内容,在path属性中指定。

   

 这里需要注意的是:

这里的每个标签的顺序

 

2、拦截请求执行的流程

1、单个拦截器的执行流程

 直接看代码进行演示:

拦截类:

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("preHandle....");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle....");
    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion.....");
    }
}

 controller类:

@Controller
public class interceptorController {

    @RequestMapping("/gototest")
    public  String  test(){
        System.out.println("test....");
        return "test";
    }
}

 配置文件:

    <!--配置拦截器-->
    <mvc:interceptors>
       <mvc:interceptor>
           <mvc:mapping path="/gototest"/>
           <!--配置不需要拦截的路径-->
           <mvc:exclude-mapping path="/"></mvc:exclude-mapping>
           <!--表示匹配路径下的请求才进行拦截-->
           <bean class="Interceptor.MyInterceptor"></bean>
       </mvc:interceptor>
    </mvc:interceptors>

 前端页面

<body>
    拦截器的测试视图....
</body>

 访问请求之后:

技术分享图片

查看后台的打印顺序:

技术分享图片

 

 2、多个拦截器的执行流程

 在单个拦截器的基础上新建一个拦截器:

public class MyInterceptor1 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("preHandle11....");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle11....");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion11.....");
    }
}

 配置文件:

    <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/gototest"/>
            <!--配置不需要拦截的路径-->
            <mvc:exclude-mapping path="/"></mvc:exclude-mapping>
            <!--表示匹配路径下的请求才进行拦截-->
            <bean class="Interceptor.MyInterceptor"></bean>
        </mvc:interceptor>

        <mvc:interceptor>
            <mvc:mapping path="/gototest"/>
            <!--配置不需要拦截的路径-->
            <mvc:exclude-mapping path="/"></mvc:exclude-mapping>
            <!--表示匹配路径下的请求才进行拦截-->
            <bean class="Interceptor.MyInterceptor1"></bean>
        </mvc:interceptor>

    </mvc:interceptors>

 测试:

技术分享图片

 

 后台的顺序:

技术分享图片

 

 3、用户登陆的权限验证

 controller类:

@Controller
public class LoginController {
    //登陆页面初始化
    @RequestMapping("/toLogin")
    public  String logiin(){
        return "tologin";
    }
    //处理登陆功能
    @RequestMapping("/login")
    public String login(Users users, Model model, HttpSession session){
        System.out.println(users);

        if (users.getName().equals("admin") && users.getPwd().equals("123")){
            //登陆成功
            session.setAttribute("user",users);
            return "loginsuccess";
        }else {
            model.addAttribute("msg","账号或者密码错误!!!");
            return "tologin";
        }
    }
}

 拦截器的配置:

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("preHandle11....");
        Object object = httpServletRequest.getSession().getAttribute("user");
        if (object == null){
            httpServletRequest.getRequestDispatcher(httpServletRequest.getContextPath()+ "/toLogin").
                    forward(httpServletRequest,httpServletResponse);
            httpServletRequest.setAttribute("msg","没有权限进行登陆!!!");
            return  false;
        }else {
            return true;
        }
    }
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle11....");
    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion11.....");
    }
}

 配置文件:

 <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <!--配置不需要拦截的路径-->
            <mvc:exclude-mapping path="/toLogin"></mvc:exclude-mapping>
            <mvc:exclude-mapping path="/login"></mvc:exclude-mapping>
            <!--表示匹配路径下的请求才进行拦截-->
            <bean class="Interceptor.LoginInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

 前端页面:

 tologin.jsp

<body>
${msg}
<br>
<form action="<%=request.getContextPath()%>/login"  method="post">
    name:<input type="text" name="name" ><br>
    pwd:<input type="text" name="pwd" ><br>
    <input type="submit" value="submit">
</form>
</body>

 loginsuccess.jsp

<body>
welcome:${user.name}
</body>

 测试数据:

 技术分享图片

结果:

技术分享图片

 

以上是关于拦截器的主要内容,如果未能解决你的问题,请参考以下文章

ViewPager里面的TextView拦截触摸事件

如何利用redis来进行分布式集群系统的限流设计

AOP框架Dora.Interception 3.0 [3]: 拦截器设计

servlet,过滤器,监听器,拦截器的区别

webservice 权限控制

SpringBoot2----拦截器和文件上传功能