Die obige Aktion bezieht sich im Allgemeinen auf die Schnittstelle unserer Controller-Ebene.
2. Angepasster Interceptor
(1) Schreiben Sie einen Interceptor, um die HandlerInterceptor-Schnittstelle zu implementieren.
(2) Der Abfangjäger ist im Container registriert.
(3) Abfangregeln konfigurieren.
2.1 Einen Interceptor schreiben
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; /** * 登录拦截器 */ @Slf4j public class LoginInterceptor implements HandlerInterceptor { /** * 目标方法执行之前执行 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取请求路径 String requestUrl = request.getRequestURI(); log.info("请求的路径是: {}", requestUrl); String username = request.getParameter("username"); if (username != null) { // 放行 return true; } request.setAttribute("msg", "请先登录"); // 携带msg跳转到登录页 request.getRequestDispatcher("/").forward(request, response); return false; } /** * 目标方法完成以后执行 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("postHandle执行"); } /** * 页面渲染以后执行 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("afterCompletion执行"); } }
2.2 Interceptoren registrieren und konfigurieren
import com.codeliu.interceptor.LoginInterceptor; 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 WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") // 拦截所有路径 .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); // 不拦截这些路径 } }
Beachten Sie, dass wir bei der Konfiguration zum Abfangen aller Pfade statische Ressourcen ausschließen müssen, da sonst die Bildstile abgefangen werden.
Durch die oben genannten Schritte haben wir einen dem System hinzugefügten Abfangjäger implementiert. Beginnen Sie einfach mit der Verifizierung.
3. Interceptor-Prinzip
Starten Sie die Anwendung im Debug-Modus, greifen Sie auf eine beliebige Schnittstelle zu und verfolgen Sie den Codeprozess
3.1 Finden Sie den Handler, der die Anfrage verarbeiten kann, und alle Abfangjäger des Handlers
Hier haben wir den HandlerExecutionChain und gefunden die Interceptor-Kette, die aus drei Interceptoren besteht: Interceptor, unserem benutzerdefinierten
und den standardmäßigen zwei Interceptoren des Systems.LoginInterceptor
3.2 Führen Sie die preHandle-Methode des Interceptors aus.
// 执行拦截器的preHandle方法,如果返回为fasle,则直接return,不执行目标方法 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // 反射执行目标方法 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
Wir geben die applyPreHandle-Methode ein, um die Logik der Methode anzuzeigen Wenn der aktuelle Interceptor Wenn die preHandle-Methode true zurückgibt, wird die preHandle-Methode des nächsten Interceptors weiterhin ausgeführt, andernfalls wird die afterCompletion-Methode des Interceptors ausgeführt.
Dann schauen wir uns die Logik der Methode triggerAfterCompletion an.
/** * Apply preHandle methods of registered interceptors. * @return {@code true} if the execution chain should proceed with the * next interceptor or the handler itself. Else, DispatcherServlet assumes * that this interceptor has already dealt with the response itself. */ boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { // 遍历拦截器 for (int i = 0; i < this.interceptorList.size(); i++) { HandlerInterceptor interceptor = this.interceptorList.get(i); // 执行当前拦截器的preHandle方法 if (!interceptor.preHandle(request, response, this.handler)) { // 如果preHandle方法返回为false,则执行当前拦截器的afterCompletion方法 triggerAfterCompletion(request, response, null); return false; } // 记录当前拦截器的下标 this.interceptorIndex = i; } return true; }
Durch den obigen Code wissen wir, dass die afterCompletion-Methode des Interceptors umgekehrt ausgeführt wird.
3.3 Führen Sie die Zielmethode aus
Wenn alle PreHandle-Methoden des oben genannten Interceptors true zurückgeben, gibt es in der doDispatch-Methode keine direkte Rückgabe, aber die Zielmethode wird weiterhin ausgeführt. Wenn die preHandle-Methode eines Interceptors false zurückgibt, kehrt die doDispatch-Methode nach der Ausführung der afterCompletion-Methode des Interceptors (des Interceptors, der die preHandle-Methode ausgeführt hat) direkt zurück und die Zielmethode wird nicht ausgeführt.
/** * Trigger afterCompletion callbacks on the mapped HandlerInterceptors. * Will just invoke afterCompletion for all interceptors whose preHandle invocation * has successfully completed and returned true. */ void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) { // 反向遍历拦截器 for (int i = this.interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = this.interceptorList.get(i); try { // 执行当前拦截器的afterCompletion方法 interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); } } }
Ich werde nicht auf die spezifische interne Ausführung achten, sondern auf die Logik nach der Ausführung.
3.4 Führen Sie die postHandle-Methode des Interceptors aus.
Nachdem die Zielmethode ausgeführt wurde, geht der Code aus.
// Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());.
Weiter Gehen Sie nach unten
mappedHandler.applyPostHandle(processedRequest, response, mv);
und geben Sie diese Methode ein. Diese Methode verarbeitet die Ausführungsergebnisse und rendert die Seite. Führen Sie am Ende dieser Methode den folgenden Code aus
3.6 Ausnahmebehandlung Wenn während der Ausführung der doDispatch-Methode eine Ausnahme ausgelöst wird, lösen Ausnahmen im Catch-Modul die Ausführung der afterCompletion-Methode ausDas obige ist der detaillierte Inhalt vonAnalyse des SpringBoot-Interceptor-Quellcodes. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!