我们知道,拦截器是SpringMVC提供的一种AOP的实现,而SpringMVC体系默认是只有DispatcherServlet一个Servlet的,所以拦截器并不能拦截自定义Servlet的情况(虽然我们自定义的Servlet可以有处理请求的功能)。
SpringMVC讲究所有网络都由handler提供,所以,我们尝试了一下静态资源发布的时候,到底用的是哪些handler。
我们通过拦截器方法中给出的handler,也就是像这样:
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("handler:" + handler);
}
首先,静态资源目录,也就是classpath,是可以直接通过路径关系去访问的,这时候我们访问资源,输出信息,得到其handler是:
handler:ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
然后我们再尝试Controller发布静态网页:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class PageController {
@GetMapping("/page_3")
public String index() {
return "page_3";
}
}
得到的结果是:
handler:com.micah.demo.controller.PageController#index()
我们知道,有些静态资源放在一些冷门的路径中,这时我们可以自己去定义资源路径。
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
System.out.println("addResourceHandlers...");
registry.addResourceHandler("/d/**").addResourceLocations("file:D:/");
}
}
这时候我们访问d盘的一个资源,得到的处理器handler信息:
handler:ResourceHttpRequestHandler [URL [file:D:/]]
我们用自定义Servlet去发布静态资源,连DispatcherServlet都用不上,更别说用了什么handler了。
值得注意的是,加入我们将拦截器postHandle方法中的ModelAndView(未解析的view)打印,会得到一个更加有趣的结果,也就是只有当请求的静态资源是通过Controller获取的时候,ModelAndView才不为null,打印结果如下:
modelAndView:ModelAndView [view="page_3"; model={}]
也就是view为当时return的那个字符串。