springmvc-拦截器

1.css

Spring MVC 的处理器拦截器相似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。
用户能够本身定义一些拦截器来实现特定的功能。
谈到拦截器,还要向你们提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器按必定的顺
序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其以前定义的顺序被调用。
说到这里,可能你们脑海中有了一个疑问,这不是咱们以前学的过滤器吗?是的它和过滤器是有几分类似,但
是也有区别,接下来咱们就来讲说他们的区别:
过滤器是 servlet 规范中的一部分, 任何 java web 工程均可以使用。
拦截器是 SpringMVC 框架本身的,只有使用了 SpringMVC 框架的工程才能用。
过滤器在 url-pattern 中配置了/*以后,能够对全部要访问的资源拦截。
拦截器它是只会拦截访问的控制器方法,若是访问的是 jsp, html,css,image 或者 js 是不会进行拦
截的。
它也是 AOP 思想的具体应用。
咱们要想自定义拦截器, 要求必须实现: HandlerInterceptor 接口。

2.做用过程html

拦截器的做用对象的controller,拦截器有个放行的功能,能够在放行以前和以后编写一些代码java

预处理,在请求controller以前,会先通过拦截器web

后处理,在请求controller以后,跳转某个页面以前,会通过拦截器spring

拦截器链,也就是会有多个拦截器,好比第一个拦截器放行了,会再通过第二个拦截器...一直到没有了,才会执行controller,返回依然。spring-mvc

 

 

 演示

1、jsp页面

1.index.jspmvc

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>拦截器</title>
</head>
<body>
    <h3>拦截器</h3>
    <a href="user/testInterceptor">测试拦截器</a>
</body>
</html>

2.跳转成功页面success.jsp,会有一个在控制台输出的代码,方便演示app

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>跳转成功</h3>
    <%System.out.println("run success.jsp...");%>
</body>
</html>

3.跳转失败的页面error.jsp框架

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>跳转失败页面</h3>
</body>
</html>

2、控制器

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/testInterceptor")
    public String testInterceptor(){
        System.out.println("run testInterceptor()...");
        return "success";
    }
}

3、拦截器

拦截器须要实现HandlerInterceptor类,这个类有三个方法jsp

1.preHandle()方法

这里先演示第一个方法,也就是在controller执行以前的方法

public class MyInterceptor implements HandlerInterceptor {
    /**
     * 预处理,controller执行以前执行这个方法
     * @param request
     * @param response
     * @param handler
     * @return true,表示放行,会执行这个方法的代码,而后再执行下一个拦截器,若是没有,则执行controller中的方法;
     *         false则表示不放行,也就是只执行这个方法的代码,不会执行controller中的方法,能够经过request和response直接跳转到某个页面
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("run MyInterceptor1.preHandle()...");
//        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
        return true;
    }
}

拦截器须要在springmvc.xml配置文件中配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.cong.controller"></context:component-scan>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--要拦截的具体的方法-->
            <mvc:mapping path="/user/*"/>
            <!--不要拦截的具体的方法-->
            <!--<mvc:exclude-mapping path=""/>-->
            <!--配置拦截器对象-->
            <bean class="com.cong.interceptor.MyInterceptor"/>
        </mvc:interceptor>
        <!--配置第二个拦截器要另外写一个mvc:interceptor-->
        <!--<mvc:interceptor></mvc:interceptor>-->
    </mvc:interceptors>
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

结果,根据打印的内容,能够看出,

先是执行了拦截器的preHandle()方法,而后放行,执行controller中的方法,最后跳转到success.jsp页面

 

 

若是, 将preHandle()方法的返回值设置为false,那么就是拦截器不容许经过,

也就是不会执行controller中的方法,再取消注释,手动跳转到error.jsp页面

结果以下,根据控制台的打印内容,

先是执行了拦截器的preHandle()方法,而后不放行,再也不执行controller中的方法,直接跳转到error.jsp页面

 

 

 2.postHandle()方法

在preHandle()的基础上添加一个postHandle()方法

public class MyInterceptor implements HandlerInterceptor {
    /**
     * 预处理,controller执行以前执行这个方法
     * @param request
     * @param response
     * @param handler
     * @return true,表示放行,执行下一个拦截器,若是没有,则执行controller中的方法;
     *          false则表示不放行,能够经过request和response直接跳转到某个页面
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("run MyInterceptor1.preHandle()...");
//        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
        return true;
    }

    /**
     * 后处理的方法,当controller的方法执行完,要进行页面跳转了(也就是执行success.jsp),就会先这个方法
     * 也能够直接进行页面跳转
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("run MyInterceptor1.postHandle()...");
//        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
    }
}

结果以下,也就是先执行了preHandle()方法,而后执行controller中的方法,再执行postHandle()方法,最后跳转到success.jsp页面

 

 

postHandle()没有返回值,可是同样能够直接进行页面跳转,若是直接进行页面跳转,结果以下

也就是先执行了preHandle()方法,而后执行controller中的方法,再执行postHandle()方法,最后跳转到error.jsp页面

(虽然打印了run success.jsp...   但实际上并无跳转到success。jsp)

 

 

 3.afterCompletion()方法

public class MyInterceptor implements HandlerInterceptor {
    /**
     * 预处理,controller执行以前执行这个方法
     * @param request
     * @param response
     * @param handler
     * @return true,表示放行,执行下一个拦截器,若是没有,则执行controller中的方法;
     *          false则表示不放行,能够经过request和response直接跳转到某个页面
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("run MyInterceptor1.preHandle()...");
//        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
        return true;
    }

    /**
     * 后处理的方法,当controller的方法执行完,要进行页面跳转了(也就是执行success.jsp),就会先这个方法
     * 也能够直接进行页面跳转
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("run MyInterceptor1.postHandle()...");
        //request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
    }

    /**
     * success.jsp执行以后再执行的方法,通常用做释放资源
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("run MyInterceptor1.afterCompletion()...");
    }
}

结果以下,也就是afterComplition()方法是在页面跳转以后再进行执行的

 

 在这里,再写一个拦截器

public class MyInterceptor2 implements HandlerInterceptor {
    /**
     * 预处理,controller执行以前执行这个方法
     * @param request
     * @param response
     * @param handler
     * @return true,表示放行,执行下一个拦截器,若是没有,则执行controller中的方法;
     *          false则表示不放行,能够经过request和response直接跳转到某个页面
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("run MyInterceptor2.preHandle()...");
//        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
        return true;
    }

    /**
     * 后处理的方法,当controller的方法执行完,要进行页面跳转了(也就是执行success.jsp),就会通过这个方法
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("run MyInterceptor2.postHandle()...");
//        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
    }

    /**
     * success.jsp执行以后再执行的方法,通常用做释放资源
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("run MyInterceptor2.afterCompletion()...");
    }
}

注入到容器中

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/user/*"/>
            <bean class="com.cong.interceptor.MyInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.cong.interceptor.MyInterceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>

执行的过程以下

相关文章
相关标签/搜索