Webx的总体流程
WebxFrameworkFilter->AbstractWebxRootController->WebxRootControllerImpl->WebxControllerImpl->Pipeline
具体执行流程
Webx的主要流程,由于Webx是基于Servlet的Filter开发的
Request Contexts服务该服务负责访问和修改request和response,但不负责改变应用执行的流程。
Pipeline服务提供应用执行的流程,但不关心request和response。
public final void service(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws Exception {
RequestContext requestContext = null;
try {
requestContext = assertNotNull(getRequestContext(request, response), "could not get requestContext");
// 如果请求已经结束,则不执行进一步的处理。例如,当requestContext已经被重定向了,则立即结束请求的处理。
if (isRequestFinished(requestContext)) {
return;
}
// 请求未结束,则继续处理...
request = requestContext.getRequest();
response = requestContext.getResponse();
// 如果是一个内部请求,则执行内部请求
if (handleInternalRequest(request, response)) {
return;
}
// 如果不是内部的请求,并且没有被passthru,则执行handleRequest
if (isRequestPassedThru(request) || !handleRequest(requestContext)) {
// 如果请求被passthru,或者handleRequest返回false(即pipeline放弃请求),
// 则调用filter chain,将控制交还给servlet engine。
giveUpControl(requestContext, chain);
}
} catch (Throwable e) {
handleException(requestContext, request, response, e);
} finally {
commitRequest(requestContext);
}
}
其中getRequestContext对应RequestContext的执行过程,handleRequest函数对应执行pipeline流程,而commitRequest表示RequestContext的提交过程。
首先看一下RequestContext
public interface RequestContext {
/**
* 取得被包装的context。
*
* @return 被包装的<code>RequestContext</code>对象
*/
RequestContext getWrappedRequestContext();
/**
* 取得servletContext对象。
*
* @return <code>ServletContext</code>对象
*/
ServletContext getServletContext();
/**
* 取得request对象。
*
* @return <code>HttpServletRequest</code>对象
*/
HttpServletRequest getRequest();
/**
* 取得response对象。
*
* @return <code>HttpServletResponse</code>对象
*/
HttpServletResponse getResponse();
/** 开始一个请求。 */
void prepare();
/**
* 结束一个请求。
*
* @throws RequestContextException 如果失败
*/
void commit() throws RequestContextException;
}
可以看到执行需要重写prepare方法,提交需要重写commit方法。
RequestContext执行过程
会根据顺序的执行所有的RequestContext(已经init方法中进行了初始化)
public RequestContext getRequestContext(ServletContext servletContext, HttpServletRequest request,
HttpServletResponse response) {
assertInitialized();
// 异步请求(dispatcherType == ASYNC)开始时,如果已经存在request context,则直接取得并返回之。
boolean asyncDispatcher = request_isDispatcherType(request, DISPATCHER_TYPE_ASYNC);
RequestContext requestContext = null;
if (asyncDispatcher) {
requestContext = RequestContextUtil.getRequestContext(request);
}
if (requestContext == null) {
SimpleRequestContext innerReuestContext = new SimpleRequestContext(servletContext, request, response, this);
requestContext = innerReuestContext;
// 将requestContext放入request中,以便今后只需要用request就可以取得requestContext。
// 及早设置setRequestContext,以便随后的prepareRequestContext就能使用。
RequestContextUtil.setRequestContext(requestContext);
for (RequestContextFactory<?> factory : factories) {
requestContext = factory.getRequestContextWrapper(requestContext);
// 调用<code>requestContext.prepare()</code>方法
prepareReq