Rising Sun
BlogJava
::
首页
::
新随笔
::
联系
::
聚合
::
管理
::
148 随笔 :: 0 文章 :: 22 评论 :: 0 Trackbacks
<
2013年3月
>
日
一
二
三
四
五
六
24
25
26
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
常用链接
我的随笔
我的评论
我的参与
最新评论
留言簿
(10)
给我留言
查看公开留言
查看私人留言
随笔分类
cpp(3)
(rss)
css(6)
(rss)
hibernate+struts+spring(3)
(rss)
javascript(9)
(rss)
Lucene(3)
(rss)
oracle 数据库(6)
(rss)
云计算(4)
(rss)
其它(6)
(rss)
处理Excel poi(6)
(rss)
学习总结(15)
(rss)
环境设置(2)
(rss)
随笔档案
2015年1月 (3)
2014年12月 (1)
2014年9月 (1)
2014年6月 (2)
2014年4月 (2)
2014年1月 (2)
2013年12月 (3)
2013年11月 (1)
2013年10月 (2)
2013年8月 (2)
2013年7月 (3)
2013年5月 (3)
2013年3月 (9)
2013年2月 (8)
2013年1月 (4)
2012年10月 (1)
2012年9月 (2)
2012年8月 (1)
2012年7月 (3)
2012年5月 (1)
2012年1月 (1)
2011年3月 (1)
2010年12月 (1)
2009年12月 (1)
2009年10月 (1)
2009年8月 (4)
2009年7月 (3)
2009年6月 (2)
2009年5月 (2)
2009年4月 (3)
2008年11月 (3)
2008年10月 (2)
2008年9月 (1)
2008年8月 (2)
2008年7月 (3)
2008年5月 (1)
2007年11月 (1)
2007年10月 (2)
2007年9月 (2)
2007年8月 (3)
2007年7月 (6)
2007年6月 (3)
2007年4月 (2)
2006年12月 (2)
2006年11月 (1)
2006年10月 (2)
2006年9月 (3)
2006年8月 (3)
2006年7月 (26)
2005年11月 (4)
相册
我的相册
java--->ajax
BlueDavy
http://www.blogjava.net/BlueDavy/
css
css
eamoi
搜索
最新评论
1. re: request.getParameterValues与request.getParameter的区别:
5+5+
--5465
2. re: 关于filter验证用户权限
333
--12
3. re: Gson通过借助TypeToken获取泛型参数的类型的方法
博主如果解决了楼上的问题 请联系我 万分感谢 联系方式QQ 474233979
--yueguangxuanyuan
4. re: Gson通过借助TypeToken获取泛型参数的类型的方法
评论内容较长,点击标题查看
--yueguangxuanyuan
5. re: CMS,全称Concurrent Low Pause Collector gc[未登录]
很有用。非常感谢!!!!
--匿名
阅读排行榜
1. Gson通过借助TypeToken获取泛型参数的类型的方法(42668)
2. 304 Not Modified状态码(18896)
3. 电脑非法关机 导致ORA-01033:解决方法(9080)
4. struts2 -- interceptor(如何配置Interceptor) (7511)
5. MYSQL在默认的情况下查询是不区分大小写的(7340)
评论排行榜
1. Gson通过借助TypeToken获取泛型参数的类型的方法(6)
2. Busy Developers' Guide to HSSF Features (说明书)(3)
3. 对于网上看到Window.Open()传值(3)
4. excel 处理 Poi(1)
5. 关于filter验证用户权限(1)
struts2核心工作流程与原理(转)
1. Struts2架构图
这是Struts2官方站点提供的Struts 2 的整体结构。
2. Struts2部分类介绍
这部分从Struts2参考文档中翻译就可以了。
ActionMapper
ActionMapper其实是HttpServletRequest和Action调用请求的一个映射,它屏蔽了Action对于Request等java Servlet类的依赖。Struts2中它的默认实现类是DefaultActionMapper,ActionMapper很大的用处可以根据自己的需要来设计url格式,它自己也有Restful的实现,具体可以参考文档的docs\actionmapper.html。
ActionProxy&ActionInvocation
Action的一个代理,由ActionProxyFactory创建,它本身不包括Action实例,默认实现DefaultActionProxy是由ActionInvocation持有Action实例。ActionProxy作用是如何取得Action,无论是本地还是远程。而ActionInvocation的作用是如何执行Action,拦截器的功能就是在ActionInvocation中实现的。
ConfigurationProvider&Configuration
ConfigurationProvider就是Struts2中配置文件的解析器,Struts2中的配置文件主要是尤其实现类XmlConfigurationProvider及其子类StrutsXmlConfigurationProvider来解析。
3. Struts2请求流程
1、客户端发送请求
2、请求先通过ActionContextCleanUp-->FilterDispatcher
3、FilterDispatcher通过ActionMapper来决定这个Request需要调用哪个Action
4、如果ActionMapper决定调用某个Action,FilterDispatcher把请求的处理交给ActionProxy,这儿已经转到它的Delegate--Dispatcher来执行
5、ActionProxy根据ActionMapping和ConfigurationManager找到需要调用的Action类
6、ActionProxy创建一个ActionInvocation的实例
7、ActionInvocation调用真正的Action,当然这涉及到相关拦截器的调用
8、Action执行完毕,ActionInvocation创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener。添加PreResultListener可以在Interceptor中实现。
另一个版本:大同小异~
一个请求在Struts2框架中的处理大概分为以下几个步骤:
1.
客户端提起一个(HttpServletRequest)请求,如上文在浏览器中输入”http://localhost:8080/TestMvc/add.action”就是提起一个(HttpServletRequest)请求。
2.
请求被提交到一系列(主要是三层)的过滤器(Filter),如(ActionContextCleanUp、其他过滤器(SiteMesh等)、 FilterDispatcher)。注意这里是有顺序的,先ActionContextCleanUp,再其他过滤器(SiteMesh等)、最后到FilterDispatcher。
3.
FilterDispatcher是控制器的核心,就是mvc中c控制层的核心。下面粗略的分析下我理解的FilterDispatcher工作流程和原理:FilterDispatcher进行初始化并启用核心doFilter
其代码如下:
Java代码
public
void
doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws
IOException, ServletException ...{
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
ServletContext servletContext = filterConfig.getServletContext();
// 在这里处理了HttpServletRequest和HttpServletResponse。
DispatcherUtils du = DispatcherUtils.getInstance();
du.prepare(request, response);
//正如这个方法名字一样进行locale、encoding以及特殊request parameters设置
try
...{
request = du.wrapRequest(request, servletContext);
//对request进行包装
}
catch
(IOException e) ...{
String message =
"Could not wrap servlet request with MultipartRequestWrapper!"
;
LOG.error(message, e);
throw
new
ServletException(message, e);
}
ActionMapperIF mapper = ActionMapperFactory.getMapper();
//得到action的mapper
ActionMapping mapping = mapper.getMapping(request);
// 得到action 的 mapping
if
(mapping ==
null
) ...{
// there is no action in this request, should we look for a static resource?
String resourcePath = RequestUtils.getServletPath(request);
if
(
""
.equals(resourcePath) &&
null
!= request.getPathInfo()) ...{
resourcePath = request.getPathInfo();
}
if
(
"true"
.equals(Configuration.get(WebWorkConstants.WEBWORK_SERVE_STATIC_CONTENT))
&& resourcePath.startsWith(
"/webwork"
)) ...{
String name = resourcePath.substring(
"/webwork"
.length());
findStaticResource(name, response);
}
else
...{
// this is a normal request, let it pass through
chain.doFilter(request, response);
}
// WW did its job here
return
;
}
Object o =
null
;
try
...{
//setupContainer(request);
o = beforeActionInvocation(request, servletContext);
//整个框架最最核心的方法,下面分析
du.serviceAction(request, response, servletContext, mapping);
}
finally
...{
afterActionInvocation(request, servletContext, o);
ActionContext.setContext(
null
);
}
}
du.serviceAction(request, response, servletContext, mapping);
//这个方法询问ActionMapper是否需要调用某个Action来处理这个(request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
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());
//实例化Map请求 ,询问ActionMapper是否需要调用某个Action来处理这个(request)请求
extraContext.put(SERVLET_DISPATCHER,
this
);
OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);
if
(stack !=
null
) ...{
extraContext.put(ActionContext.VALUE_STACK,
new
OgnlValueStack(stack));
}
try
...{
ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext);
//这里actionName是通过两道getActionName解析出来的, FilterDispatcher把请求的处理交给ActionProxy,下面是ServletDispatcher的 TODO:
request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());
proxy.execute();
//通过代理模式执行ActionProxy
if
(stack !=
null
)...{
request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY,stack);
}
}
catch
(ConfigurationException e) ...{
log.error(
"Could not find action"
, e);
sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e);
}
catch
(Exception e) ...{
log.error(
"Could not execute action"
, e);
sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
}
}
4.
FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy。
5.
ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类.
如上文的struts.xml配置
Java代码
<?xml version=
"1.0"
encoding=
"GBK"
?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"
>
<struts>
<include file=
"struts-default.xml"
/>
<
package
name=
"struts2"
extends
=
"struts-default"
>
<action name=
"add"
class
=
"edisundong.AddAction"
>
<result>add.jsp</result>
</action>
</
package
>
</struts>
如果提交请求的是add.action,那么找到的Action类就是edisundong.AddAction。
6.
ActionProxy创建一个ActionInvocation的实例,同时ActionInvocation通过代理模式调用Action。但在调用之前ActionInvocation会根据配置加载Action相关的所有Interceptor。(Interceptor是struts2另一个核心级的概念)
下面我们来看看ActionInvocation是如何工作的:
ActionInvocation 是Xworks 中Action 调度的核心。而对Interceptor 的调度,也正是由ActionInvocation负责。ActionInvocation 是一个接口, 而DefaultActionInvocation 则是Webwork 对ActionInvocation的默认实现。
Interceptor 的调度流程大致如下:
1. ActionInvocation初始化时,根据配置,加载Action相关的所有Interceptor。
2. 通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor。
Interceptor将很多功能从我们的Action中独立出来,大量减少了我们Action的代码,独立出来的行为具有很好的重用性。XWork、WebWork的许多功能都是有Interceptor实现,可以在配置文件中组装Action用到的Interceptor,它会按照你指定的顺序,在Action执行前后运行。
那么什么是拦截器。
拦截器就是AOP(Aspect-Oriented Programming)的一种实现。(AOP是指用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。)
拦截器的例子这里就不展开了。
struts-default.xml文件摘取的内容:
Java代码
< interceptor name =
"alias"
class
=
"com.opensymphony.xwork2.interceptor.AliasInterceptor"
/>
< interceptor name =
"autowiring"
class
=
"com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"
/>
< interceptor name =
"chain"
class
=
"com.opensymphony.xwork2.interceptor.ChainingInterceptor"
/>
< interceptor name =
"conversionError"
class
=
"org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"
/>
< interceptor name =
"createSession"
class
=
"org.apache.struts2.interceptor.CreateSessionInterceptor"
/>
< interceptor name =
"debugging"
class
=
"org.apache.struts2.interceptor.debugging.DebuggingInterceptor"
/>
< interceptor name =
"external-ref"
class
=
"com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"
/>
< interceptor name =
"execAndWait"
class
=
"org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"
/>
< interceptor name =
"exception"
class
=
"com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"
/>
< interceptor name =
"fileUpload"
class
=
"org.apache.struts2.interceptor.FileUploadInterceptor"
/>
< interceptor name =
"i18n"
class
=
"com.opensymphony.xwork2.interceptor.I18nInterceptor"
/>
< interceptor name =
"logger"
class
=
"com.opensymphony.xwork2.interceptor.LoggingInterceptor"
/>
< interceptor name =
"model-driven"
class
=
"com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"
/>
< interceptor name =
"scoped-model-driven"
class
=
"com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"
/>
< interceptor name =
"params"
class
=
"com.opensymphony.xwork2.interceptor.ParametersInterceptor"
/>
< interceptor name =
"prepare"
class
=
"com.opensymphony.xwork2.interceptor.PrepareInterceptor"
/>
< interceptor name =
"static-params"
class
=
"com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"
/>
< interceptor name =
"scope"
class
=
"org.apache.struts2.interceptor.ScopeInterceptor"
/>
< interceptor name =
"servlet-config"
class
=
"org.apache.struts2.interceptor.ServletConfigInterceptor"
/>
< interceptor name =
"sessionAutowiring"
class
=
"org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"
/>
< interceptor name =
"timer"
class
=
"com.opensymphony.xwork2.interceptor.TimerInterceptor"
/>
< interceptor name =
"token"
class
=
"org.apache.struts2.interceptor.TokenInterceptor"
/>
< interceptor name =
"token-session"
class
=
"org.apache.struts2.interceptor.TokenSessionStoreInterceptor"
/>
< interceptor name =
"validation"
class
=
"com.opensymphony.xwork2.validator.ValidationInterceptor"
/>
< interceptor name =
"workflow"
class
=
"com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"
/>
< interceptor name =
"store"
class
=
"org.apache.struts2.interceptor.MessageStoreInterceptor"
/>
< interceptor name =
"checkbox"
class
=
"org.apache.struts2.interceptor.CheckboxInterceptor"
/>
< interceptor name =
"profiling"
class
=
"org.apache.struts2.interceptor.ProfilingActivationInterceptor"
/>
7.
一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。如上文中将结构返回“add.jsp”,但大部分时候都是返回另外一个action,那么流程又得走一遍………
1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
6 ActionProxy创建一个ActionInvocation的实例。
7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
在上述过程中所有的对象(Action,Results,Interceptors,等)都是通过ObjectFactory来创建的。
posted on 2013-03-05 09:31
brock
阅读(211)
评论(0)
编辑
收藏
所属分类:
hibernate+struts+spring
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
Chat2DB
C++博客
博问
管理
相关文章:
struts2核心工作流程与原理(转)
JSTL中fn表达式的使用说明【转自www.bitsCN.com】
hibernate +struts +spring ing ....
Powered by:
BlogJava
Copyright © brock