ResourceHttpRequestHandler——SpringMVC静态资源发布时使用的处理器handler

我们知道,拦截器是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的那个字符串。

上一篇:windows python生成 pyd文件


下一篇:超详细讲解SpringMVC三层架构