Spring MVC拦截器配置以及统一登陆校验实现

本文介绍了Java中拦截器的概念,它可在Action执行前后操作或阻止执行。还阐述了拦截器的用途,如日志记录、权限校验等。重点讲解了Spring MVC拦截器的配置,包括dispatch - servlet.xml节点分析、path情况分析,以及请求流程,并给出了Java实现拦截器的示例。

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

拦截器概念

这里引用百度百科里面的说法,java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作

用途

  1. 日志记录:记录请求的一些信息和请求参数
  2. 权限校验:如登陆校验,管理员权限校验
  3. 性能监控:监控请求处理的时间
  4. 通用行为:如读取cookie信息等

配置Spring MVC拦截器

配置 dispatch-servlet.xml

<mvc:interceptors>
        <!-- 如果在interceptors中配置bean,那么所有定义在这里的bean都会被拦截-->
        <!--<bean></bean>-->
        <mvc:interceptor>
            <mvc:mapping path="/manage/**"/>
            <!--过滤登陆死循环情况-->
            <!--<mvc:exclude-mapping path="/manage/login.do"/>-->
            <bean class="com.test.controller.common.interceptor.AuthorityInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
分析配置中的节点
  • interceptors节点:这个节点是SpringMVC的拦截器集配置节点,在这个节点里面我们可以声明多个interceptor
  • interceptor节点:这个节点是配置拦截路径以及你拦截器实现类的节点
    • mapping节点:符合mapping路径匹配的请求都会经过拦截器
    • exclude-mapping节点:符合exclude-mapping路径匹配的请求都不会经过拦截器
    • bean节点:配置我们自己的实现类,实现类要实现HandlerInterceptor接口
path情况分析
  1. 如果要拦截同一个controller下的所有的请求,如/manage/***.do,path应该为 /manage/*
  2. 如果要拦截请求路径为manage包下不同controller的所有请求,如 /manage/product/b.do/manage/order/list.do,path应该为/manage/**
  3. 如果想要某个请求不走拦截器,那么可以配置exclude-mappingpath应该为具体的url,准确到方法,如/manage/login.do
spring MVC拦截器请求流程
spring请求流程具体如下:
  1. 浏览器/客户端发送请求给我们的服务器
  2. 请求来到Spring的dispatchServlet进行请求分发
  3. dispatchServlet检查我们在dispatch-servlet.xml定义好的规则,按照规则判断请求是否走拦截器
  4. 如果判断请求不走拦截器,请求直接分发到对应的controller(这里默认有对应的controller)
  5. 如果判断请求是走拦截器的,就走我们自己实现的拦截器,验证请求,通过就放行,走到controller,反之则提前返回给客户端
spring请求流程图

这里写图片描述

实现拦截器示例(java)

这是自己实现的一个统一登陆校验拦截器,具体代码如下,写代码之前一定要根据自己的实际情况,把dispatch-servlet.xml中的拦截器路径配置好,不然拦截器无法正常工作

@Slf4j
public class AuthorityInterceptor implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info(("preCompletion"));
        //请求中controller的方法名
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        //解析handlermethod

        //获取方法名
        String methodName = handlerMethod.getMethod().getName();
        //获取类名,simplename是获取名字不带包名,name是带包名的
        String className = handlerMethod.getBean().getClass().getSimpleName();
        //解析参数
        StringBuffer stringBuffer = new StringBuffer();
        Map paramMap = request.getParameterMap();
        Iterator it = paramMap.entrySet().iterator();
        while ((it.hasNext())){

            Map.Entry entry = (Map.Entry) it.next();
            String mapKey = (String) entry.getKey();
            String mapValue = "";

            //request的这个参数map的value返回的是一个String[]
            Object obj = entry.getValue();
            if (obj instanceof String[]){
                String[] strs = (String[])obj;
                mapValue = Arrays.toString(strs);
            }
            stringBuffer.append(mapKey).append("=").append(mapValue);
        }

        //判断登陆,如果是登陆就放行
        if(StringUtils.equals(className, UserManageController.class.getSimpleName())&&StringUtils.equals(methodName,"login")){
            //登陆的时候不能把参数的日志也打上,如果日志泄露,账号密码就会泄露
            log.info("权限拦截器拦截到的请求 className{} methodName{}",className,methodName);
            return true;
        }
        //判断登陆
        User user = session.getAttribute(Const.CURRENT_USER);
        if(user == null )){
            //未登录,返回false,不会调用controller里面的方法
            //response必须重置重置,否则会宝getWritter() has already been called for this response
            //这里我们手动接管了SpringMVC原生的返回,而是托管到拦截器中返回
            response.reset();
            //这是返回编码,否者会乱码
            response.setCharacterEncoding("UTF-8");
            //设置返回值类型
            response.setContentType("application/json;chartset=UTF-8");
            PrintWriter out = response.getWriter();
            out.print("你想返回的错误信息")
            }
            out.flush();
            out.close();
            return false;
        }
        return  true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info(("postCompletion"));
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info(("afterCompletion"));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值