java

位置:IT落伍者 >> java >> 浏览文章

Struts2的整体流程(上)


发布日期:2019年06月17日
 
Struts2的整体流程(上)
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代理相关内容读者可以参考拦截器章节的介绍

上一篇:Spring 控制反转(IoC)容器

下一篇:Struts2教程10:国际化