@Configuration
public class MyInterceptorConfig extends WebMvcConfigurationSupport {
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
我的拦截器这样配置,那么static/css/下的css与js文件会被拦截吗
在上述配置中,MyInterceptor被添加到了拦截器注册表中,并且通过addPathPatterns(“/”)方法指定了拦截的路径模式为/****,这意味着所有的请求都会被拦截。
通常情况下,静态资源(例如css、js文件)不应该被拦截,因为它们通常不需要额外的处理。但是,由于拦截器配置中使用了/**作为路径模式,这也包括了静态资源的请求。
方法一
为了避免拦截静态资源,可以将拦截器应用的路径模式限制在需要拦截的请求范围内,而不包括静态资源的路径。例如,可以排除静态资源所在的路径,或者更具体地指定需要拦截的路径。用来指定静态资源不被拦截
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/css/**", "/img/**", "/js/**");
super.addInterceptors(registry);
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
super.addResourceHandlers(registry);
}
}
方法二
如果您希望 MyInterceptor 不拦截某些特定的静态资源路径,您可以在 addInterceptors 方法中使用 excludePathPatterns 方法来排除这些路径。例如,如果您想要排除static/css/,static/js/,static/img/下的路径,可以修改 WebMvcConfig 类中的 addInterceptors 方法如下:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/css/**", "/img/**", "/js/**");
}
}
这样配置后,static/img/1.jpg 这样的静态资源请求就不会被 MyInterceptor 拦截器拦截了。
方法三
静态资源请求的处理程序对象是 ResourceHttpRequestHandler,而不是 HandlerMethod。
为了避免拦截,您可以在拦截器中添加一个条件来检查处理程序对象的类型,以确保只有当处理程序对象是 HandlerMethod 类型时才进行转换。这样就可以避免在处理静态资源请求时出现类型转换异常。从而放行静态资源
以下是修改后的拦截器代码示例:
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
@Slf4j
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 判断处理程序对象是否是 HandlerMethod 类型
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
String methodName = method.getName();
log.info("====拦截到了方法:{},在该方法执行之前执行====", methodName);
// 获取请求的URI
String requestURI = request.getRequestURI();
// 获取Session对象
HttpSession session = request.getSession();
String username = (String) session.getAttribute("username");
if (!requestURI.equals("/login") && !requestURI.equals("/user/login"))
return username != null;
}
// 其他情况下直接放行
return true;
}
}
通过添加对处理程序对象类型的检查,我们确保只有当处理程序对象是 HandlerMethod 类型时才尝试转换,并且在其他情况下直接放行请求,避免了类型转换异常。
转发请求,拦截器调用几次呢?
请求转发:如果拦截器配置了对某些路径的拦截,当一个请求被转发到这些路径时,拦截器会被调用。如果请求被多次转发,且每次转发的路径都被同一个拦截器所覆盖,那么拦截器就会被多次调用。这种情况下,如果没有正确配置排除拦截的路径,可能会导致无限循环或重定向次数过多的问题。
重定向:与请求转发类似,如果拦截器没有正确配置,导致请求在处理过程中发生重定向,且重定向的路径又被同一个拦截器所拦截,那么拦截器也会被多次调用。这同样可能导致重定向次数过多的问题。
过滤器与拦截器的区别:需要注意的是,拦截器与过滤器(Filter)不同。过滤器在所有的servlet之前执行,而拦截器在Spring MVC的DispatcherServlet之后执行。因此,过滤器可以过滤任何请求,而拦截器则侧重于拦截对Controller的请求。
模板文件夹下的请求:对于在模板文件夹下查找视图文件的请求,通常不会触发拦截器的调用,因为这些请求通常是由前端控制器(如DispatcherServlet)直接处理的。