国外做的比较好的购物网站,网站开发与维护价格,怎么做外网的网站,汽车网站建设分析报告【拦截器Interceptor】springboot拦截器的使用和原理 【一】拦截器简介#xff08;1#xff09;简介【2】作用 【二】实现步骤【1】自定义拦截器#xff0c;实现拦截器接口HandlerInterceptor【2】将拦截器添加到容器当中【3】配置拦截器的拦截规则【4】拦截器的执行顺序 【… 【拦截器Interceptor】springboot拦截器的使用和原理 【一】拦截器简介1简介【2】作用 【二】实现步骤【1】自定义拦截器实现拦截器接口HandlerInterceptor【2】将拦截器添加到容器当中【3】配置拦截器的拦截规则【4】拦截器的执行顺序 【三】拦截器参数【1】获取请求头 request.getHeader【2】Object handler 是什么参数【3】ModelAndView modelAndView【4】Exception ex【5】HttpServletRequest request【6】HttpServletResponse response 【四】多拦截器执行顺序【五】拦截器和过滤器的区别【六】拦截器的实际案例【1】拦截器实现权限控制【2】拦截器实现日志记录【3】拦截器实现接口幂等性校验 【七】拦截器的性能优化和常见问题【1】拦截器性能优化策略【2】拦截器的常见问题和解决方案 【八】拦截器的原理和源码分析 【一】拦截器简介
1简介
拦截器就是用来拦截指定的请求在请求前、请求处理后做一些响应的业务逻辑处理或者在请求完成之后做一些资源释放。
拦截器最常用的使用场景就是认证在请求开始之前对当前请求进行权限校验如果当前请求用户具备操作当前请求的权限就对当前请求放行允许执行业务逻辑否则拦截当前请求直接返回。
拦截器的功能通过网关也都是可以实现的但是一些单体架构还是需要使用拦截器。
【2】作用
拦截器可以用于实现以下功能 1权限控制拦截器可以在请求到达处理器之前进行权限验证从而实现对不同用户的访问控制。 2日志记录拦截器可以在请求处理过程中记录请求和响应的详细信息便于后期分析和调试。 3接口幂等性校验拦截器可以在请求到达处理器之前进行幂等性校验防止重复提交。 4数据校验拦截器可以在请求到达处理器之前对请求数据进行校验确保数据的合法性。 5缓存处理拦截器可以在请求处理之后对响应数据进行缓存提高系统性能。
【二】实现步骤
【1】自定义拦截器实现拦截器接口HandlerInterceptor
要在SpringBoot中实现拦截器首先需要创建一个类并实现HandlerInterceptor接口。HandlerInterceptor接口包含以下三个方法 1preHandle在请求到达处理器之前执行可以用于权限验证、数据校验等操作。如果返回true则继续执行后续操作如果返回false则中断请求处理。 2postHandle在处理器处理请求之后执行可以用于日志记录、缓存处理等操作。 3afterCompletion在视图渲染之后执行可以用于资源清理等操作。
/*** 登录检查* 1.配置到拦截器要拦截哪些请求* 2.把这些配置放在容器中** 实现HandlerInterceptor接口*/
public class LoginInterceptor implements HandlerInterceptor {/*** 目标方法执行之前* 登录检查写在这里如果没有登录就不执行目标方法* param request* param response* param handler* return* throws Exception*/Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取进过拦截器的路径String requestURI request.getRequestURI();// 登录检查逻辑HttpSession session request.getSession();Object loginUser session.getAttribute(loginUser);if(loginUser !null){// 放行return true;}// 拦截 就是未登录,自动跳转到登录页面然后写拦截住的逻辑return false;}/*** 目标方法执行完成以后* param request* param response* param handler* param modelAndView* throws Exception*/Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}/*** 页面渲染以后* param request* param response* param handler* param ex* throws Exception*/Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}【2】将拦截器添加到容器当中
要让拦截器生效需要将其注册到InterceptorRegistry中。这可以通过实现WebMvcConfigurer接口并重写addInterceptors方法来实现。以下是一个简单的注册示例
Configuration
//定制SpringMVC的一些功能都使用WebMvcConfigurer
public class AdminWebConfig implements WebMvcConfigurer {/*** 配置拦截器* param registry 相当于拦截器的注册中心*/Overridepublic void addInterceptors(InterceptorRegistry registry) {//下面这句代码相当于添加一个拦截器 添加的拦截器就是我们刚刚创建的registry.addInterceptor(new LoginInterceptor())//addPathPatterns()配置我们要拦截哪些路径 addPathPatterns(/**)表示拦截所有请求包括我们的静态资源.addPathPatterns()//excludePathPatterns()表示我们要放行哪些表示不用经过拦截器//excludePathPatterns(/,/login)表示放行“/”与“/login”请求//如果有静态资源的时候可以在这个地方放行.excludePathPatterns(/,/login);}
}【3】配置拦截器的拦截规则
在注册拦截器时可以通过addPathPatterns和excludePathPatterns方法来配置拦截器的拦截规则。addPathPatterns方法用于指定需要拦截的请求路径excludePathPatterns方法用于指定不需要拦截的请求路径。以下是一个配置示例
Configuration
public class WebMvcConfig implements WebMvcConfigurer {Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns(/**).excludePathPatterns(/login, /register);}
}
在上述示例中我们配置了拦截器拦截所有请求但排除了登录和注册请求。
【4】拦截器的执行顺序 【三】拦截器参数
【1】获取请求头 request.getHeader Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String contenType request.getHeader(Content-Type);System.out.println(preHandle...contenType);//放行return true;}【2】Object handler 是什么参数 Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String contenType request.getHeader(Content-Type);System.out.println(handler);System.out.println(preHandle...contenType);
// 放行return true;}使用PostMan发送请求后控制台出现下面这个样子 这个参数有什么用被调用的处理器对象本质上是一个方法对象对反射技术中的Method对象进行了再包装 Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String contenType request.getHeader(Content-Type);
// System.out.println(handler);HandlerMethod hm (HandlerMethod)handler;
// 通过hm.getMethod()就可以拿到原始执行的对象拿到这个对象就可以进行反射hm.getMethod();System.out.println(preHandle...contenType);
// 放行return true;}【3】ModelAndView modelAndView
封装了SpringMVC进行页面跳转的相关数据但是我们现在都是返回JSON
【4】Exception ex
通过这个ex可以拿到原始的程序执行过程中出现的异常的
假设controller层抛了异常在这里是可以拿到异常对象的但是我们有异常处理机制所以这里就没有那么大的需求了
如果处理器执行过程中出现异常对象可以针对异常情况进行单独处理
【5】HttpServletRequest request
request请求对象
【6】HttpServletResponse response
response响应对象
【四】多拦截器执行顺序
当配置多个拦截器时形成拦截器链
准备第二个拦截器 注册 Configuration
//定制SpringMVC的一些功能都使用WebMvcConfigurer
public class AdminWebConfig implements WebMvcConfigurer {/*** 配置拦截器* param registry 相当于拦截器的注册中心*/Overridepublic void addInterceptors(InterceptorRegistry registry) {
// 下面这句代码相当于添加一个拦截器 添加的拦截器就是我们刚刚创建的registry.addInterceptor(new LoginInterceptor())
// addPathPatterns()配置我们要拦截哪些路径 addPathPatterns(/**)表示拦截所有请求包括我们的静态资源.addPathPatterns()
// excludePathPatterns()表示我们要放行哪些表示不用经过拦截器
// excludePathPatterns(/,/login)表示放行“/”与“/login”请求
// 如果有静态资源的时候可以在这个地方放行.excludePathPatterns(/,/login);// 第二个拦截器registry.addInterceptor(new LoginInterceptor2()).addPathPatterns(/books);}
}那当我们配置了两个拦截器以后会有一个执行顺序
拦截器链的运行顺序参照拦截器添加顺序为准下面就是三个拦截器时的执行顺序
拦截器链的运行顺序参照拦截器添加顺序为准下面就是三个拦截器时的执行顺序 【五】拦截器和过滤器的区别
拦截器和过滤器都可以实现对请求和响应的拦截和处理但它们之间存在以下区别 1执行顺序过滤器在拦截器之前执行拦截器在处理器之前执行。 2功能范围过滤器可以对所有请求进行拦截而拦截器只能对特定的请求进行拦截。 3生命周期过滤器由Servlet容器管理拦截器由Spring容器管理。 4使用场景过滤器适用于对请求和响应的全局处理拦截器适用于对特定请求的处理。
【六】拦截器的实际案例
【1】拦截器实现权限控制
拦截器可以在请求到达处理器之前进行权限验证从而实现对不同用户的访问控制。以下是一个简单的权限控制示例
public class AuthInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {HttpSession session request.getSession();User user (User) session.getAttribute(user);if (user null) {response.sendRedirect(/login);return false;}return true;}
}
在上述示例中我们在preHandle方法中检查用户是否已登录如果未登录则重定向到登录页面并中断请求处理。
【2】拦截器实现日志记录
拦截器可以在请求处理过程中记录请求和响应的详细信息便于后期分析和调试。以下是一个简单的日志记录示例
public class LogInterceptor implements HandlerInterceptor {private static final Logger logger LoggerFactory.getLogger(LogInterceptor.class);Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {logger.info(Request URI: {}, request.getRequestURI());return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {logger.info(Response status: {}, response.getStatus());}
}
在上述示例中我们在preHandle方法中记录请求URI在postHandle方法中记录响应状态。
【3】拦截器实现接口幂等性校验
拦截器可以在请求到达处理器之前进行幂等性校验防止重复提交。以下是一个简单的幂等性校验示例
public class IdempotentInterceptor implements HandlerInterceptor {private static final String IDEMPOTENT_TOKEN idempotentToken;Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String token request.getHeader(IDEMPOTENT_TOKEN);if (StringUtils.isEmpty(token)) {throw new RuntimeException(Idempotent token is missing);}if (!checkIdempotentToken(token)) {throw new RuntimeException(Duplicate request);}return true;}private boolean checkIdempotentToken(String token) {// Check the token in the cache or database// Return true if the token is valid, false otherwise}
}
在上述示例中我们在preHandle方法中检查请求头中的幂等性令牌如果令牌无效则抛出异常并中断请求处理。
【七】拦截器的性能优化和常见问题
【1】拦截器性能优化策略
拦截器在请求处理过程中可能会影响系统性能以下是一些性能优化策略 1减少拦截器数量尽量将相关功能集中到一个拦截器中避免创建过多的拦截器。 2精确配置拦截规则通过addPathPatterns和excludePathPatterns方法精确配置拦截规则避免不必要的拦截。 3使用异步处理在拦截器中使用异步处理避免阻塞请求处理过程。 4使用缓存在拦截器中使用缓存减少对数据库或其他资源的访问。
【2】拦截器的常见问题和解决方案
拦截器是一种用于处理请求和响应的中间件它可以在请求到达目标处理器之前或响应返回客户端之前执行一些操作。然而在实际使用过程中我们可能会遇到一些问题如拦截器不生效、执行顺序错误或影响性能等。接下来我们将逐一分析这些问题的原因及解决方法。
1拦截器不生效拦截器不生效的可能原因有很多其中最常见的包括拦截器未注册到InterceptorRegistry、拦截规则配置错误等。为了解决这个问题我们需要首先检查拦截器是否已经正确注册到InterceptorRegistry中然后再检查拦截规则是否配置正确。如果发现问题需要及时进行调整和修复。
2拦截器执行顺序错误拦截器执行顺序错误的主要原因是拦截器的注册顺序错误。在实际应用中拦截器的执行顺序是根据它们在InterceptorRegistry中的注册顺序来决定的。因此为了解决这个问题我们需要调整拦截器在InterceptorRegistry中的注册顺序确保它们按照预期的顺序执行。
3拦截器影响性能拦截器影响性能的主要原因是拦截器中的处理逻辑过于复杂或资源消耗过大。为了解决这个问题我们需要对拦截器的处理逻辑进行优化尽量减少不必要的计算和资源消耗。同时我们还可以考虑使用一些性能监控工具如JProfiler等来对拦截器的性能进行实时监控和分析从而找到性能瓶颈并进行优化。
【八】拦截器的原理和源码分析