WebWork 工作流程
1、处理客户端提交的请求
客户端提交的请求由com.opensymphony.xwork.dispatcher.ServletDispatcher进行处理。ServletDispatche是一个HttpServlet。
ServletDispatche接收到客户端的请求以后,首先调用init方法进行初始化工作:
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
// 进行各种初始化
}
初始化完成之后,由service方法处理请求:
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException {
try {
// ....
serviceAction(request, response, getNameSpace(request), getActionName(request), getRequestMap(request), getParameterMap(request), getSessionMap(request), getApplicationMap());
} catch (IOException e) {
String message = "Could not wrap servlet request with MultipartRequestWrapper!";
log.error(message, e);
sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, new ServletException(message, e));
}
}
这里,service方法把请求转交给了serviceAction方法:
public void serviceAction(HttpServletRequest request, HttpServletResponse response, String namespace, String actionName, Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap) {
HashMap extraContext = createContextMap(requestMap, parameterMap, sessionMap, applicationMap, request, response, getServletConfig());
extraContext.put(SERVLET_DISPATCHER, this);
// ...
try {
ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext);
request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());
proxy.execute();
// ...
} catch (ConfigurationException e) {
log.error("Could not find action", e);
sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e);
// ...
}
到这里为止,WebWork就把处理Action的工作交给了XWork了,然后就等待XWork给结果了。
XWork怎么将结果返回给WebWork呢?
下面我们来看action部分的定义:
<action name="helloWebWorld" class="lesson03.HelloWebWorldAction">
<result name="success" type="dispatcher">ex01-success.jsp</result>
</action>
这里的result结点有一个type属性,这表示此action的结果应该怎样处理。
再来看看dispatcher类型的result是怎么定义的:
<result-type name="dispatcher" class="com.opensymphony.webwork.dispatcher.ServletDispatcherResult" default="true"/>
到这里就可以知道了处理是交给ServletDispatcherResult类来做的。
ServletDispatcherResult类继承了WebWorkResultSupport类,而WebWorkResultSupport实现了com.opensymphony.xwork.Result接口,此接口用来处理action的结果。
WebWorkResultSupport类定义了一个抽象的方法 -- doExecute,此方法用于实现对Result的处理。
下面来看看ServletDispatcherResult是怎么处理的:
public void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
PageContext pageContext = ServletActionContext.getPageContext();
if (pageContext != null) {
pageContext.include(finalLocation);
} else {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);
// if the view doesn't exist, let's do a 404
if (dispatcher == null) {
response.sendError(404, "result '" + finalLocation + "' not found");
return;
}
// If we're included, then include the view
// Otherwise do forward
// This allow the page to, for example, set content type
if (!response.isCommitted() && (request.getAttribute("javax.servlet.include.servlet_path") == null)) {
request.setAttribute("webwork.view_uri", finalLocation);
request.setAttribute("webwork.request_uri", request.getRequestURI());
dispatcher.forward(request, response);
} else {
dispatcher.include(request, response);
}
}
}
我们看到,最终调用的是dispatcher.forward(request, response);
这样就可以成功转到我们的目标页了。