七、springMVC拦截器

拦截器

springmvc提供了拦截器,类似于过滤器, 他将在请求具体处理之前先做检查,有权决定接下来是否继续。还可以对请求进行加工。

拦截器可是设计多个,

通过实现HandlerInterceptor接口,定义了三个方法

  • 前置处理
  • 后置处理
  • 完成处理

案例一

拦截器实现方法耗时统计与警告

后台代码

package com.text.interceptors;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
* 方法耗时统计的拦截器
* */
public class MethodTimerInterceptor implements HandlerInterceptor {

    //获得
    private static final Logger LOGGER = Logger.getLogger(MethodTimerInterceptor.class);

    //前置功能 开始到结束,做个减法
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //1 定义开始时间
        long start = System.currentTimeMillis();
        //2 将其存到请求域当中
        request.setAttribute("start",start);

        //记录请求日志
        LOGGER.info(request.getRequestURI() + ",请求到达");

        //返回true,才会找下一个拦截器,如果没有下一个拦截器,则去Controller
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //1 取出start
        long start = (long) request.getAttribute("start");
        //2 得到end
        long end = System.currentTimeMillis();
        //3 记录一下耗时
        long spendTime = end - start;

        if(spendTime>=1000){
            LOGGER.warn("方法耗时严重,请及时处理,耗时:"+ spendTime + "毫秒");
        }else{
            LOGGER.info("方法耗时:"+spendTime+"毫秒,处理时间正常");
        }

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

springmvc配置

<!--拦截器的配置-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--
           /*的写法只能拦截/name方法,只能有一层,不能多层拦截
        -->
        <mvc:mapping path="/**/*"/>
        <bean class="com.text.interceptors.MethodTimerInterceptor">
        </bean>
    </mvc:interceptor>

    <mvc:interceptor>
        <!--
            只想拦截/user/**/*
            还需开方登录权限
        -->
        <mvc:mapping path="/user/**/*"/>
        <!--还要排除登录的URI-->
        <mvc:exclude-mapping path="/user/login"/>
        <bean class="com.text.interceptors.SessionInterceptor">

        </bean>
    </mvc:interceptor>
</mvc:interceptors>

案例二

一个会话拦截器,用于检验该用户是否有登录权限

后台代码

package com.text.interceptors;

import com.text.pojo.User;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 会话拦截器
 */
public class SessionInterceptor implements HandlerInterceptor {

    private static final Logger LOGGER = Logger.getLogger(SessionInterceptor.class);

    //检查当前会话是否有User,如果有,放行,如果没有就不放行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        Object user = request.getSession().getAttribute("SESSION_USER");
        if(user == null){
            LOGGER.warn("您不具备权限,请重新登录");
            return false;
        }

        if(user instanceof User){
            //再去数据库检查其身份对不对
            User u = (User) user;
            u.setPassword(null);
            request.getSession().setAttribute("SESSION_USER",u);
            LOGGER.info(u.getUsername() + "处于登录状态,可以执行操作");
            return true;
        }else {
            LOGGER.warn("请不要搞事,请重新登录");
            return false;
        }
    }
}

springmvc配置

<mvc:interceptors>
    <mvc:interceptor>
        <!--
            只想拦截/user/**/*
            还需开方登录权限
        -->
        <mvc:mapping path="/user/**/*"/>
        <!--还要排除登录的URI-->
        <mvc:exclude-mapping path="/user/login"/>
        <bean class="com.text.interceptors.SessionInterceptor">

        </bean>
    </mvc:interceptor>
</mvc:interceptors>

其它事项

springmvc配置

<mvc:interceptors>结点下可以放多个拦截器,按照从上到下的顺序一个个拦截

拦截器执行顺序问题

如果有n个拦截器,并且都能拦截到某个URL的时候,执行顺序问题

在springmvc当中拦截器定义的顺序是有关系的,配在前面的优先去拦截

如i1 i2 i3

前置处理i1 i2 i3

后置处理i3 i2 i1

拦截器与过滤器的比较

相似

都有优先处理请求的权利,可以决定是否将请求转移到实际处理的控制器,都可以对请求或者会话中的请求进行加工

不同
  • 拦截器可以做前置处理,亦可以做后置处理,还可以完成后处理,控制更加细致一些,过滤器只负责前面和后面的过滤行为

  • 过滤器优先执行,过滤器是servlet规范里的组件,而拦截器是框架自己额外添加的组件

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容