HandlerInterceptor
에 대한 자세한 설명을 통해 handler
프로세서 실행 체인의 워크플로 인터페이스를 사용자 정의할 수 있습니다. 핸들러 프로세서(컨트롤러 계층의 인터페이스로 이해할 수 있음)를 가로채기 위해 인터셉터를 사용자 정의할 수 있으므로 일반적인 반복 처리 동작(예: 인터페이스 인증, 인터페이스 로깅, 성능 모니터링 등)을 추가할 수 있습니다. 각 처리기의 구현을 수정합니다. HandlerInterceptor
允许定制 handler
处理器执行链的工作流接口。我们可以自定义拦截器用于拦截 handlers 处理器(你可以理解为 controller 层的接口),从而可以添加一些共同的重复性的处理行为(例如接口鉴权,接口日志记录,性能监控等),而不用修改每一个 handler 的实现。
注意,此基于 SpringBoot 2.3.12.RELEASE
版本讲解。
HandlerInterceptor 接口只有三个默认空实现方法,在低版本中这三个方法不是默认方法,而是抽象方法。
public interface HandlerInterceptor { default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }
这三个方法的执行顺序图如下:
preHandle
前置处理,拦截一个处理器(handler)的执行,preHandle 方法会在 HandlerMapping
确定一个适当的处理器对象之后,但在 HandlerAdapter
调用处理器之前被调用。可以简单理解为 controller 接口被调用之前执行。
Intercepter 是链式的,就是一个接着一个执行。如果此方法返回 true,则会执行下一个拦截器或者直接执行处理器。如果此方法返回 false 或者抛出异常则终止执行链,也不再调用处理器。
注意,此方法如果不返回 true,那么 postHandle
和 afterCompletion
不会被执行。
那这个方法有什么用呢?其实可以做一些接口被调用前的预处理,例如用户权限校验。
package com.chenpi; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; /** * @Description 用户权限验证拦截 * @Author 陈皮 * @Date 2021/6/27 * @Version 1.0 */ @Component public class UserPermissionInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; // 获取用户权限校验注解 UserAuthenticate userAuthenticate = handlerMethod.getMethod().getAnnotation(UserAuthenticate.class); if (null == userAuthenticate) { userAuthenticate = handlerMethod.getMethod().getDeclaringClass() .getAnnotation(UserAuthenticate.class); } if (userAuthenticate != null && userAuthenticate.permission()) { // 验证用户信息 UserContext userContext = userContextManager.getUserContext(request); if (null == userContext) { return false; } } } return true; } }
postHandle
后置处理,会在 HandlerAdapter
调用处理器之后,但在 DispatcherServlet
渲染视图之前被调用。可以在此对 ModelAndView
做一些额外的处理。可以简单理解为 controller 接口被调用之后执行。
注意,此方法在执行链中的执行顺序是倒着执行的,即先声明的拦截器后执行。
afterCompletion 完成之后,在请求处理完之后被执行,也就是渲染完视图之后。一般用于做一些资源的清理工作,配合 preHandle 计算接口执行时间等。
注意,和 postHandle 一样,此方法在执行链中的执行顺序也是倒着执行的,即先声明的拦截器后执行。
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) { // 请求完后,清除当前线程的用户信息 UserContextHolder.removeUserContext(); }
注意,我们自定义的拦截器要通过 WebMvcConfigurer
SpringBoot 2.3.12.RELEASE
버전을 기준으로 합니다. 🎜🎜HandlerInterceptor 인터페이스에는 세 가지 기본 빈 구현 메서드만 있습니다. 하위 버전에서는 이 세 가지 메서드가 기본 메서드가 아니라 추상 메서드입니다. 🎜package com.yzj.ehr.common.config; import com.yzj.ehr.common.context.UserContextResolver; import org.springframework.stereotype.Component; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.yzj.ehr.common.interceptor.UserPermissionInterceptor; /** * @Description 注册拦截器 * @Author 陈皮 * @Date 2021/6/27 * @Version 1.0 */ @Component public class WebAppConfigurer implements WebMvcConfigurer { private UserPermissionInterceptor userPermissionInterceptor; public WebAppConfigurer(final UserPermissionInterceptor userPermissionInterceptor) { this.userPermissionInterceptor = userPermissionInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { // 匹配所有接口,排除/base/test接口 registry.addInterceptor(userPermissionInterceptor).addPathPatterns("/**") .excludePathPatterns("/base/test"); } }🎜이 세 가지 메소드의 실행 순서 다이어그램은 다음과 같습니다. 🎜🎜🎜
preHandle
사전 처리를 사용하여 프로세서(핸들러)의 실행을 가로채는 방법, preHandle 메서드는 HandlerMapping은 적절한 핸들러 객체를 결정한 후 HandlerAdapter
가 핸들러를 호출하기 전에 호출됩니다. 컨트롤러 인터페이스가 호출되기 전에 실행된다는 것을 간단히 이해하면 됩니다. 🎜🎜인터셉터는 체인으로 연결되어 있습니다. 즉, 차례로 실행됩니다. 이 메서드가 true를 반환하면 다음 인터셉터가 실행되거나 핸들러가 직접 실행됩니다. 이 메서드가 false를 반환하거나 예외를 발생시키면 실행 체인이 종료되고 핸들러가 더 이상 호출되지 않습니다. 🎜🎜이 메서드가 true를 반환하지 않으면 postHandle
및 afterCompletion
이 실행되지 않습니다. 🎜🎜그렇다면 이 방법의 용도는 무엇인가요? 실제로 인터페이스가 호출되기 전에 사용자 권한 확인과 같은 일부 전처리를 수행할 수 있습니다. 🎜rrreeepostHandle
후처리는 HandlerAdapter
가 프로세서를 호출한 후에 수행되지만 DispatcherServlet
후에 수행됩니다. code> code>는 뷰를 렌더링하기 전에 호출됩니다. 여기에서 ModelAndView
에 대한 몇 가지 추가 처리를 수행할 수 있습니다. 간단히 말해서 컨트롤러 인터페이스가 호출된 후에 실행된다고 이해하면 됩니다. 🎜🎜실행 체인에서 이 메서드의 실행 순서가 반대라는 점에 유의하세요. 즉, 먼저 선언된 인터셉터가 나중에 실행됩니다. 🎜WebMvcConfigurer
구현 클래스를 통해 등록되어야 합니다. 🎜아아아아위 내용은 SpringBoot 인터셉터를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!