概述
文章目录
- 0.前记
- 1.请求处理流程分析
- 1.1 EngineValve
- 1.2 HostValve
- 1.3 ContextValve
- 1.4 WrapperValve
- 2.Valve
0.前记
本章主要内容为在请求转交给Coyote
适配器后的流程分析
紧接上文中请求交由Processor
处理.
CoyoteAdapter.service()
此时在service方法中会调用CoyoteAdapter.service()
,至此请求就即将被发送给Engine
引擎.
//获取Coyote适配器,并调用其service方法
getAdapter().service(request, response);
1.请求处理流程分析
CoyoteAdapter.service()
这里先将CoyoteRequest
转换为HttpServletRequest
, 然后HttpServletRequest
里设置CoyoteRequest
然后就是一系列的invoke
方法
-
请求被
Connector
组件接收,创建Request
和Response
对象。 -
Connector
将Request
和Response
交给Container
,先通过Engine
的pipeline
组件流经内部的每个Valve
。 -
请求流转到
Host
的pipeline
组件中,并且经过内部Valve
的过滤。 -
请求流转到
Contex
t的pipeline
组件中,并且经过内部的Valve
的过滤。 -
请求流转到
Wrapper
的pipeline
组件中,并且经过内部的Valve
的过滤。 -
Wrapper
内部的WrapperValve
创建FilterChain
实例,调用指定的Servlet
实例处理请求。 -
返回
1.1 EngineValve
得到Engine
的Pipeline
得到管道的阀门, 默认为basic
为StandardEngineValve
StandardEngineValve.invoke()
1.2 HostValve
ErrorReportValve -> StandardHostValve
ErrorReportValve .invoke()
StandardHostValve.invoke()
1.3 ContextValve
AuthenticatorBase -> NonLoginAuthenticator -> StandardContextValue
StandardContextValve.invoke()
在这个方法中解释了为什么 /WEB-INF/
下的资源不可以直接请求的原因
MessageBytes requestPathMB = request.getRequestPathMB();
if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0))
|| (requestPathMB.equalsIgnoreCase("/META-INF"))
|| (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0))
|| (requestPathMB.equalsIgnoreCase("/WEB-INF"))) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); //解释了 /WEB-INF/下的资源为什么不能直接请求
return;
}
1.4 WrapperValve
Wrapper
封装了Servlet
的信息
StandardWrapperValve.invoke()
- 创建了Servlet对象
- 初始化了Servlet对象
- 准备FIlter链, 并执行Filter链
- 最后执行了
Servlet.service()
创建并初始化Servlet
准备了一个FIlterChain
执行FilterChain
所以Tomcat
在请求到达Servlet
之前会执行FilterChain
ApplicationFilterChain.doFilter()
ApplicationFilterChain.internalDoFilter()
最后执行了Servlet.service()
然后执行了HttpServlet.service()
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException(lStrings.getString("http.non_http"));
}
service(request, response);
}
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);
}
}
在转换完Response和Request后,service会调用重载的service方法,此时则开始正式执行Get,Post等等.
2.Valve
为阀门, 为一个责任链模式
通过getNext()
获取到下一个阀门
实现类:
- StandardWrapperValve
- StandardContextValve
- StandardHostValve
- StandardEngineValve
最后
以上就是腼腆山水为你收集整理的Tomcat 源码分析 (Tomcat请求处理流程) (五)的全部内容,希望文章能够帮你解决Tomcat 源码分析 (Tomcat请求处理流程) (五)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复