Struts
框架本身大致可以分为
个部分
核心控制器FilterDispatcher
业务控制器Action和用户实现的企业业务逻辑组件
核心控制器FilterDispatcher
核心控制器 FilterDispatcher是Struts 框架的基础包含了框架内部的控制流程和处理机制业务控制器Action和业务逻辑组件是需要用户来自己实现的用户在开发Action和业务逻辑组件的同时还需要编写相关的配置文件供核心控制器FilterDispatcher来使用
Struts 的工作流程相对于Struts 要简单与WebWork框架基本相同所以说Struts 是WebWork的升级版本Struts 框架按照模块来划分可以分为Servlet FiltersStruts核心模块拦截器和用户实现部分Struts 框架结构图如图所示
图 Struts 框架结构图
一个请求在Struts 框架中的处理大概分为以下几个步骤
客户端提交一个(HttpServletRequest)请求如上文在浏览器中输入
就是提交一个(HttpServletRequest)请求
请求被提交到一系列(主要是层)的过滤器(Filter)如(ActionContextCleanUp其他过滤器(SiteMesh等) FilterDispatcher)注意这里是有顺序的先ActionContext CleanUp再其他过滤器(Othter FiltersSiteMesh等)最后到FilterDispatcher
FilterDispatcher是控制器的核心就是MVC的Struts 实现中控制层(Controller)的核心
FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(HttpServlet Request)请求如果ActionMapper决定需要调用某个ActionFilterDispatcher则把请求的处理交给ActionProxy
ActionProxy通过Configuration Manager(strutsxml)询问框架的配置文件找到需要调用的Action类例如用户注册示例将找到UserReg类
ActionProxy创建一个ActionInvocation实例同时ActionInvocation通过代理模式调用Action但在调用之前ActionInvocation会根据配置加载Action相关的所有Interceptor(拦截器)
一旦Action执行完毕ActionInvocation负责根据strutsxml中的配置找到对应的返回结果result
Struts 的核心控制器是FilterDispatcher有个重要的方法destroy()doFilter()和Init()可以在Struts 的下载文件夹中找到源代码如代码所示
代码 核心控制器FilterDispatcher
public class FilterDispatcher implements StrutsStatics Filter {
/**
* 定义一个Log实例
*/
private static final Log LOG = LogFactorygetLog(FilterDispatcherclass)
… …
/**
* 存放属性文件中的STRUTS_IN_ENCODING值
*/
private static String encoding;
/**
* 定义ActionMapper实例
*/
private static ActionMapper actionMapper;
/**
* 定义FilterConfig实例
*/
private FilterConfig filterConfig;
protected Dispatcher dispatcher;
/**
* 创建一个默认的dispatcher初始化filter
* 设置默认的packages *
*/
public void init(FilterConfig filterConfig) throws ServletException {
thisfilterConfig = filterConfig;
dispatcher = createDispatcher(filterConfig)
dispatcherinit()
String param = filterConfiggetInitParameter(packages)
String packages = orgapachestrutsstatic template orgapachestrutsinterceptordebugging;
if (param != null) {
packages = param + + packages;
}
thispathPrefixes = parse(packages)
}
//销毁filter方法
public void destroy() {
if (dispatcher == null) {
LOGwarn(something is seriously wrong Dispatcher is not initialized (null) )
} else {
dispatchercleanup()
}
}
/**
* 处理一个Action或者资源请求
*
* filter尝试将请求同action mapping相匹配
* 如果找到将执行dispatcher的serviceAction方法
* 如果Action处理失败 doFilter将建立一个异常
*
* 如果请求静态资源
* 资源将被直接复制给 response
*
* 如果找不到匹配Action 或者静态资源则直接跳出
public void doFilter(ServletRequest req ServletResponse res FilterChain chain) throws IOException ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
ServletContext servletContext = getServletContext()
String timerKey = FilterDispatcher_doFilter: ;
try {
UtilTimerStackpush(timerKey)
request = prepareDispatcherAndWrapRequest(request response)
ActionMapping mapping;
try {
mapping=actionMappergetMapping(request dispatchergetConfigurationManager())
} catch (Exception ex) {
LOGerror(error getting ActionMapping ex)
dispatchersendError(request response servletContext HttpServletResponseSC_INTERNAL_SERVER_ERROR ex)
return;
}
if (mapping == null) {
String resourcePath = RequestUtilsgetServletPath(request)
if (equals(resourcePath) && null != requestgetPathInfo()) {
resourcePath = requestgetPathInfo()
}
if (serveStatic && resourcePathstartsWith(/struts)) {
String name = resourcePathsubstring(/strutslength())
findStaticResource(name request response)
} else {
//为一个普通的request 则通过
chaindoFilter(request response)
}
return;
}
/**
*这个方法询问ActionMapper是否需要调用某个Action来处理这个(request)请求
*如果ActionMapper决定需要调用某个Action
*FilterDispatcher则把请求的处理交给ActionProxy
dispatcherserviceAction(request response servletContext mapping)
} finally {
try {
ActionContextCleanUpcleanUp(req)
} finally {
UtilTimerStackpop(timerKey)
}
}
}
… …
}
在doFilter()方法中将调用dispatcherserviceAction该方法如果找到相应的Action将把用户请求交给ActionProxyserviceAction()代码在Dispatcherjava中如代码所示
代码 Dispatcher类
public class Dispatcher {
…
/**
* 为mapping加载类并调用相应的方法或者直接返回result
*
* 根据用户请求的参数建立Action上下文
* 根据指定的Action名称和包空间名称加载一个Action代理 ActionProxy
* 然后Action的相应方法将被执行
*/
public void serviceAction(HttpServletRequest request HttpServletResponse response ServletContext context ActionMapping mapping) throws ServletException {
Map extraContext = createContextMap(request response mapping context)
//如果存在一个值栈则建立一个新的并复制以备Action使用
ValueStack stack = (ValueStack) requestgetAttribute(ServletActionContextSTRUTS_VALUESTACK_KEY)
if (stack!= null) {
extraContextput(ActionContextVALUE_STACK ValueStackFactorygetFactory()createValueStack(stack))
}
String timerKey = Handling request from Dispatcher;
try {
UtilTimerStackpush(timerKey)
String namespace = mappinggetNamespace()
String name = mappinggetName()
String method = mappinggetMethod()
Configuration config = configurationManagergetConfiguration()
//FilterDispatcher把请求的处理交给ActionProxy
ActionProxy proxy = configgetContainer()getInstance(ActionProxyFactoryclass)createActionProxy(namespace name extraContext true false)
proxysetMethod(method)
requestsetAttribute(ServletActionContextSTRUTS_VALUESTACK_KEY proxygetInvocation()getStack())
//ActionMapping 直接返回一个result
if (mappinggetResult() != null) {
Result result = mappinggetResult()
resultexecute(proxygetInvocation())
} else {
proxyexecute()
}
if (stack != null) {
requestsetAttribute(ServletActionContextSTRUTS_VALUESTACK_KEY stack)
}
} catch (ConfigurationException e) {
LOGerror(Could not find action or result e)
sendError(request response context HttpServletResponseSC_NOT_FOUND e)
} catch (Exception e) {
throw new ServletException(e)
} finally {
UtilTimerStackpop(timerKey)
}
}
…
}
从上面代码中可以看出来Struts 用于处理用户请求的Action实例并不是用户实现的业务控制器而是Action代理关于Action代理相关内容读者可以参考拦截器章节的介绍