Spring Boot

spring boot整合web开发-4-注册、配置拦截器

2021-03-29  本文已影响0人  星海0815

拦截器原理:

拦截器的原理很简单,是 AOP 的一种实现,专门拦截对动态资源的后台请求,即拦截对控制层的请求。使用场景比较多的是判断用户是否有权限请求后台,更拔高一层的使用场景也有,比如拦截器可以结合 websocket 一起使用,用来拦截 websocket 请求,然后做相应的处理等等。

注册拦截器

步骤01 创建一个spring boot项目,添加spring-boot-starter-web依赖
步骤02 创建拦截器实现HandlerInterceptor接口

package xintianweng;
import org.apache.catalina.filters.ExpiresFilter;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;

/**
 * 创建一个拦截器
 * @author 信天翁
 * 2021/3/29 10:00 下午
 **/
public class MyInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler){
        System.out.println("MyInterceptor>>>preHandle");
        return true;
    }
    public void postHandle(HttpServletRequest request, ExpiresFilter.XHttpServletResponse response, Object handler, ModelAndView modelAndView){
        System.out.println("MyInterceptor>>>postHandle");
    }
    public void afterCompletion(HttpServletRequest request, ExpiresFilter.XHttpServletResponse response, Object handler,Exception ex){
        System.out.println("MyInterceptor>>>afterCompletion");
    }
}

拦截器中的方法将按preHandle➡️Controller➡️postHandle➡️afterCompletion的顺序执行。
注意,只有当preHandle方法返回true时后面的方法才会执行。
当拦截器链内存在多个拦截器时,postHandler在拦截器链内的所有拦截器返回成功时才会调用,而afterCompletion只有preHandle返回true才调用,但若拦截器链内的第一个拦截器的preHandle方法返回false,则后面的方法都不会执行。

步骤03 配置拦截器。定义配置类进行拦截器的配置

package xintianweng;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 配置拦截器
 * @author 信天翁
 * 2021/3/29 10:00 下午
 **/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/hello");
    }
}

preHandle(……) 方法:该方法的执行时机是,当某个 url 已经匹配到对应的 Controller 中的某个方法,且在这个方法执行之前。所以 preHandle(……) 方法可以决定是否将请求放行,这是通过返回值来决定的,返回 true 则放行,返回 false 则不会向后执行。

postHandle(……) 方法:该方法的执行时机是,当某个 url 已经匹配到对应的 Controller 中的某个方法,且在执行完了该方法,但是在 DispatcherServlet 视图渲染之前。所以在这个方法中有个 ModelAndView 参数,可以在此做一些修改动作。

afterCompletion(……) 方法:顾名思义,该方法是在整个请求处理完成后(包括视图渲染)执行,这时做一些资源的清理工作,这个方法只有在 preHandle(……) 被成功执行后并且返回 true 才会被执行。

自定义类实现WebMvcConfigurer接口,实现接口中的addInterceptors方法。其中,
addPathPatterns是用来表示拦截路径。
excludePathPatterns是用来表示排除的路径。

templates下创建hello.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    spring boot !
</body>
</html>

执行springboot启动类,控制台输出如下:

MyInterceptor>>>>preHandle
HELLO SPRING BOOT!
MyInterceptor>>>>postHandle
MyInterceptor>>>>afterCompletion

总结:
①:首先会在拦截到Controller中的“/hello”时先执行preHandle里的逻辑。输出“MyInterceptor>>>>preHandle”
②:然后执行“/hello”对应映射的方法逻辑,输出“HELLO SPRING BOOT!”
③:成功执行“/hello”对应映射的方法逻辑,然后在 DispatcherServlet 视图渲染之前执行postHandle方法里的逻辑。
④:整个请求结束后,然后在这里执行一些其他辅助逻辑,包括资源清理等。

拦截器处理静态资源被拦截的问题

spring boot 2.0以后废弃了WebMvcConfigurerAdapter,但是WebMvcConfigurationSupport 又会导致默认的静态资源被拦截

手动放开静态资源拦截:(和上面的手动配置拦截器一样,在原来的>addInterceptors方法外,还需要重写addResourceHandlers,将资源放开)

    protected void addResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        super.addResourceHandlers(registry);
    }
上一篇下一篇

猜你喜欢

热点阅读