Tomcat学习之Request/Response封装
2016-07-25 08:42
543 查看
http://blog.csdn.net/aesop_wubo/article/details/7630440
[html] view
plain copy
print?
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;
}
然后从线程池中分配一个线程来处理这次请求,会调用Http11ConnectionHandler.process方法来处理,来看看这个process方法
[html] view
plain copy
print?
public SocketState process(SocketWrapper<S> socket,SocketStatus status) {
Processor<S> processor = connections.remove(socket.getSocket());
......
if (processor == null) {
processor = createProcessor();
}
......
state = processor.process(socket);
......
在这个方法里面如果处理器为空,就调用createProcessor方法创建一个,创建processor时会产生两个对象,分别是request,response,也就是说在接收到socket之后用户的请求作了如下转化:
处理用户请求会调用Adapter.service方法,Adapter就是一个适配器,来看看service方法的签名
[html] view
plain copy
print?
public void service(org.apache.coyote.Request req,org.apache.coyote.Response res)
service方法规定了用户请求必须被转化为org.apache.coyote.Request才能被容器处理,由于用户请求多种多样,将这些多种多样的请求接口转换为一个统一的接口正是适配器模式所长,这以这里采用了适配器模式。
正如所料,在Adapter的service方法中将org.apache.coyote.Request转化为了org.apache.catalina.connector.Request,如下代码所示:
[html] view
plain copy
print?
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的呢?这里采用了外观模式,将与容器相关的方法封装起来。
[java] view
plain copy
print?
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的类层次结构,具体请求的处理在后面分析!
org.apache.coyote.Request和org.apache.coyote.Response
在Acceptor接收到一个socket之后,在JIoEndpoint的processSocket方法中这个socket被包装成SocketWrapper[html] view
plain copy
print?
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;
}
然后从线程池中分配一个线程来处理这次请求,会调用Http11ConnectionHandler.process方法来处理,来看看这个process方法
[html] view
plain copy
print?
public SocketState process(SocketWrapper<S> socket,SocketStatus status) {
Processor<S> processor = connections.remove(socket.getSocket());
......
if (processor == null) {
processor = createProcessor();
}
......
state = processor.process(socket);
......
在这个方法里面如果处理器为空,就调用createProcessor方法创建一个,创建processor时会产生两个对象,分别是request,response,也就是说在接收到socket之后用户的请求作了如下转化:
处理用户请求会调用Adapter.service方法,Adapter就是一个适配器,来看看service方法的签名
[html] view
plain copy
print?
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,如下代码所示:
[html] view
plain copy
print?
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的呢?这里采用了外观模式,将与容器相关的方法封装起来。
[java] view
plain copy
print?
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的类层次结构,具体请求的处理在后面分析!
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- i-jetty环境搭配与编译
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 实现单Tomcat多Server配置
- 生产环境下的Tomcat配置
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- Linux部署Tomcat服务器
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器