1.1.1.1 servlet的解析过程
servlet的解析分为两步实现,第一个是匹配到对应的Wrapper,第二个是加载对应的servlet并进行数据,这些数据是怎么到界面的,response.getWrite()获取对应的流,然后写入这个流中,这个流中就有上文的outputBuffer。
匹配到对应Wrapper
在上文中我们曾经走到过了doRun方法,现在就直接从这里开始
执行顺序如下:
NioEndpoint(run)==>下步调用doRun
NioEndpoint(doRun)==>下步调用state = handler.process(ka,status);
handler实例对象Http11ConnectionHandler其继承AbstractConnectionHandler
AbstractConnectionHandler(process) ==》下步调用 state = processor.process(wrapper);
processor实例对象Http11NioProcessor 其继承AbstractHttp11Processor
AbstractHttp11Processor(process) ==》下步调用getAdapter().service(request, response);
CoyoteAdapter.service(request,response)这个方法就已经接近核心处理了,代码如下:
在第一处标红的地方,对请求进行了解析,并且匹配到对应的主机和context和wrapper
在第二处标红的地方是加载servlet并进行调用处理
在第三处标红的地方是刷新流,响应到界面
@SuppressWarnings("deprecation")
@Override
publicvoid service(org.apache.coyote.Request req,
org.apache.coyote.Responseres)
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 = 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());
}
if (connector.getXpoweredBy()){
response.addHeader("X-Powered-By",POWERED_BY);
}
boolean comet =false;
boolean async = false;
boolean postParseSuccess = false;
try {
//设置执行线程线程名
req.getRequestProcessor().setWorkerThreadName(THREAD_NAME.get());
//对uri进行解码,主要是解析报文,如果不合法返回响应码400
postParseSuccess = postParseRequest(req,request, res, response);
if (postParseSuccess) {
//设置是否支持异步
request.setAsyncSupported(connector.getService().getContainer().getPipeline().isAsyncSupported());
//不断调用管道加载对应的servlet进行调用,其中传递了response参数,所以可以放入流数据
connector.getService().getContainer().getPipeline().getFirst().invoke(request,response);
if (request.isComet()) {
if (!response.isClosed()&& !response.isError()) {
comet = true;
res.action(ActionCode.COMET_BEGIN, null);
if (request.getAvailable()|| (request.getContentLength() >0 &&(!request.isParametersParsed()))) {
event(req, res,SocketStatus.OPEN_READ);
}
} else {
request.setFilterChain(null);
}
}
}
//如果是异步请求
if (request.isAsync()){
async = true;
ReadListener readListener= req.getReadListener();
if (readListener != null&&request.isFinished()) {
ClassLoader oldCL =null;
try {
oldCL =request.getContext().bind(false, null);
if (req.sendAllDataReadEvent()){
req.getReadListener().onAllDataRead();
}
} finally {
request.getContext().unbind(false,oldCL);
}
}
Throwable thr