首先,struts2是基于Servlet/JSP的应用,那么在web.xml中的配置也会起作用。如下片段
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在web.xml中配置了如上的过滤器。因为其url-pattern为/*,因此会对此web应用下的所有请求进行过滤,
那么StrutsPrepareAndExecuteFilter过滤器会对请求进行过滤。
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
ActionMapping mapping = prepare.findActionMapping(request, response, true);
if (mapping == null) {
...
} else {
//如果mapping不为null,那么执行action。此时,应用进入struts框架
//的控制中。
execute.executeAction(request, response, mapping);
}
}
} finally {
prepare.cleanupRequest(request);
}
}
执行executeAction方法,进入struts框架的控制之中。该方法定义如下:
public class ExecuteOperations {
private Dispatcher dispatcher;
/**
* Executes an action
*/
public void executeAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
dispatcher.serviceAction(request, response, servletContext, mapping);
}
}
然后通过dispatcher成员变量的serviceAction方法,下面是该方法的关键代码部分
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
ActionMapping mapping) throws ServletException {
...
try {
...
//获得ActionProxy接口的实现类的对象,具体是StrutsActionProxy的实例,准备调用其execute方法,
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method, extraContext, true, false);
...
if (mapping.getResult() != null) {
...
} else {
//执行action代理的execute方法
proxy.execute();
}
}
}
进入action代理的实际类StrutsActionProxy的execute方法中,调用ActionInvocation接口的invoke方
法,开始进行正式的处理。
public String execute() throws Exception {
ActionContext previous = ActionContext.getContext();
ActionContext.setContext(invocation.getInvocationContext());
try {
//此处的invocation成员变量是其父类DefaultActionProxy的成员变量。其运行时的对象是
//DefaultActionInvocation的实例
return invocation.invoke();
} finally {
if (cleanupContext)
ActionContext.setContext(previous);
}
}
进入DefaultActionInvocation的invoke方法后就开始了拦截器的处理。拦截器处理完后,调用用户编写的具
体action的处理逻辑。之后在对处理进行拦截器的后处理。拦截器处理和调用action的过程和过滤器过滤请求并
调用相应Servlet处理,再进行过滤器后处理的过程相似。
处理完后返回结果,再由StrutsPrepareAndExecuteFilter根据返回结果的逻辑视图,通过forward的方式来
请求具体的结果页面。结果页面生成响应发送给StrutsPrepareAndExecuteFilter,再由该过滤器返回给客户端。
至此,一个基本的请求流程结束。