Servlet内部跳转机制 ("...").forward(req, resp);

时间:2025-03-23 07:05:18

// Servlet内部跳转的源代码片段 ("...").forward(req, resp);
// ("/hello?parmam1=value1&param2=value2").forward(req, resp);

// Servlet内部跳转的源代码片段 ("...").forward(req, resp);
		// ("/hello?parmam1=value1¶m2=value2").forward(req, resp);
		
		// 取得转发器  ----------------------- 1
		// ("/hello?parmam1=value1¶m2=value2") ==== 
		class {
			public RequestDispatcher getRequestDispatcher(String path) {
				return (path);//!!!
			}
		}
		
		class {
			public RequestDispatcher getRequestDispatcher(String path) {
				Context context = getContext(); // 
				if (path == null) {
		            return null;
		        } else if (("/")) {
		        	// !!! ("/a/hello-servlet")
		            return (().getRequestDispatcher(path));
		        }
			}
		}
		
		class {
			public RequestDispatcher getRequestDispatcher(final String path) {
	        	// context == 
	            return (path);
		    }
		}

		class {
			public RequestDispatcher getRequestDispatcher(String path) {
	
		    	// path == "/hello?parmam1=value1¶m2=value2"
		    	
		    	// path = "/a/b/c/"
		    	// path = "/a/b/c/HelloServlet"
		        // Get query string
		        String queryString = null;
		        String normalizedPath = path;
		        int pos = ('?');
		        if (pos >= 0) {
		            queryString = (pos + 1); // 有带参数  "parmam1=value1¶m2=value2"
		            normalizedPath = (0, pos); // 标准的地址  "/hello"
		        }
	
		        pos = ();
	
		        // Use the thread local URI and mapping data
		        DispatchData dd = ();
		        if (dd == null) { // 每个线程有各自的副本!!!
		            dd = new DispatchData();
		            (dd);
		        }
	
		        MessageBytes uriMB = ;
		        ();
	
		        // Use the thread local mapping data
		        MappingData mappingData = ;
	
		        // Map the URI
		        CharChunk uriCC = ();
		        try {
		        	// 
		        	// 如:/example
		            ((), 0, ().length());
		            /*
		             * Ignore any trailing path params (separated by ';') for mapping
		             * purposes
		             */
		            int semicolon = (';');
		            if (pos >= 0 && semicolon > pos) {
		                semicolon = -1;
		            }
		            (normalizedPath, 0, semicolon > 0 ? semicolon : pos);
		            // uriMB === "/example/a/b/c/"
		            // uriMB === "/example/a/b/c/"
		            // uriMB === "/example/a/b/c/HellorvSelet"
		            // uriMB === "/test/hello"
		            ().map(context, uriMB, mappingData);//!!!! 匹配路由
		            if ( == null) { // 找到包装器
		                return (null);
		            }
		            /*
		             * Append any trailing path params (separated by ';') that were
		             * ignored for mapping purposes, so that they're reflected in the
		             * RequestDispatcher's requestURI
		             */
		            if (semicolon > 0) {
		                (normalizedPath, semicolon, pos - semicolon);
		            }
		        } catch (Exception e) {
		            // Should never happen
		            log((""), e);
		            return (null);
		        }
		        
	//	      <servlet-mapping>
	//				    <servlet-name>HelloServlet</servlet-name>
	//				    <url-pattern>/hello/*</url-pattern>
	//			</servlet-mapping>
		        // 转发地址:/hello?parmam1=value1¶m2=value2
		        // 
		        Wrapper wrapper = ; // 匹配的StandardWrapper
		        String wrapperPath = (); // 如:"/hello"
		        String pathInfo = ();// null
		        Mapping mapping = (new ApplicationMapping(mappingData)).getMapping(); // 创建映射对象,来保存匹配到的信息
	
		        (); // 回收掉原来映射器的信息
	
		        String encodedUri = (()); // 如: "/test/hello"
	
		        // Construct a RequestDispatcher to process this request
		        // 
		        return new ApplicationDispatcher(wrapper, encodedUri, wrapperPath, pathInfo,
		                queryString, mapping, null);
		    }
		}
		
		
		// 调用转发器的forward方法  ----------------------- 2
		// (req, resp);
		class {
			// 构造函数
			public ApplicationDispatcher(Wrapper wrapper, String requestURI, String servletPath,
		         String pathInfo, String queryString, Mapping mapping, String name) {
	
		        super();
		        // Save all of our configuration parameters
		         = wrapper; // 
		         = (Context) ();
		         = requestURI;
		         = servletPath;
		         = pathInfo;
		         = queryString;
		         = mapping;
		         = name;
		    }
			
			// 内部跳转
			public void forward(ServletRequest request, ServletResponse response)
			        throws ServletException, IOException
		    {
	            doForward(request,response);//!!!! 跳转
		    }
			
			private void doForward(ServletRequest request, ServletResponse response)
			        throws ServletException, IOException
		    {
				// 清除数据,回收空间
	            // 不回收编码转换器
	        	// 
	            (); 
	            State state = new State(request, response, false); // 创建state对象
	            wrapResponse(state);//!!! 包裹对象
	         // 包裹 request == 
	            ApplicationHttpRequest wrequest =
	                (ApplicationHttpRequest) wrapRequest(state);
	            String contextPath = (); // 如: “/test”
	            HttpServletRequest hrequest = ; 
	            // hrequest == 
	            // wrequest == 
	            if ((RequestDispatcher.FORWARD_REQUEST_URI) == null) {
	            	// 把原请求对象RequestFacade的信息,放入新的请求对象ApplicationHttpRequest
	                (RequestDispatcher.FORWARD_REQUEST_URI,
	                                      ());
	                (RequestDispatcher.FORWARD_CONTEXT_PATH,
	                                      ());
	                (RequestDispatcher.FORWARD_SERVLET_PATH,
	                                      ());
	                (RequestDispatcher.FORWARD_PATH_INFO,
	                                      ());
	                (RequestDispatcher.FORWARD_QUERY_STRING,
	                                      ());
	                Mapping mapping;
	                if (hrequest instanceof .) {
	                    mapping = ((.)
	                            hrequest).getMapping(); // 取得路由匹配信息
	                } else {
	                    mapping = (new ApplicationMapping(null)).getMapping();
	                }
	                (
	                        ..FORWARD_MAPPING,
	                        mapping);
	            }

	            // 设置新的请求对象ApplicationHttpRequest的信息
	            (contextPath);
	            (requestURI);
	            (servletPath);
	            (pathInfo);
	            if (queryString != null) {
	                (queryString);
	                (queryString);
	            }
	            (mapping);

	            //  request == 
	            //  response == 
	            processRequest(request,response,state); // 处理请求
	            
	            ((ResponseFacade) response).finish(); // 结束请求
	            
	            PrintWriter writer = (); // 关闭输出对象
                ();
		    }
			
			// 处理请求
			private void processRequest(ServletRequest request,
                    ServletResponse response,
                    State state)
				throws IOException, ServletException {
				
				//  request == 
				//  response == 
				
				// context === 
	            if (() &&
	                    !(request)) { // 如果有配置监听器,就出发跳转监听器
	                doInvoke = false;
	            }
	            //  ==  
                // response == 
                invoke(, response, state);
			}
			
			// 调用
			private void invoke(ServletRequest request, ServletResponse response,
		            State state) throws IOException, ServletException {
		    	
		    	// request ==  
		        // response == 
			
				// wrapper ==  是Servlet的包装器
            	// !!!!! 加载Servlet类,创建Servlet对象,反射Servlet对象内部的注解,如:@Resource声明的资源,并进行依赖注入到Servlet对象中!!!
                // !!!!! 调用Servlet对象的init方法
                servlet = ();

                // Get the FilterChain Here  创建过滤器链条
                ApplicationFilterChain filterChain =
                        (request, wrapper, servlet);
                if ((servlet != null) && (filterChain != null)) {
                    (request, response); // 执行过滤链条
                }
                ();  // 回收过滤器链条的资源
                (servlet); // 回收Servlet的资源
			}
		}