Spring MVC 拦截器

前言

Spring MVC 提供了一个拦截器的机制,它专门用于拦截 controller层 的路由请求。

它的本质是:AOP面向切面的编程,也就是说符合横切关注点的功能都可以考虑使用拦截器实现。比如一些应用场景:

  • 权限检查

例如:用户登录检查,访问项目的内部接口时,可以通过拦截器检测用户是否登录,如果登录,直接放回用户登录页面。

  • 日志记录

更新推荐用原生的 AOP 机制会更好一点,粒度会更细,控制起来也更方便,如果你是针对某个接口或者某个请求,或者某个业务针对性的记录日志,其实也可以考虑用拦截器来完成。

  • 性能监控

记录接口访问过程中的开始时间和结束时间的处理机制。

  • 通用行为

比如获取 cookie信息,获取用户信息,并将用户信息存放到请求头中,方便后续业务的使用。

自定义拦截器

1.创建一个拦截器类实现一个接口HandlerInterceptor。

返回值类型方法声明描述
booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)该方法在控制器处理请求方法前执行,其返回值表示是否中断后续操作,返回 true 表示继续向下执行,返回 false 表示中断后续操作
voidpostHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)该方法在控制器处理请求方法调用之后、解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步修改
voidafterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)该方法在视图渲染结束后执行,可以通过此方法实现资源清理、记录日志信息等工作
package com.example.canal.aop;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拦截器类 注意:MyInterceptor 中的方法执行顺序为 preHandle – Controller 方法 – postHandle – afterCompletion 所以拦截器实际上可以对 Controller
 * 方法执行前后进行拦截监控。
 */
@Slf4j
public class MyInterceptor implements HandlerInterceptor {// 实现HandlerInterceptor接口
    /**
     * 访问控制器方法前执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        Object loginUser = request.getSession().getAttribute("loginUser");
        if (loginUser == null) {
            // 未登录,返回登陆页
            request.setAttribute("msg", "您没有权限进行此操作,请先登陆!");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        } else {
            // 放行
            return true;
        }
    }

    /**
     * 访问控制器方法后执行
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {
        log.info("postHandle执行", modelAndView);
    }

    /**
     * postHandle方法执行完成后执行,一般用于释放资源
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {
        log.info("afterCompletion执行异常", ex);
    }
}
  1. 创建一个拦截器的配置类实现WebMvcConfigurer的接口,并且重写addInterceptors方法,注册拦截器类,并且为当前拦截器类定义规则。
package com.example.canal.aop;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 定义拦截器配置类
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 对所有访问路径,都通过MyInterceptor类型的拦截器进行拦截
        // addPathPatterns:该方法用于指定拦截路径,例如拦截路径为“/**”,表示拦截所有请求,包括对静态资源的请求。
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/", "/login",
            "/index.html", "/user/login", "/css/**", "/images/**", "/js/**", "/fonts/**");
        // 放行登录页,登陆操作,静态资源
        // excludePathPatterns:该方法用于排除拦截路径,即指定不需要被拦截器拦截的请求。
    }
}

自定义注解实现拦截器

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestOne {
    String value();
}
public class TestOneInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
        	//获得注解信息
            TestOne testOne = ((HandlerMethod) handler).getMethodAnnotation(TestOne.class);
            if ("".equals(testOne.value())) { //条件根据需求判断
                //内容
            }
        }
        return super.preHandle(request, response, handler);
    }

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

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

单拦截器和多拦截器流程

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值