在Tomcat的源代码中,处理请求路径和映射到Servlet的相关代码主要集中在以下几个类中:
org.apache.catalina.connector.CoyoteAdapter
org.apache.catalina.core.StandardEngineValve
org.apache.catalina.core.StandardHostValve
org.apache.catalina.core.StandardContextValve
org.apache.catalina.core.StandardWrapperValve
下面是对这些类和关键方法的介绍和代码示例。
1. CoyoteAdapter
类
CoyoteAdapter
类将HTTP请求适配到Tomcat内部的请求对象。
CoyoteAdapter
类的关键方法:
public void service(org.apache.coyote.Request req, org.apache.coyote.Response res)
throws Exception {
Request request = (Request) req.getNote(ADAPTER_NOTES);
Response response = (Response) res.getNote(ADAPTER_NOTES);
if (request == null) {
request = (Request) connector.createRequest();
request.setCoyoteRequest(req);
response = (Response) connector.createResponse();
response.setCoyoteResponse(res);
request.setResponse(response);
response.setRequest(request);
req.setNote(ADAPTER_NOTES, request);
res.setNote(ADAPTER_NOTES, response);
}
try {
// 执行服务方法,将请求分发给容器进行处理
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
} finally {
// 清理请求和响应对象
request.recycle();
response.recycle();
}
}
2. StandardEngineValve
类
StandardEngineValve
是Tomcat请求处理管道中的第一个Valve,它将请求传递给主机级别的Valve。
StandardEngineValve
类的关键方法:
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// 获取请求对应的主机
Host host = request.getHost();
if (host == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
// 将请求传递给主机级别的Valve进行处理
host.getPipeline().getFirst().invoke(request, response);
}
3. StandardHostValve
类
StandardHostValve
将请求传递给上下文级别的Valve。
StandardHostValve
类的关键方法:
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// 获取请求对应的上下文
Context context = request.getContext();
if (context == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
// 将请求传递给上下文级别的Valve进行处理
context.getPipeline().getFirst().invoke(request, response);
}
4. StandardContextValve
类
StandardContextValve
将请求传递给Wrapper级别的Valve,即最终的Servlet。
StandardContextValve
类的关键方法:
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// 获取请求对应的Wrapper
Wrapper wrapper = request.getWrapper();
if (wrapper == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 将请求传递给Wrapper级别的Valve进行处理
wrapper.getPipeline().getFirst().invoke(request, response);
}
5. StandardWrapperValve
类
StandardWrapperValve
是处理具体Servlet的Valve。
StandardWrapperValve
类的关键方法:
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// 获取请求对应的Servlet
Servlet servlet = wrapper.allocate();
try {
// 调用Servlet的service方法处理请求
servlet.service(request.getRequest(), response.getResponse());
} finally {
// 释放Servlet
wrapper.deallocate(servlet);
}
}
请求处理流程
- CoyoteAdapter:将HTTP请求适配为Tomcat内部的请求对象,并调用容器的pipeline。
- StandardEngineValve:将请求传递给Host级别的pipeline。
- StandardHostValve:将请求传递给Context级别的pipeline。
- StandardContextValve:将请求传递给Wrapper级别的pipeline。
- StandardWrapperValve:调用具体的Servlet来处理请求。
总结
以上代码展示了Tomcat如何通过一系列的Valve来处理和分发HTTP请求。每一层Valve都将请求传递给下一级的Valve,最终由具体的Servlet来处理请求。通过这种方式,Tomcat实现了请求路径的解析和映射。