SpringBoot(08) -- Web Development -- Interceptor

SpringBoot2 study notes

source address

4. Web development

4.7) Interceptor

4.7.1) HandlerInterceptor interface

The source code of HandlerInterceptor.java is as follows:

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 {
    }
}

In the project SpringBootDemo4Admin, create a new LoginInterceptor.java with the following code:

package com.study.admin.interceptor;
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;
import javax.servlet.http.HttpSession;
/**
 * 拦截器
 * 登录检查
 * 1、配置好拦截器要拦截哪些请求
 * 2、把这些配置放在容器中
 */
@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 requestURI = request.getRequestURI();
        log.info("preHandle拦截的请求路径是{}", requestURI);
        //登录检查逻辑
        HttpSession session = request.getSession();
        Object loginUser = session.getAttribute("loginUser");
        // 用户已登录
        if (loginUser != null) {
            //放行
            return true;
        }
        //拦截住。未登录。跳转到登录页
        request.setAttribute("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执行{}", modelAndView);
    }
    /**
     * 页面渲染以后进行拦截
     *
     * @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执行异常{}", ex);
    }
}

4.7.2) Configure Interceptor

Create a new AdminWebConfig.java, the code is as follows:

/**
 * 1、编写一个拦截器实现HandlerInterceptor接口
 * 2、拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors)
 * 3、指定拦截规则【如果是拦截所有,静态资源也会被拦截】
 *
 */
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                //所有请求都被拦截包括静态资源
                .addPathPatterns("/**")
                //剔除不被拦截的请求路径,放行的请求
                .excludePathPatterns("/", "/login", "/css/**", "/fonts/**", "/images/**",
                        "/js/**", "/aa/**");
    }
}

Test: Browser access: http://localhost:8080/main.html , the page is as follows:

 Console output:

2022-06-07 20:15:41.569  INFO 22852 --- [nio-8080-exec-3] c.s.admin.interceptor.LoginInterceptor   : preHandle拦截的请求路径是/main.html

Enter the user and password, click login, the page is redirected to the home page, and the console outputs:

2022-06-07 20:20:54.747  INFO 22852 --- [nio-8080-exec-7] c.s.admin.interceptor.LoginInterceptor   : preHandle拦截的请求路径是/main.html
2022-06-07 20:20:54.748  INFO 22852 --- [nio-8080-exec-7] c.s.admin.controller.IndexController     : 当前方法是:mainPage
2022-06-07 20:20:54.748  INFO 22852 --- [nio-8080-exec-7] c.s.admin.interceptor.LoginInterceptor   : postHandle执行ModelAndView [view="main"; model={}]
2022-06-07 20:20:54.858  INFO 22852 --- [nio-8080-exec-7] c.s.admin.interceptor.LoginInterceptor   : afterCompletion执行异常{}

4.7.3) Interceptor principle

  1. According to the current request, find the source code of HandlerExecutionChain [the handler that can handle the request and all interceptors of the handler] as shown below:

 First come and execute the preHandle method of all interceptors sequentially:

    • If the current interceptor prehandler returns true. Then execute the preHandle of the next interceptor;

    • If the current interceptor returns false, execute the afterCompletion of all interceptors that have been executed directly in reverse order;

  1. If any interceptor returns false, jump out without executing the target method

  2. All interceptors return True. execute target method

  3. Execute the postHandle method of all interceptors in reverse order

  4. Any exceptions in the previous steps will directly trigger afterCompletion in reverse order

  5. After the page is successfully rendered, afterCompletion will also be triggered in reverse order

The execution flow of the interceptor is as follows:

 

Guess you like

Origin blog.csdn.net/jianghao233/article/details/125172802