org.apache.coyote.Request和org.apache.coyote.Response
在Acceptor接收到一個socket之後,在JIoEndpoint的processSocket方法中這個socket被包裝成SocketWrapper
- protected boolean processSocket(Socket socket) {
- // Process the request from this socket
- try {
- SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);
- wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
- // During shutdown, executor may be null - avoid NPE
- if (!running) {
- return false;
- }
- getExecutor().execute(new SocketProcessor(wrapper));
- } catch (RejectedExecutionException x) {
- log.warn("Socket processing request was rejected for:"+socket,x);
- return false;
- } catch (Throwable t) {
- ExceptionUtils.handleThrowable(t);
- // This means we got an OOM or similar creating a thread, or that
- // the pool and its queue are full
- log.error(sm.getString("endpoint.process.fail"), t);
- return false;
- }
- return true;
- }
- public SocketState process(SocketWrapper<S> socket,SocketStatus status) {
- Processor<S> processor = connections.remove(socket.getSocket());
- ......
- if (processor == null) {
- processor = createProcessor();
- }
- ......
- state = processor.process(socket);
- ......
處理用戶請求會調用Adapter.service方法,Adapter就是一個適配器,來看看service方法的簽名
- public void service(org.apache.coyote.Request req,org.apache.coyote.Response res)
service方法規定了用戶請求必須被轉化爲org.apache.coyote.Request才能被容器處理,由於用戶請求多種多樣,將這些多種多樣的請求接口轉換爲一個統一的接口正是適配器模式所長,這以這裏採用了適配器模式。
org.apache.catalina.connector.Request和org.apache.catalina.connector.Response
我們知道servlet的service方法需要傳入ServletRequest和ServletResponse類型的參數,tomcat是不是直接將org.apache.coyote.Request直接轉換爲ServletRequest了呢?從org.apache.coyote.Request沒有實現javax.servlet.http.HttpServletRequest接口可知不是這樣的。事實上也不能這樣做,因爲org.apache.coyote.Request裏面封閉了很多底層處理方法,不想暴露給web開發人員使用。所以org.apache.coyote.Request與ServletRequest之前還有一箇中間層,這就是tomcat容器獨有的請求響應接口:org.apache.catalina.connector.Request與org.apache.catalina.connector.Response
正如所料,在Adapter的service方法中將org.apache.coyote.Request轉化爲了org.apache.catalina.connector.Request,如下代碼所示:
- 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 = connector.createRequest();
- request.setCoyoteRequest(req);
- response = connector.createResponse();
- response.setCoyoteResponse(res);
- request.setResponse(response);
- response.setRequest(request);
- req.setNote(ADAPTER_NOTES, request);
- res.setNote(ADAPTER_NOTES, response);
- }
- ......
- }
org.apache.catalina.connector.Request實現了HttpServletRequest接口,重寫了父類的一些方法,還加了一些與容器相關的方法,另外還代理了org.apache.coyote.Request裏面的一些方法,既然org.apache.catalina.connector.Request裏面有一些容器特有的方法,這些方法也是不能給web開發人員使用的,那麼org.apache.catalina.connector.Request又是怎麼轉換爲ServletRequest的呢?這裏採用了外觀模式,將與容器相關的方法封裝起來。
- public class RequestFacade implements HttpServletRequest {
- protected Request request = null;
- public RequestFacade(Request request) {
- this.request = request;
- }
- }
- public class ResponseFacade implements HttpServletResponse {
- protected Response response = null;
- public ResponseFacade(Response response) {
- this.response = response;
- }
- }
本節只分析了request和response的類層次結構,具體請求的處理在後面分析!