Adapter连接了Tomcat连接器Connector和容器Container.它的实现类是CoyoteAdapter主要负责的是对请求进行封装,构造Request和Response对象.并将请求转发给Container也就是Servlet容器.
首先它实现了4个主要方法,以接口的形式给予了定义.
public interface Adapter
{
public void service(Request req, Response res)throws Exception;
public boolean event(Request req, Response res, SocketStatus status)throws Exception;
public boolean asyncDispatch(Request req,Response res, SocketStatus status)throws Exception;
public void log(Request req, Response res, long time);
public String getDomain();
}
CoyoteAdapter对其一一进行实现,以其service为例
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) {
// Create objects
request = connector.createRequest();
request.setCoyoteRequest(req);
response = connector.createResponse();
response.setCoyoteResponse(res);
// Link objects
request.setResponse(response);
response.setRequest(request);
// Set as notes
req.setNote(ADAPTER_NOTES, request);
res.setNote(ADAPTER_NOTES, response);
// Set query string encoding
req.getParameters().setQueryStringEncoding
(connector.getURIEncoding());
}
.....
try {
// Parse and set Catalina and configuration specific
// request parameters
req.getRequestProcessor().setWorkerThreadName(Thread.currentThread().getName());
boolean postParseSuccess = postParseRequest(req, request, res, response);
if (postParseSuccess) {
//check valves if we support async
request.setAsyncSupported(connector.getService().getContainer().getPipeline().isAsyncSupported());
// Calling the container
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
.....
}
AsyncContextImpl asyncConImpl = (AsyncContextImpl)request.getAsyncContext();
if (asyncConImpl != null) {
async = true;
} else if (!comet) {
request.finishRequest();
response.finishResponse();
if (postParseSuccess &&
request.getMappingData().context != null) {
// Log only if processing was invoked.
// If postParseRequest() failed, it has already logged it.
// If context is null this was the start of a comet request
// that failed and has already been logged.
((Context) request.getMappingData().context).logAccess(
request, response,
System.currentTimeMillis() - req.getStartTime(),
false);
}
req.action(ActionCode.POST_REQUEST , null);
}
} catch (IOException e) {
// Ignore
} finally {
req.getRequestProcessor().setWorkerThreadName(null);
// Recycle the wrapper request and response
if (!comet && !async) {
request.recycle();
response.recycle();
} else {
// Clear converters so that the minimum amount of memory
// is used by this processor
request.clearEncoders();
response.clearEncoders();
}
}
}
service的代码流程首先是从coyote的request和response得到connector的request和response并且他们之间互相链接.接下来是通过postParseRequest来解析请求的参数,查找context,解析CookieID,session等.然后用connector.getService().getContainer().getPipeline().getFirst().invoke(request, response)调用容器的方法.从调用的方式可以知道,这个Container已经内置在StandardService中.也就是server.xml的Engine节点.最后是结束请求.调用connector的回调方法.
对于log等方法也是调用了容器的方法.然后回调连接器进行返回.具体实现有所差异而已.由此可见连接适配器CoyoteAdapter的作用是连接器Connector和容器Container的桥梁.