• DispatcherServlet 分发流程


    • HTTPServlet 的 Service 方法将请求按类进行分解
      doXXX
      
    • FrameworkServlet 重写 doXXX 方法,统一调用 doService 方法
      • doXXX 方法统一调用 processRequest 方法
        • doOptions 和 doTrace 有额外的处理
        • 其他是直接调用
      • processRequest 主要是初始化 ThreadLocal ,调用 doService 方法,并进行日志等处理
        • ThreadLocal 是 LocalContext 和 Attributes
        • doService 方法执行核心逻辑,是抽象方法
        • 完成后会清空 ThreadLocal ,打印日志,产生事件。
    • DispatcherServlet 进行具体的实现
      • 重写 doService 方法
        DispatcherServlet
        doDispatch
        
      • doDispatch 方法的逻辑为:
        1. 查找是否有合适的 Handler,该过程在基于RESTful API 设计的 SpringMVC 中有性能问题
        2. 查找 Handler 是否有支持的 Adapter
        3. 执行拦截器
        4. 执行处理
        5. 解析结果并返回

    1, DispatcherServlet 的父类做了什么

    DistpathcerServlet 的类图如下,可见其父类为 FrameworkServlet ,同时是一个 HttpServlet .

    1.1 HttpServlet 的分发逻辑:

    service 方法作为入口, 其逻辑如下:

    protected void service(HttpServletRequest req, HttpServletResponse resp)
    	throws ServletException, IOException {
    
    	String method = req.getMethod();
    
    	if (method.equals(METHOD_GET)) {
    		long lastModified = getLastModified(req);
    		if (lastModified == -1) {
    			// servlet doesn't support if-modified-since, no reason
    			// to go through further expensive logic
    			doGet(req, resp);
    		} else {
    			long ifModifiedSince;
    			try {
    				ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
    			} catch (IllegalArgumentException iae) {
    				// Invalid date header - proceed as if none was set
    				ifModifiedSince = -1;
    			}
    			if (ifModifiedSince < (lastModified / 1000 * 1000)) {
    				// If the servlet mod time is later, call doGet()
    				// Round down to the nearest second for a proper compare
    				// A ifModifiedSince of -1 will always be less
    				maybeSetLastModified(resp, lastModified);
    				doGet(req, resp);
    			} else {
    				resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
    			}
    		}
    
    	} else if (method.equals(METHOD_HEAD)) {
    		long lastModified = getLastModified(req);
    		maybeSetLastModified(resp, lastModified);
    		doHead(req, resp);
    
    	} else if (method.equals(METHOD_POST)) {
    		doPost(req, resp);
    
    	} else if (method.equals(METHOD_PUT)) {
    		doPut(req, resp);
    
    	} else if (method.equals(METHOD_DELETE)) {
    		doDelete(req, resp);
    
    	} else if (method.equals(METHOD_OPTIONS)) {
    		doOptions(req,resp);
    
    	} else if (method.equals(METHOD_TRACE)) {
    		doTrace(req,resp);
    
    	} else {
    		//
    		// Note that this means NO servlet supports whatever
    		// method was requested, anywhere on this server.
    		//
    
    		String errMsg = lStrings.getString("http.method_not_implemented");
    		Object[] errArgs = new Object[1];
    		errArgs[0] = method;
    		errMsg = MessageFormat.format(errMsg, errArgs);
    
    		resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
    	}
    }

    可见对于 POST PUT DELETE OPTIONS TRACE 方法都是直接调用对应的具体方法 doXXX , 而 GET 方法会增加 if-modified-since 检查,符合条件后才进行 doGet , 这是为了支持 HTTP 协议的 if-modified-since 请求头。而 HEAD 方法的额外处理也是检查是否需要设置 last-mo

  • 相关阅读:
    Android JobScheduler介绍
    模型/视图 及 各类的继承关系
    猿创征文|Highgo Database安全版安装指导手册
    Java-----面向对象
    接口测试新手入门全流程
    unity的乐高世界
    【大厂招聘试题】__嵌入式开发工程师_2023届“联想”_1
    聚苯乙烯核-聚(丙烯酰胺-丙烯酸)壳荧光素微球/磺酸官能化聚苯乙烯高荧光微球的制备
    Arduino PLC IDE
    图像相机-相机属性SDK汇总设置
  • 原文地址:https://blog.csdn.net/m0_73257876/article/details/126673709