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的桥梁.