SpringMVC学习笔记【part8】拦截器

导读:本篇文章讲解 SpringMVC学习笔记【part8】拦截器,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

SpringMVC 学习笔记 Part8

1. 拦截器的概述

SpringMVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。用户可以自己定义一些拦截器来实现特定的功能。

拦截器和过滤器Filter的区别:

  1. 过滤器是 servlet 规范中的一部分,任何 java web 工程都可以使用。拦截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。
  2. 过滤器在 url-pattern 中配置了**/***之后,可以对所有要访问的资源拦截。拦截器它是只会拦截访问的控制器方法,如果访问的是 jsp,html,css,image 或者 js 是不会进行拦截的。

总结:springmvc拦截器能干的事情,过滤器Filter都能干。过滤器Filter能干的事情,springmvc拦截器不一定能干。

2. 拦截器链

拦截器链就是将拦截器按一定的顺序组成的一条链。在访问被拦截的方法时,拦截器链中的拦截器就会按其在 springmvc.xml 定义的顺序被调用。

在这里插入图片描述

3. 自定义拦截器

拦截器实质上也是AOP思想的一种实现方式。想要自定义拦截器,可以总结为两个步骤,配置拦截器和创建类实现HandlerInterceptor接口。

在 springmvx.xml 中配置拦截器。

<!-- 配置拦截器 --> 
<mvc:interceptors> 
    
    <mvc:interceptor> 
        <!-- 哪些方法进行拦截 -->
        <mvc:mapping path="/user/*"/>
        <!-- 哪些方法不进行拦截(与上面的 mapping 二选一) -->
		<mvc:exclude-mapping path=""/>
        <!-- 注册拦截器对象 --> 
        <bean class="com.swz.interceptor.MyInterceptor"/> 
    </mvc:interceptor> 
    
</mvc:interceptors>

HandlerInterceptor接口中的方法共有3个,都是接口已经实现的方法,我们需要手动去添加并重写( idea 快捷键 ctrl+o )。

  1. preHandle方法是controller方法执行前拦截的方法。主要作用:如果我们决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是Controller方法去进行处理,则返回 true 放行。 如果程序员决定不需要再调用其他的任何组件去处理请求,则返回 false 拦截。

  2. postHandle是controller方法执行后执行的方法。主要作用:在业务处理器处理完请求后,但是 DispatcherServlet 向客户端返回响应前被调用,在该方法中对用户请求 request 进行处理,以把处理或增强过的 request 转发去 jsp 页面。

  3. postHandle方法是在JSP执行后执行。主要作用:在 DispatcherServlet 完全处理完请求后被调用,也就是 jsp 页面执行完时。可以在该方法中进行一些资源清理的操作。

public class MyInterceptor implements HandlerInterceptor {

    /** 
        1. 可以使用request或者response跳转到指定的页面。
        2. return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
        3. return false不放行,不会执行controller中的方法。
    */
    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {
        System.out.println("MyInterceptor拦截器执行了...前")
        return true;
    }

    /** 
        1. 可以使用request或者response跳转到指定的页面。
		2. 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
    */
    @Override
    public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor拦截器执行了...后")
    }

    /** 
        1. request或者response不能再跳转页面了。
    */
    @Override
    public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {
        System.out.println("MyInterceptor拦截器执行了...最后")
    }
}

输出结果:

MyInterceptor拦截器执行了...前
controller方法执行了...
MyInterceptor拦截器执行了...后
success.jsp执行了...
MyInterceptor拦截器执行了...最后

4. 配置多个拦截器

在 springmvx.xml 中配置2个拦截器,配置时的顺序代表了拦截器的执行顺序。

<!-- 配置拦截器 --> 
<mvc:interceptors> 
    
    <mvc:interceptor> 
        <!-- 哪些方法进行拦截 -->
        <mvc:mapping path="/user/*"/>
        <!-- 注册拦截器对象 --> 
        <bean class="com.swz.interceptor.MyInterceptor1"/> 
    </mvc:interceptor> 
    
    <mvc:interceptor> 
        <!-- 哪些方法进行拦截 -->
        <mvc:mapping path="/**"/>
        <!-- 注册拦截器对象 --> 
        <bean class="com.swz.interceptor.MyInterceptor2"/> 
    </mvc:interceptor> 
    
</mvc:interceptors>

输出结果:

MyInterceptor1拦截器执行了...前11111
MyInterceptor2拦截器执行了...前22222
controller方法执行了...
MyInterceptor2拦截器执行了...后22222
MyInterceptor1拦截器执行了...后11111
success.jsp执行了...
MyInterceptor2拦截器执行了...最后22222
MyInterceptor1拦截器执行了...最后11111

5. 简单案例(验证用户是否已经登录)

首先先进行业务分析。

有一个登录页面,登录页面有一提交表单的动作,需要在 controller 中处理,因此需要写一个 controller 方法。

controller 方法中要实现的业务:

  1. 判断用户名密码是否正确
  2. 如果正确,向 session 中写入用户信息
  3. 返回登录成功

拦截器中要实现的业务:

  1. 拦截用户请求,判断用户是否登录
  2. 如果用户已经登录就放行,如果用户未登录就跳转到登录页面

现在开始编写代码。

控制器的代码编写如下。

    //跳转到登陆页面
    @RequestMapping("login")
    public String login(Model model)throws Exception{
    	return "login"; 
    }

    //登陆成功,向 session 中写入用户信息
    //username:用户名,pwd:密码
    @RequestMapping("loginsubmit")
    public String loginsubmit(HttpSession session,String username,String pwd) throws Exception{
        //向 session 记录用户身份信息
        session.setAttribute("activeUser", username);
        return "redirect:/main.jsp"; 
    }

    //登出
    @RequestMapping("logout")
    public String logout(HttpSession session)throws Exception{
        //清空所有session 
        session.invalidate();
        return "redirect:index.jsp";
    }

拦截器的代码编写如下。

public class LoginInterceptor implements HandlerInterceptor{
    @Override
    Public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {
        //如果是登录页面则放行,这部分一般更多地在springmvc.xml中配置
        if(request.getRequestURI().indexOf("login")>=0){
        	return true; 
        }
        HttpSession session = request.getSession();
        //如果用户已登录也放行
        if(session.getAttribute("activeUser")!=null){
       		return true; 
        }
        //用户没有登录跳转到登录页面
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
        return false;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84486.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!