SpringMVC中的拦截器的示例及应用

本文详细介绍了SpringMVC中的拦截器实现方式及其应用场景。包括自定义拦截器的步骤、多个拦截器的调用顺序及如何通过拦截器进行权限控制等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、自定义拦截器实现类

在Springmvc中想要定义拦截器,则自定义一个类要实现HandlerInterceptor接口,HandlerInterceptor接口中有三个抽象方法,若不想使用全部,则可以或者是这个类继承HandlerInterceptor接口的实现类,比如Spring已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;
在此之前,先回顾下springmvc整个访问的流程:
这里写图片描述

HandlerInterceptor接口的定义如下:

public interface HandlerInterceptor {
    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

    void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception;

    void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception;

}

HandlerInterceptor接口中定义了三个抽象方法:
**preHandle方法:**Springmvc中可以存在多个自定义拦截器。每个拦截器的调用会依据他的声明顺序依次执行,preHandle()为最先执行的方法,返回值为boolean类型。当返回true时,会继续调用下一个拦截器的preHandle方法,直至最后一个拦截器的preHandle运行结束并返回true时,才调用Controller中的方法。当某个拦截器的preHandle()返回值为false时,后续的拦截器和Controller都不会再执行;这个方法作用在上图中2的位置。

postHandle方法:执行完Controller后调用的方法。也就意味着在此之前全部拦截器的preHandle()返回值均为true,否则无法执行Controller。进而总结出此方法的一个特点:postHandle()方法是只有在preHandle()方法的返回值为true 时才能被调用的方法。它的执行时间是在处理器适配器进行处理之后,在上图中10的位置执行,也就是说在这个方法中你可以对ModelAndView进行操作。这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor拦截器该方法反而会后调用。

afterCompletion方法:次方法同样为当前对应的拦截器 的preHandle方法的返回值为true 时才能被调用的方法。该方法将在整个请求完成之后,也就是在上图13位置执行,这个方法的主要作用是用于清理资源的。

二、拦截器应用简单示例

1.创建自定义Class实现HandlerInterceptor接口:

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("preHandle....");
        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....");

    }

}

2.在springmvc.xml中配置自定义的Interceptor

<!-- 配置拦截器 -->
    <mvc:interceptors>
        <!-- 多个拦截器,顺序执行 -->
        <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
        <!-- <bean class="com.asjy.util.MyInterceptor"></bean> -->
        <mvc:interceptor>
            <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
            <mvc:mapping path="/user/**" />
            <bean class="com.asjy.util.MyInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

3.测试,访问登录页login.jsp,点击登录后会向Controller发送一个请求(jsp页和Controller页不为本次重点,略)

这里写图片描述

三、多个拦截器应用示例

1.新增两个测试拦截器MyInterceptor2, MyInterceptor3,增加一个登录验证拦截器LoginInterceptor,对于未进行登录的用户禁止访问login.jsp以外的页面

public class MyInterceptor2 implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("preHandle....2");
        return true; 

    }
        @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle....2");

    }

    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
           System.out.println("afterCompletion....2");

    }

}
public class MyInterceptor3 implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("preHandle....3");
        return true; 

    }
        @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle....3");

    }

    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
           System.out.println("afterCompletion....3");

    }

}

public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("Login....preHandle.... 4");
         //获取请求的URL  
       String url = request.getRequestURI();  
       //URL:login.jsp是公开的;这个demo是除了login.jsp是可以公开访问的,其它的URL都进行拦截控制  
       if(url.indexOf("doLogin.do")>=0){  
           return true;  
       }  
       //获取Session  
       HttpSession session = request.getSession();  
       String username = (String)session.getAttribute("username");  

       if(username != null){  
           return true;  
       }  
       //不符合条件的,跳转到登录界面  
       request.getRequestDispatcher("../login.jsp").forward(request, response);  

       return false;  
    }

    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("login...postHandle....4");

    }

    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
          System.out.println("login...afterCompletion....4");

    }

}

2.在springmvc.xml中配置自定义的Interceptor

    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <!-- 多个拦截器,顺序执行 -->
        <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
        <bean class="com.asjy.util.MyInterceptor"></bean>
        <bean class="com.asjy.util.MyInterceptor2"></bean>
        <bean class="com.asjy.util.MyInterceptor3"></bean>
        <mvc:interceptor>
            <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
            <mvc:mapping path="/user/**" />
            <bean class="com.asjy.util.LoginInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

点击登录后,拦截器放行,跳转至doLogin.do,保存信息至session中。代码为:

@RequestMapping("doLogin")
    public String doLogin(String username,HttpServletRequest request){
        HttpSession session = request.getSession();
        session.setAttribute("username", username);
        return "redirect:/user/list.do";   //重至用户列表主页面
    }
    @RequestMapping("list")
    public String doAdd(UserExt userExt,Model model){
        List<User> list = new ArrayList<User>();
        User u1 = new User();
        u1.setId(1);
        u1.setUsername("tom");

        User u2 = new User();
        u2.setId(2);
        u2.setUsername("jerry");

        User u3 = new User();
        u3.setId(3);
        u3.setUsername("lucy");

        list.add(u1);
        list.add(u2);
        list.add(u3);

        model.addAttribute("list",list);
        return "list";
    }

3.测试
(1)未进行登录状态下直接访问list.do
这里写图片描述

这里写图片描述
可见程序执行至LoginInterceptor时,未检测到session中username的值,则返回false,并跳转至登录页,程序无法进入Controller

(2).先登录
这里写图片描述
登录成功:
这里写图片描述
打开新窗口,再次直接访问list.do
这里写图片描述

访问成功!看看控制台打印的什么:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值