软件编程
位置:首页>> 软件编程>> java编程>> SpringBoot * 的配置使用介绍

SpringBoot * 的配置使用介绍

作者:刘婉晴  发布时间:2021-06-20 07:25:54 

标签:SpringBoot, ,

1. 配置 *

具体步骤:

编写一自定义 * 类实现接口 HandlerInterceptor

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

将 * 注册到容器中,实现 WebMvcConfigurer 中的 addInteraptor,然后将自定义 * 注册到 * 中

指定 * 规则 —— 拦截所有 '/**' ,静态资源也会被拦截

解决静态资源同时被拦截问题:

  • addPathPatterns中精确指定精确需要拦截资源

  • excludePathPatterns 中指定排除静态资源

可在 application.properties 文件中指定静态资源统一前缀,方便排除静态资源

spring.mvc.static-path-pattern=/static/**

2. 一个小 Demo

实现未登录用户不能访问除登录页外其他页面的小Demo

1. 自定义 * 类—LoginInterceptor

自定义登录 * ,实现检测到用户未登录,则拦截用户对其他资源的访问,并返回到登录页面

package com.wanqing.admin.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Session;
import org.springframework.lang.Nullable;
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;
/*
登录检查
*/
@Slf4j // lombok 提供的功能
public class LoginInterceptor implements HandlerInterceptor {
   // 目标方法执行之前
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      log.info("拦截的路径是{}", request.getRequestURI());
       // 登录检查逻辑
       HttpSession session = request.getSession();
       Object loginUser = session.getAttribute("loginUser");
       if(loginUser != null){
           return true; // 放行
       }
       // 拦截住,重定向到登录页面
       request.setAttribute("msg", "未登录不允许访问");
       request.getRequestDispatcher("/").forward(request, response); // 转发到当前请求
       return false;
   }
   // 目标方法执行之后
   public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
   }
   // 页面渲染完成之后
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
   }
}

2. 将 * 注册到容器中

通过下列方法,将 * 注册到容器中,并配置好要拦截的路径和要放行的路径。本次 demo 中若未登录则所有路径都拦截,只放行登录页面

package com.wanqing.admin.config;
import com.wanqing.admin.interceptor.LoginInterceptor;
import lombok.extern.slf4j.Slf4j;
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 AdminWebConfig implements WebMvcConfigurer {
   @Override
   public void addInterceptors(InterceptorRegistry registry) {
       // 在 * 的注册中心里,添加 Login *
       registry.addInterceptor(new LoginInterceptor())
                   .addPathPatterns("/**") //所有请求都被拦截,静态资源也被拦截
                   .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); // 放行的请求
   }
}

3. 原理分析

1. 根据当前请求,找到HandlerExecutionChainand,即得到可以处理请求的 Handler,以及 Handler 的所有 *

处理器执行链 :

SpringBoot * 的配置使用介绍

2. 先顺序执行所有 * 的preHandle方法

  • 如果返回为true执行下一个 * 的preHandle;

  • 若为 false,直接倒叙执行所有已经执行了的 * 的 afterCompletion 方法

Step into:

if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    return;
}

* 方法执行 源码分析:

HandlerExecutionChain.class

—— 顺序执行所有 * 的preHandle方法

for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {
    HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
    if (!interceptor.preHandle(request, response, this.handler)) {
        this.triggerAfterCompletion(request, response, (Exception)null);
        return false;
    }
}

&mdash;&mdash; 倒叙执行所有已经执行了的 * 的 afterCompletion 方法

void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) {
       for(int i = this.interceptorIndex; i >= 0; --i) {
           HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
           try {
               interceptor.afterCompletion(request, response, this.handler, ex);
           } catch (Throwable var7) {
               logger.error("HandlerInterceptor.afterCompletion threw exception", var7);
           }
       }
   }

3. 如果任何一个 * 返回 false,直接跳出不执行目标方法

4. 所有 * 都返回 true,执行目标方法

5. 目标方法执行后,倒叙执行所有 * 的 postHandle 方法

6. 前面的步骤有任何异常都会直接触发 afterCompletion 方法

7. 页面成果渲染完成之后,也会倒叙触发 afterCompletion 方法

图解:

SpringBoot * 的配置使用介绍

来源:https://blog.csdn.net/liuwanqing233333/article/details/127235421

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com