Spring之DispatchServlet

Source

先谈谈HttpServletRequest

里面有个coreRequest,其实这个是Tomcat通过门面模式封装的一个Request

 coyoteRequest里面有个headers,从Mime就能知道,这个是浏览器头,因为我们从浏览器发出的请求

=== MimeHeaders ===
host = localhost:8080
connection = keep-alive
cache-control = max-age=0
sec-ch-ua = " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
sec-ch-ua-mobile = ?0
sec-ch-ua-platform = "Windows"
upgrade-insecure-requests = 1
user-agent = Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
accept = text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
sec-fetch-site = none
sec-fetch-mode = navigate
sec-fetch-user = ?1
sec-fetch-dest = document
accept-encoding = gzip, deflate, br
accept-language = zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
cookie = Pycharm-f7ec2ab9=dc7861fa-7990-4700-a0ed-0ae63b47b57c; Idea-f3ea9ae9=6061a667-b955-4dc3-a1d2-c132567ae26f; Hm_lvt_8b02a318fde5831da10426656a43d03c=1622963064; _ga=GA1.1.1797705622.1622963064; Webstorm-c7ff158c=27af0b17-0c16-4ee3-96b6-f6d20eafc5b4; JSESSIONID=865C5C79D63E55E2C71209E2A2A52F2C

注意到里面有个cookie,其实cookie就是浏览器存储的一些值,比如JSESSIONID就是对应的session id

对于不同的请求,会有不同的handler,默认是ResourceHttpRequestHandler,通过

    Resource resource = this.getResource(request);
            if (resource == null) {
            logger.debug("Resource not found");
            response.sendError(404);
        }

来获取资源信息,而资源信息存储在

 protected Resource getResource(HttpServletRequest request) throws IOException {
        String path = (String)request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
        if (path == null) {
            throw new IllegalStateException("Required request attribute '" + HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE + "' is not set");
        } else {
   
     

不过不太明白在哪set进去的attribute

我的理解,一个@requestmapping对应一个,

HandlerExecutionChain mappedHandler

 如果找不到指定handler,那么就会报错404.如下

 看下图,registry就是对应了4个url

 然后打开其中一个看看,可以看到hanlerMethod就是对应路径@RequestMapping("/payToMember") 下的方法payToMember()

 不过能看到有多个handlerMapping

第0个就是requestMapping对应的handler,而1就是Xml对应的handler(因为我们也可以通过xml来配置url mapping)

找到了对应的mappedHandler以后,就可以通过java的反射执行对应方法method了

找到

adapter后面会执行

 

 applyPreHandler就会执行我们预先定义的TokenInteceptor拦截器的前置方法:

 整个流程如下图:

 

 最后invokeForRequest会调用反射方法doInvoke,最后走到controller的指定方法

tokenInterceptor的几个方法执行顺序:

 一个大致的流程图是