public void init(FilterConfig filterConfig) throws ServletException { try { this.filterConfig = filterConfig; initLogging(); dispatcher = createDispatcher(filterConfig); dispatcher.init(); dispatcher.getContainer().inject(this); staticResourceLoader.setHostConfig(newFilterHostConfig(filterConfig)); } finally { ActionContext.setContext(null); } }
由上面的代码可以看出,在filterDispatcher的初始化中,
会初始化log,创建一个dispatcher并对他进行初始化,并调用它的container的inject方法,在这个方法中会根据
[struts-default.xml, struts-plugin.xml, struts.xml]这些配置文件,获取里面action,inceputor的配置信息,
放在ActionMapper里面。
当一个http请求过来时,经过层层过滤器,最后调用filterDispatcher过滤器,执行他的doFilter,代码如下:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { .... ActionMapping mapping; try { mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager()); } catch (Exception ex) { log.error("error getting ActionMapping", ex); dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex); return; } .... dispatcher.serviceAction(request, response, servletContext, mapping); .... }
在这个方法里面会根据
传入的HTTP信息,到ActionMapper查找是否需要调用某个action类,如果需要,获取该action在配置文件中的mapping,并掉用如下dispatcher的serviceAction方法:
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionMapping mapping) throws ServletException { .... try { UtilTimerStack.push(timerKey); String namespace = mapping.getNamespace(); String name = mapping.getName(); String method = mapping.getMethod(); Configuration config = configurationManager.getConfiguration(); ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy( namespace, name, method, extraContext, true, false); request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack()); // if the ActionMapping says to go straight to a result, do it! if (mapping.getResult() != null) { Result result = mapping.getResult(); result.execute(proxy.getInvocation()); } else { proxy.execute(); } .... }
在serviceAction方法中会创建需要调用的action的代理类,actionProxy,调用代理类的excute()方法。代码为:
public String execute() throws Exception { .... retCode = invocation.invoke(); .... }
如上在excute()方法中,会调用代理类的Invocation()方法,此刻,就会调用struts默认的一系列拦截器在struts-default.xml中定义。如ParametersInterceptor,ActionMappingParametersInteceptor拦截器和用户自己定义的拦截器,执行完后就会调用用户真正执行的action类的指定方法体