Spring MVC拦截器(Interceptor)

来源:互联网 发布:刷码软件 编辑:程序博客网 时间:2024/05/29 08:17

1、相关知识

  • 在作用范围内, 拦截器有三个方法:preHandle、postHandle、afterCompletion,拦截器位于控制器运行之前(preHandle)和之后(postHandle、afterCompletion)执行的。在这里preHandle是有一个boolean返回值的,返回true,执行控制器和另外两个方法,放回false,则只刷新页面,不做任何操作。
  • 拦截器的作用:一般是检查资源的合法性,比如有些网站没有登录是不能回复的,没有登陆是不能访问某些页面的,这些操作必须在执行逻辑(控制器逻辑)之前拦截下来,并进行相应的提示。当然还有其他作用,其实struts2拦截器该有的功能都有吧。
  • 要写一个拦截器我们只要实现HandlerInterceptor接口即可,但是不是每次都需要三个方法,Spring MVC中也有现成的实现类,一个是实现了HandlerInterceptor子接口的适配器类HandlerInterceptorAdapter,让拦截器继承这个类,重写需要的方法即可。
  • 在Spring MVC中是没有拦截器的注解的,所以只能在xml配置文件中声明拦截器的bean,或者在类配置文件中addInterceptor方法中注册一个拦截器bean。

2、实例

实现直接实现HandlerInterceptor接口:

package space.xxhui.interceptor;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import space.xxhui.POJO.User;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.logging.Logger;public class CommonInterceptor implements HandlerInterceptor {    private final Logger log = Logger.getLogger(String.valueOf(getClass()));    public static final String LAST_PAGE = "com.alibaba.lastPage";    /**     * 在业务处理器处理请求之前被调用     * 如果返回false     *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链     * 如果返回true     *    执行下一个拦截器,直到所有的拦截器都执行完毕     *    再执行被拦截的Controller     *    然后进入拦截器链,     *    从最后一个拦截器往回执行所有的postHandle()     *    接着再从最后一个拦截器往回执行所有的afterCompletion()     */    public boolean preHandle(HttpServletRequest request,                             HttpServletResponse response, Object handler) throws Exception {        log.info("==============执行顺序: 1、preHandle================");        String requestUri = request.getRequestURI();        String contextPath = request.getContextPath();        String url = requestUri.substring(contextPath.length());        log.info("requestUri:"+requestUri);        log.info("contextPath:"+contextPath);        log.info("url:"+url);        if(url.equals("/login")){            log.info("登录");            return true;        }        User user = (User) request.getSession().getAttribute("user");        if(user == null){            log.info("Interceptor:跳转到login页面!");            request.getRequestDispatcher("/WEB-INF/views/Login.jsp").forward(request, response);            return false;        }else            return true;    }    /**     * 在业务处理器处理请求执行完成后,生成视图之前执行的动作     * 可在modelAndView中加入数据,比如当前时间     */    public void postHandle(HttpServletRequest request,                           HttpServletResponse response, Object handler,                           ModelAndView modelAndView) throws Exception {        log.info("==============执行顺序: 2、postHandle================");        if(modelAndView != null){  //加入当前时间            modelAndView.addObject("var", "测试postHandle");        }    }    /**     * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等     *     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()     */    public void afterCompletion(HttpServletRequest request,                                HttpServletResponse response, Object handler, Exception ex)            throws Exception {        log.info("==============执行顺序: 3、afterCompletion================");    }}

继承HandlerInterceptorAdapter适配器类:

package space.xxhui.interceptor;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class PerformanceInterceptor extends HandlerInterceptorAdapter {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        long startTime = System.currentTimeMillis();        request.setAttribute("startTime",startTime);        return true;    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {        long startTime = (Long) request.getAttribute("startTime");        request.removeAttribute("startTime");        long stopTime = System.currentTimeMillis();        long disTime = stopTime-startTime;        System.out.println("本次请求的处理时间为:"+disTime);        request.setAttribute("handleTime",disTime);    }}

添加xml配置:

     <mvc:interceptors>        <mvc:interceptor>            <mvc:mapping path="/**"/>            <mvc:exclude-mapping path="/css/**"/>            <mvc:exclude-mapping path="/js/**"/>            <mvc:exclude-mapping path="/fonts/**"/>            <bean class="space.xxhui.interceptor.PerformanceInterceptor"/>        </mvc:interceptor>        <!-- 如果不定义 mvc:mapping path 将拦截所有的URL请求 -->        <mvc:interceptor>            <mvc:mapping path="/**"/>            <mvc:exclude-mapping path="/css/**"/>            <mvc:exclude-mapping path="/js/**"/>            <mvc:exclude-mapping path="/fonts/**"/>            <bean class="space.xxhui.interceptor.CommonInterceptor"/>        </mvc:interceptor>    </mvc:interceptors>

mvc:exclude-mapping排除静态资源,不然不能加载静态资源。

懒得创建分支了,请直接查看:SpringMVCDemoByXml-aop_transactions分支

参考文章:使用springMVC框架时,怎样在controller里获得Session。 - ITeye问答 、SpringMVC拦截器(资源和权限管理)