目录
1、启动8080端口监听http请求时序图
2、启动8080端口监听http请求代码解析
3、http请求时序图
4、http请求request和response的封装
5、查找自定义过滤器和servlet
6、自定义的过滤器和servlet调用
NioEndpoint的方法startInternal启动socket的监听,监听http请求
@Override
public void startInternal() throws Exception {
if (!running) {
running = true;
paused = false;
processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getProcessorCache());
eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getEventCache());
nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getBufferPool());
// Create worker collection
if ( getExecutor() == null ) {
createExecutor();
}
initializeConnectionLatch();
// Start poller threads
pollers = new Poller[getPollerThreadCount()];
for (int i=0; i
NioEndpoint的内部类Acceptor,启动监听,在浏览器输入http地址,此内部类接受到请求
protected class Acceptor extends AbstractEndpoint.Acceptor {
@Override
public void run() {
int errorDelay = 0;
// Loop until we receive a shutdown command
while (running) {
// Loop if endpoint is paused
while (paused && running) {
state = AcceptorState.PAUSED;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// Ignore
}
}
if (!running) {
break;
}
state = AcceptorState.RUNNING;
try {
//if we have reached max connections, wait
countUpOrAwaitConnection();
SocketChannel socket = null;
try {
// Accept the next incoming connection from the server
// 监听http请求
socket = serverSock.accept();
} catch (IOException ioe) {
// We didn't get a socket
countDownConnection();
if (running) {
// Introduce delay if necessary
errorDelay = handleExceptionWithDelay(errorDelay);
// re-throw
throw ioe;
} else {
break;
}
}
// Successful accept, reset the error delay
errorDelay = 0;
// Configure the socket
if (running && !paused) {
// setSocketOptions() will hand the socket off to
// an appropriate processor if successful
//重要的方法,将socket连接添加到一个缓存队列,这里使用的是生产者和消费者模式
//关于生产者和消费者的学习地址
//http://blog.csdn.net/c275046758/article/details/50492107
if (!setSocketOptions(socket)) {
closeSocket(socket);
}
} else {
closeSocket(socket);
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
log.error(sm.getString("endpoint.accept.fail"), t);
}
}
state = AcceptorState.ENDED;
}
。。。。。
}
三、http请求时序图
四、http请求request和response的封装
类AbstractProtocol,完成tomcat的不能被继承org.apache.coyote.Request和org.apache.coyote.Response的初始化
@Override
public SocketState process(SocketWrapperBase wrapper, SocketEvent status) {
。。。。。
if (processor == null) {
//初始化tomcat内部的request和response
processor = getProtocol().createProcessor();
register(processor);
}
SocketState state = SocketState.CLOSED;
do {
//重点
state = processor.process(wrapper, status);
}
类CoyoteAdapter,完成org.apache.coyote.Request、org.apache.coyote.Response到org.apache.catalina.connector.Request、org.apache.catalina.connector.Response的转换;
@Override
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);
//request和response的转换
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);
}
try {
// Parse and set Catalina and configuration specific
// 查找servlet
postParseSuccess = postParseRequest(req, request, res, response);
if (postParseSuccess) {
//check valves if we support async
request.setAsyncSupported(
connector.getService().getContainer().getPipeline().isAsyncSupported());
// 重点
connector.getService().getContainer().getPipeline().getFirst().invoke(
request, response);
}
}
StandardContextValve类,如果访问的是WEB-INF目录则阻止
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// 对指定的访问目录做控制 WEB-INF or META-INF
MessageBytes requestPathMB = request.getRequestPathMB();
if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0))
|| (requestPathMB.equalsIgnoreCase("/META-INF"))
|| (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0))
|| (requestPathMB.equalsIgnoreCase("/WEB-INF"))) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
五、查找自定义的过滤器和servlet
CoyoteAdapter类的方法postParseRequest,查找servlet
protected boolean postParseRequest(org.apache.coyote.Request req, Request request,
org.apache.coyote.Response res, Response response) throws IOException, ServletException {
。。。。。。。。。。
while (mapRequired) {
// 查找到servlet
connector.getService().getMapper().map(serverName, decodedURI,
version, request.getMappingData());
}
六、自定义的过滤器和servlet的调用
类ApplicationFilterChain,调用自定义的过滤器和自定义servlet
private void internalDoFilter(ServletRequest request,
ServletResponse response)
throws IOException, ServletException {
if( Globals.IS_SECURITY_ENABLED ) {
final ServletRequest req = request;
final ServletResponse res = response;
Principal principal =
((HttpServletRequest) req).getUserPrincipal();
Object[] args = new Object[]{req, res, this};
SecurityUtil.doAsPrivilege ("doFilter", filter, classType, args, principal);
} else {
//调用自定义过滤器
filter.doFilter(request, response, this);
}
} catch (IOException | ServletException | RuntimeException e) {
throw e;
} catch (Throwable e) {
e = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(e);
throw new ServletException(sm.getString("filterChain.filter"), e);
}
return;
}
} else {
//调用自定义servlet
servlet.service(request, response);
}
}
一次http请求参考资料:https://blog.csdn.net/c275046758/article/details/51347545
你可能感兴趣的:(tomcat)