// Servlet内部跳转的源代码片段 ("...").forward(req, resp);
// ("/hello?parmam1=value1¶m2=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的资源
}
}