零 上一节我们来到了 getAdapter().service(request, response);
这里,接下来需要看一个 连接器 -- Coyote框架
Coyote
的中文意思是 山狗
,北美的一种狼,我想用这个名字应该是指他非常的迅猛。 它实现了自己的 Request
和 Response
(不是 servlet
标准),主要用于将 byte数组
翻译成必要的 HTTP信息
。
一. CoyoteAdapter处理请求 CoyoteAdapter
会将 Socket
接收的 byte数组
包装成 Request
和 Response
,这是一个 Facade模式
,意将解析过程封装起来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 public class CoyoteAdapter implements Adapter { @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); 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); req.getParameters().setQueryStringCharset(connector.getURICharset()); } if (connector.getXpoweredBy()) { response.addHeader("X-Powered-By" , POWERED_BY); } boolean async = false ; boolean postParseSuccess = false ; req.getRequestProcessor().setWorkerThreadName(THREAD_NAME.get()); try { postParseSuccess = postParseRequest(req, request, res, response); if (postParseSuccess) { request.setAsyncSupported( connector.getService().getContainer().getPipeline().isAsyncSupported()); connector.getService().getContainer().getPipeline().getFirst().invoke( request, response); } 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 throwable = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); if (!request.isAsyncCompleting() && throwable != null ) { request.getAsyncContextInternal().setErrorState(throwable, true ); } } else { request.finishRequest(); response.finishResponse(); } } catch (IOException e) { } finally { AtomicBoolean error = new AtomicBoolean (false ); res.action(ActionCode.IS_ERROR, error); if (request.isAsyncCompleting() && error.get()) { res.action(ActionCode.ASYNC_POST_PROCESS, null ); async = false ; } if (!async && postParseSuccess) { Context context = request.getContext(); Host host = request.getHost(); long time = System.currentTimeMillis() - req.getStartTime(); if (context != null ) { context.logAccess(request, response, time, false ); } else if (response.isError()) { if (host != null ) { host.logAccess(request, response, time, false ); } else { connector.getService().getContainer().logAccess( request, response, time, false ); } } } req.getRequestProcessor().setWorkerThreadName(null ); if (!async) { updateWrapperErrorCount(request, response); request.recycle(); response.recycle(); } } } }
现在有必要祭出之前那副请求处理图了:
我们现在来到了 Connector
这一步,他会将 Request
和 Response
开始传递给 Engine
的 Pipeline
进行处理,Pipeline
又会继续调用容器里面的子容器的 Pipeline
逐一处理完成以后,最后来到了我们 webapp
的 service
方法。当 webapp
都执行完成了以后,就会调用到 request.finishRequest()
和 response.finishResponse();
写出去。
二. CoyoteAdapter写出响应 因为在这里完全可以拿到已经处理完成的 Response
数据,所以也是在这里写出数据的,我打算先看完 请求
和 响应
,所以直接先看写出数据。 那么我们上面是 response.finishResponse();
这个方法来完成响应的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Response implements HttpServletResponse { public void finishResponse () throws IOException { outputBuffer.close(); } public void setConnector (Connector connector) { if ("AJP/1.3" .equals(connector.getProtocol())) { outputBuffer = new OutputBuffer (8184 ); } else { outputBuffer = new OutputBuffer (); } outputStream = new CoyoteOutputStream (outputBuffer); writer = new CoyoteWriter (outputBuffer); } }
而这个 OutputBuffer
是由 Tomcat
提供的,接下来看看 close
做了哪些事情:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class OutputBuffer extends Writer { @Override public void close () throws IOException { if (closed) { return ; } if (suspended) { return ; } if (cb.remaining() > 0 ) { flushCharBuffer(); } if ((!coyoteResponse.isCommitted()) && (coyoteResponse.getContentLengthLong() == -1 ) && !coyoteResponse.getRequest().method().equals("HEAD" )) { if (!coyoteResponse.isCommitted()) { coyoteResponse.setContentLength(bb.remaining()); } } if (coyoteResponse.getStatus() == HttpServletResponse.SC_SWITCHING_PROTOCOLS) { doFlush(true ); } else { doFlush(false ); } closed = true ; Request req = (Request) coyoteResponse.getRequest().getNote(CoyoteAdapter.ADAPTER_NOTES); req.inputBuffer.close(); coyoteResponse.action(ActionCode.CLOSE, null ); } }
1 2 3 4 5 6 7 8 9 10 11 12 public final class Response { public void action (ActionCode actionCode, Object param) { if (hook != null ) { if (param == null ) { hook.action(actionCode, this ); } else { hook.action(actionCode, param); } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public abstract class AbstractProcessor extends AbstractProcessorLight implements ActionHook { @Override public final void action (ActionCode actionCode, Object param) { switch (actionCode) { case COMMIT: { if (!response.isCommitted()) { try { prepareResponse(); } catch (IOException e) { setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e); } } break ; } case CLOSE: { action(ActionCode.COMMIT, null ); try { finishResponse(); } catch (CloseNowException cne) { setErrorState(ErrorState.CLOSE_NOW, cne); } catch (IOException e) { setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e); } break ; } case ACK: {} } } }
case CLOSE
会先递归调用 Commit
,然后再调用完成响应的函数。 prepareResponse
包含了验证是否需要写 body
,Content-Type
,计算 Content-Length
等等一些必要的 响应头
,然后一起写到客户端,代码过长就不放了。 finishResponse
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class Http11Processor extends AbstractProcessor { @Override protected final void finishResponse () throws IOException { outputBuffer.end(); } } public class Http11OutputBuffer implements HttpOutputBuffer { @Override public void end () throws IOException { if (responseFinished) { return ; } if (lastActiveFilter == -1 ) { outputStreamOutputBuffer.end(); } else { activeFilters[lastActiveFilter].end(); } responseFinished = true ; } }
那现在就需要来观察 IdentityOutputFilter
的 end
函数,然而这个 end
函数会一步一步通过 代理
传递到对应的 Socket
的 end
函数来完成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 public class IdentityOutputFilter implements OutputFilter { @Override public void end () throws IOException { buffer.end(); } } protected class SocketOutputBuffer implements HttpOutputBuffer { @Override public void end () throws IOException { socketWrapper.flush(true ); } } public static class NioSocketWrapper extends SocketWrapperBase <NioChannel> { public boolean flush (boolean block) throws IOException { boolean result = false ; if (block) { flushBlocking(); } else { result = flushNonBlocking(); } return result; } protected void flushBlocking () throws IOException { doWrite(true ); if (!nonBlockingWriteBuffer.isEmpty()) { nonBlockingWriteBuffer.write(this , true ); if (!socketBufferHandler.isWriteBufferEmpty()) { doWrite(true ); } } } protected void doWrite (boolean block) throws IOException { socketBufferHandler.configureWriteBufferForRead(); doWrite(block, socketBufferHandler.getWriteBuffer()); } @Override protected void doWrite (boolean block, ByteBuffer from) throws IOException { long writeTimeout = getWriteTimeout(); Selector selector = null ; try { selector = pool.get(); } catch (IOException x) { } try { pool.write(from, getSocket(), selector, writeTimeout, block); if (block) { do { if (getSocket().flush(true , selector, writeTimeout)) { break ; } } while (true ); } updateLastWrite(); } finally { if (selector != null ) { pool.put(selector); } } } }
三.业务数据处理链 业务数据的处理主要发生在上面提到过的 CoyoteAdapter
中,我重新贴一下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 public class CoyoteAdapter implements Adapter { @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); 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); req.getParameters().setQueryStringCharset(connector.getURICharset()); } if (connector.getXpoweredBy()) { response.addHeader("X-Powered-By" , POWERED_BY); } boolean async = false ; boolean postParseSuccess = false ; req.getRequestProcessor().setWorkerThreadName(THREAD_NAME.get()); try { postParseSuccess = postParseRequest(req, request, res, response); if (postParseSuccess) { request.setAsyncSupported( connector.getService().getContainer().getPipeline().isAsyncSupported()); connector.getService().getContainer().getPipeline().getFirst().invoke( request, response); } 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 throwable = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); if (!request.isAsyncCompleting() && throwable != null ) { request.getAsyncContextInternal().setErrorState(throwable, true ); } } else { request.finishRequest(); response.finishResponse(); } } catch (IOException e) { } finally { AtomicBoolean error = new AtomicBoolean (false ); res.action(ActionCode.IS_ERROR, error); if (request.isAsyncCompleting() && error.get()) { res.action(ActionCode.ASYNC_POST_PROCESS, null ); async = false ; } if (!async && postParseSuccess) { Context context = request.getContext(); Host host = request.getHost(); long time = System.currentTimeMillis() - req.getStartTime(); if (context != null ) { context.logAccess(request, response, time, false ); } else if (response.isError()) { if (host != null ) { host.logAccess(request, response, time, false ); } else { connector.getService().getContainer().logAccess( request, response, time, false ); } } } req.getRequestProcessor().setWorkerThreadName(null ); if (!async) { updateWrapperErrorCount(request, response); request.recycle(); response.recycle(); } } } }
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
就是调用处理链来处理请求和写响应数据的关键:
那 connector.getService().getContainer()
就是拿到了 Engine
对象,再通过 getPipeline().getFirst()
拿到第一个 Pipeline
处理器,开始进行调用,也就是图中的 StandardEngineValve
,图中还有 ValveA
和 ValveB
表示我们可以根据自己的需求进行 Pipeline
的组装:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 final class StandardEngineValve extends ValveBase { @Override public final void invoke (Request request, Response response) throws IOException, ServletException { Host host = request.getHost(); if (host == null ) { response.sendError (HttpServletResponse.SC_BAD_REQUEST, sm.getString("standardEngine.noHost" , request.getServerName())); return ; } if (request.isAsyncSupported()) { request.setAsyncSupported(host.getPipeline().isAsyncSupported()); } host.getPipeline().getFirst().invoke(request, response); } }
那我使用的是默认的配置,Host
的 Pipeline
第一个即是 AccessLogValve
来处理请求的记录信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public abstract class AbstractAccessLogValve extends ValveBase implements AccessLog { @Override public void invoke (Request request, Response response) throws IOException, ServletException { if (tlsAttributeRequired) { request.getAttribute(Globals.CERTIFICATES_ATTR); } for (CachedElement element : cachedElements) { element.cache(request); } getNext().invoke(request, response); } }
然后交给 ErrorReportValve
处理,他是先将 Request
继续传递下去,如果 Response
响应的是错误的,那么会根据需求渲染错误的页面,也就是我们经常看到的 Tomcat
的错误页面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public class ErrorReportValve extends ValveBase { @Override public void invoke (Request request, Response response) throws IOException, ServletException { getNext().invoke(request, response); if (response.isCommitted()) { if (response.setErrorReported()) { try { response.flushBuffer(); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); } response.getCoyoteResponse().action(ActionCode.CLOSE_NOW, request.getAttribute(RequestDispatcher.ERROR_EXCEPTION)); } return ; } Throwable throwable = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); if (request.isAsync() && !request.isAsyncCompleting()) { return ; } if (throwable != null && !response.isError()) { response.reset(); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } response.setSuspended(false ); try { report(request, response, throwable); } catch (Throwable tt) { ExceptionUtils.handleThrowable(tt); } } }
ErrorReportValve
的接下来一个是 StandardHostValve
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 final class StandardHostValve extends ValveBase { @Override public final void invoke (Request request, Response response) throws IOException, ServletException { Context context = request.getContext(); if (context == null ) { return ; } if (request.isAsyncSupported()) { request.setAsyncSupported(context.getPipeline().isAsyncSupported()); } boolean asyncAtStart = request.isAsync(); try { context.bind(Globals.IS_SECURITY_ENABLED, MY_CLASSLOADER); if (!asyncAtStart && !context.fireRequestInitEvent(request.getRequest())) { return ; } try { if (!response.isErrorReportRequired()) { context.getPipeline().getFirst().invoke(request, response); } } catch (Throwable t) { ExceptionUtils.handleThrowable(t); container.getLogger().error("Exception Processing " + request.getRequestURI(), t); if (!response.isErrorReportRequired()) { request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t); throwable(request, response, t); } } response.setSuspended(false ); Throwable t = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); if (!context.getState().isAvailable()) { return ; } if (response.isErrorReportRequired()) { AtomicBoolean result = new AtomicBoolean (false ); response.getCoyoteResponse().action(ActionCode.IS_IO_ALLOWED, result); if (result.get()) { if (t != null ) { throwable(request, response, t); } else { status(request, response); } } } if (!request.isAsync() && !asyncAtStart) { context.fireRequestDestroyEvent(request.getRequest()); } } finally { if (ACCESS_SESSION) { request.getSession(false ); } context.unbind(Globals.IS_SECURITY_ENABLED, MY_CLASSLOADER); } } }
Host
有了,接下来就是 Context
的 Pipeline
了吧,不过默认第一个是 AuthenticatorValve
但是我们没有配置什么鉴权的请求,所以我打算跳过他,接下来就是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 final class StandardContextValve extends ValveBase { @Override public final void invoke (Request request, Response response) throws IOException, ServletException { 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 ; } Wrapper wrapper = request.getWrapper(); if (wrapper == null wrapper.isUnavailable()) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return ; } try { response.sendAcknowledgement(); } catch (IOException ioe) { container.getLogger().error(sm.getString( "standardContextValve.acknowledgeException" ), ioe); request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, ioe); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return ; } if (request.isAsyncSupported()) { request.setAsyncSupported(wrapper.getPipeline().isAsyncSupported()); } wrapper.getPipeline().getFirst().invoke(request, response); } }
StandardWrapperValve
基本可以当成表示我们的 webapp
了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 final class StandardWrapperValve extends ValveBase { @Override public final void invoke (Request request, Response response) throws IOException, ServletException { boolean unavailable = false ; Throwable throwable = null ; long t1=System.currentTimeMillis(); requestCount.incrementAndGet(); StandardWrapper wrapper = (StandardWrapper) getContainer(); Servlet servlet = null ; Context context = (Context) wrapper.getParent(); if (!context.getState().isAvailable()) { response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("standardContext.isUnavailable" )); unavailable = true ; } if (!unavailable && wrapper.isUnavailable()) { container.getLogger().info(sm.getString("standardWrapper.isUnavailable" , wrapper.getName())); long available = wrapper.getAvailable(); if ((available > 0L ) && (available < Long.MAX_VALUE)) { response.setDateHeader("Retry-After" , available); response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("standardWrapper.isUnavailable" , wrapper.getName())); } else if (available == Long.MAX_VALUE) { response.sendError(HttpServletResponse.SC_NOT_FOUND, sm.getString("standardWrapper.notFound" , wrapper.getName())); } unavailable = true ; } try { if (!unavailable) { servlet = wrapper.allocate(); } } catch (UnavailableException e) { } MessageBytes requestPathMB = request.getRequestPathMB(); DispatcherType dispatcherType = DispatcherType.REQUEST; if (request.getDispatcherType()==DispatcherType.ASYNC) dispatcherType = DispatcherType.ASYNC; request.setAttribute(Globals.DISPATCHER_TYPE_ATTR,dispatcherType); request.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, requestPathMB); ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet); try { if ((servlet != null ) && (filterChain != null )) { if (context.getSwallowOutput()) { try { SystemLogHandler.startCapture(); if (request.isAsyncDispatching()) { request.getAsyncContextInternal().doInternalDispatch(); } else { filterChain.doFilter(request.getRequest(), response.getResponse()); } } finally { String log = SystemLogHandler.stopCapture(); if (log != null && log.length() > 0 ) { context.getLogger().info(log); } } } else { if (request.isAsyncDispatching()) { request.getAsyncContextInternal().doInternalDispatch(); } else { filterChain.doFilter (request.getRequest(), response.getResponse()); } } } } catch (ClientAbortException CloseNowException e) { } finally { if (filterChain != null ) { filterChain.release(); } try { if (servlet != null ) { wrapper.deallocate(servlet); } } catch (Throwable e) { ExceptionUtils.handleThrowable(e); container.getLogger().error(sm.getString("standardWrapper.deallocateException" , wrapper.getName()), e); if (throwable == null ) { throwable = e; exception(request, response, e); } } try { if ((servlet != null ) && (wrapper.getAvailable() == Long.MAX_VALUE)) { wrapper.unload(); } } catch (Throwable e) { ExceptionUtils.handleThrowable(e); container.getLogger().error(sm.getString("standardWrapper.unloadException" , wrapper.getName()), e); if (throwable == null ) { exception(request, response, e); } } long t2=System.currentTimeMillis(); long time=t2-t1; processingTime += time; if ( time > maxTime) maxTime=time; if ( time < minTime) minTime=time; } } }
然后,通过了一个 Filter
之后,就可以进入我们 webapp
的 Servlet
进行处理了,反正我们通常是使用 SpringMVC
,Servlet
通常都是 DispatchServlet
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 public final class ApplicationFilterChain implements FilterChain { @Override public void doFilter (ServletRequest request, ServletResponse response) throws IOException, ServletException { if ( Globals.IS_SECURITY_ENABLED ) { final ServletRequest req = request; final ServletResponse res = response; try { java.security.AccessController.doPrivileged( new java .security.PrivilegedExceptionAction<Void>() { @Override public Void run () throws ServletException, IOException { internalDoFilter(req,res); return null ; } } ); } catch ( PrivilegedActionException pe) { Exception e = pe.getException(); if (e instanceof ServletException) throw (ServletException) e; else if (e instanceof IOException) throw (IOException) e; else if (e instanceof RuntimeException) throw (RuntimeException) e; else throw new ServletException (e.getMessage(), e); } } else { internalDoFilter(request,response); } } private void internalDoFilter (ServletRequest request, ServletResponse response) throws IOException, ServletException { if (pos < n) { ApplicationFilterConfig filterConfig = filters[pos++]; try { Filter filter = filterConfig.getFilter(); if (request.isAsyncSupported() && "false" .equalsIgnoreCase( filterConfig.getFilterDef().getAsyncSupported())) { request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, Boolean.FALSE); } 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 ; } try { if (ApplicationDispatcher.WRAP_SAME_OBJECT) { lastServicedRequest.set(request); lastServicedResponse.set(response); } if (request.isAsyncSupported() && !servletSupportsAsync) { request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, Boolean.FALSE); } if ((request instanceof HttpServletRequest) && (response instanceof HttpServletResponse) && Globals.IS_SECURITY_ENABLED ) { final ServletRequest req = request; final ServletResponse res = response; Principal principal = ((HttpServletRequest) req).getUserPrincipal(); Object[] args = new Object []{req, res}; SecurityUtil.doAsPrivilege("service" , servlet, classTypeUsedInService, args, principal); } else { servlet.service(request, response); } } catch (IOException ServletException RuntimeException e) { throw e; } catch (Throwable e) { e = ExceptionUtils.unwrapInvocationTargetException(e); ExceptionUtils.handleThrowable(e); throw new ServletException (sm.getString("filterChain.servlet" ), e); } finally { if (ApplicationDispatcher.WRAP_SAME_OBJECT) { lastServicedRequest.set(null ); lastServicedResponse.set(null ); } } } }
那最后完善下那幅请求图: