文章目录
文章参考
快速入门
什么是拦截器
Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理
应用场景
- 行权限验证、
- 记录请求信息的日志、
- 判断用户是否登录
- …(其他)
自定义拦截器类
第一种:通过实现HandlerInterceptor接口
-
public boolean preHandle()
方法:该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;当其返回值为false时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)。 -
public void postHandle()
方法:该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。 -
public void afterCompletion()
方法:该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。
第二种:通过实现WebRequestInterceptor接口
-
public void preHandle()
是在请求处理之前调用; -
public void postHandle()
实在请求处理之后,视图渲染之前调用; -
public void afterCompletion()
是在视图渲染之后调用
HandlerInterceptor接口 VS WebRequestInterceptor接口
不同点
-
WebRequestInterceptor的入参WebRequest是包装了HttpServletRequest 和HttpServletResponse的,通过WebRequest获取Request中的信息更简便。
-
WebRequestInterceptor的preHandle是没有返回值的,说明该方法中的逻辑并不影响后续的方法执行,所以这个接口实现就是为了获取Request中的信息,或者预设一些参数供后续流程使用。
-
HandlerInterceptor的功能更强大也更基础,可以在preHandle方法中就直接拒绝请求进入controller方法。
使用场景
这个在上条已经说了,如果想更方便获取HttpServletRequest的信息就使用WebRequestInterceptor,当然这些HandlerInterceptor都能做,只不过要多写点代码
拦截器的配置
第一种:xml配置
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/admin/**"/>
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/secure/*"/>
<bean class="org.example.SecurityInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
第二种:java类配置
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
}
}
拦截器执行流程
一、单个拦截器执行流程
二、多个拦截器执行流程
案例说明
- 继承
HandlerInterceptor
类,实现自定义拦截器
package com.huangbiao.springbootweb.config.filter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("Interceptor preHandle:请求前调用");
//返回 false 则请求中断
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("Interceptor postHandle:请求后调用");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("Interceptor afterCompletion:请求调用完成后回调方法,即在视图渲染完成后回调");
}
}
- 继承
HandlerInterceptor
类,实现自定义拦截器
package com.huangbiao.springbootweb.config.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;
@Slf4j
public class LogInterceptor implements WebRequestInterceptor {
@Override
public void preHandle(WebRequest webRequest) throws Exception {
log.info("LogInterceptor preHandle");
}
@Override
public void postHandle(WebRequest webRequest, ModelMap modelMap) throws Exception {
log.info("LogInterceptor postHandle");
}
@Override
public void afterCompletion(WebRequest webRequest, Exception e) throws Exception {
log.info("LogInterceptor afterCompletion");
}
}
- 使用@Configuration注解修饰 继承
WebMvcConfigurerAdapter
的类
@Configuration 是告诉spring容器,该类是一个配置文件类
继承WebMvcConfigurerAdapter
类是为了添加配置信息
package com.huangbiao.springbootweb.config;
import com.huangbiao.springbootweb.config.filter.LogInterceptor;
import com.huangbiao.springbootweb.config.filter.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.WebRequestInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
@Configuration
public class SpringWebConfig extends WebMvcConfigurerAdapter {
// 添加自定义拦截器
public void addInterceptors(InterceptorRegistry registry) {
registry.addWebRequestInterceptor(new LogInterceptor());
// 如果没有设置匹配路径,则针对所有请求都有效
// registry.addInterceptor(new LocaleChangeInterceptor());
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/person/*");
}
}