Struts2源代码解读之Action调用
对于Struts2源代码的分析已经有些时日了,虽然网上有很多解读代码,不过自己还是写一个放上来,供大家参考一下。
解读过程:
直接在action类中打断点(包括构造函数和待执行方法)进行debug调试,查看调用栈即可找到整个执行过程,下面用一张图来表述。
说明一下:
1.下面样例对应Action类为UserAction,在步骤9创建,待调用的方法为addUser
2.因为默认拦截器比较多,下面样例只列了两个拦截器,ExceptionMappingInterceptor和DebuggingInterceptor,限于篇幅,其他的拦截器没有列出;
3.在StrutsSpringObjectFactory到生成UserAction对象之间还有一些类的调用,同样限于篇幅,就省略了。
下面的代码就是StrutsPrepareAndExecuteFilter的doFilter方法,有请求达到时,因为在web.xml配置了StrutsPrepareAndExecuteFilter作为过滤器,所以就会执行到doFilter方法中来,下面的调用过程大致如下:
1.将输入参数转为HttpServletRequest和HttpServletResponse对象
2.如果不符合过滤要求,则直接转由下一个过滤器进行处理
3.设置字符编码和本地化信息
4.创建Action执行上下文对象
5.对request对象进行封装处理
6.通过配置信息查找请求对应的actionMapping对象
7.执行action对象对应的方法,也就是上面流程图所展示的过程
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
chain.doFilter(request, response);
} else {
prepare.setEncodingAndLocale(request, response);
prepare.createActionContext(request, response);
prepare.assignDispatcherToThread();
request = prepare.wrapRequest(request);
ActionMapping mapping = prepare.findActionMapping(request, response, true);
if (mapping == null) {
boolean handled = execute.executeStaticResourceRequest(request, response);
if (!handled) {
chain.doFilter(request, response);
}
} else {
execute.executeAction(request, response, mapping);
}
}
} finally {
prepare.cleanupRequest(request);
}
}
在调测过程中,特别留意了ParameterInterceptor这个拦截器,没有这个拦截器,页面的参数就无法设置到Action类中去。
看到网上有人说到自定义拦截器的时候,必须要关联defaultStack(<interceptor-ref name="defaultStack"/>),其实这没有清楚,为什么必须这样。
defaulStack中包含很多个拦截器,其实不是所有action都需要这么多拦截器的,说实话我没有尝试过到底哪种类型的操作需要哪些拦截器,如果只是需要完成页面的值设置到action中,则只需要自定义拦截器时关联ParameterInterceptor即可,即:
<interceptor-ref name="params">
<param name="excludeParams">^action:.*,^method:.*</param>
</interceptor-ref>
ParameterInterceptor设置值到Action中的具体代码如下:
外部代码调用intercept方法,然后调用到doIntercept方法,将值设置到Action中则是通过下面代码中的setParameters(action, stack, parameters);这一行完成的。
public String intercept(ActionInvocation invocation) throws Exception {
if (applyInterceptor(invocation)) {
return doIntercept(invocation);
}
return invocation.invoke();
}
public String doIntercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
if (!(action instanceof NoParameters)) {
ActionContext ac = invocation.getInvocationContext();
final Map<String, Object> parameters = retrieveParameters(ac);
if (LOG.isDebugEnabled()) {
LOG.debug("Setting params " + getParameterLogMap(parameters));
}
if (parameters != null) {
Map<String, Object> contextMap = ac.getContextMap();
try {
ReflectionContextState.setCreatingNullObjects(contextMap, true);
ReflectionContextState.setDenyMethodExecution(contextMap, true);
ReflectionContextState.setReportingConversionErrors(contextMap, true);
ValueStack stack = ac.getValueStack();
setParameters(action, stack, parameters);
} finally {
ReflectionContextState.setCreatingNullObjects(contextMap, false);
ReflectionContextState.setDenyMethodExecution(contextMap, false);
ReflectionContextState.setReportingConversionErrors(contextMap, false);
}
}
}
return invocation.invoke();
}
Struts2源代码解读之Action调用的更多相关文章
- struts2源代码学习之初始化(一)
看struts2源代码已有一段时日,从今天開始,就做一个总结吧. 首先,先看看怎么调试struts2源代码吧,主要是下面步骤: 使用Myeclipse创建一个webproject 导入struts2须 ...
- struts2源代码分析(个人觉得非常经典)
读者如果曾经学习过Struts1.x或者有过Struts1.x的开发经验,那么千万不要想当然地以为这一章可以跳过.实际上Struts1.x与Struts2并无我们想象的血缘关系.虽然Struts2的开 ...
- Struts2基于注解的Action配置
使用注解来配置Action的最大好处就是可以实现零配置,但是事务都是有利有弊的,使用方便,维护起来就没那么方便了. 要使用注解方式,我们必须添加一个额外包:struts2-convention-plu ...
- Struts2(四):在Action中如何访问Web资源
1.什么WEB资源? HttpServletRequest,HttpServletRespone,HttpApplication,ServletContext,HttpSession等原生Servle ...
- linux内核奇遇记之md源代码解读之四
linux内核奇遇记之md源代码解读之四 转载请注明出处:http://blog.csdn.net/liumangxiong 运行阵列意味着阵列经历从无到有,建立了作为一个raid应有的属性(如同步重 ...
- Apache OFbiz entity engine源代码解读
简单介绍 近期一直在看Apache OFbiz entity engine的源代码.为了能够更透彻得理解,也由于之前没有看人别人写过分析它的文章,所以决定自己来写一篇. 首先,我提出一个问题,假设你有 ...
- Struts2利用注解实现action跳转
使用注解来配置Action的最大好处就是可以实现零配置,但是事务都是有利有弊的,使用方便,维护起来就没那么方便了. 要使用注解方式,我们必须添加一个额外包:struts2-convention-plu ...
- Struts2基础学习(二)—Action
一.ActionSupport 为了让用户开发的Action类更加规范,Struts2提供了一个Action接口,这个接口定义了Struts2的Action处理类应该实现的规范.下面是标准A ...
- Struts2之配置文件中Action的详细配置
在Struts2之配置一文中,我们知道一个struts配置文件可以分为三部分:常量配置 包含其他配置文件的配置 Action配置 . 这其中 常量配置 和 包含其他配置文件的配置 二 ...
随机推荐
- 2015.11.27初识java一集简单的java小程序
JAVA配置环境变量方法: 1.打开我的电脑--属性--高级--环境变量 2.新建系统变量JAVA_HOME 和CLASSPATH 变量名:JAVA_HOME变量值:D:\Java\jdk1.7.0_ ...
- Perl 多线程模块 Parallel::ForkManager
Perl 多线程模块 Parallel::ForkManager 一个简单的并行处理模块.这个是用来对付循环的多线程处理. 放在循环前面. Table of Contents 1 Synops内容简介 ...
- UVA 10400 Game Show Math (dfs + 记忆化搜索)
Problem H Game Show Math Input: standard input Output: standard output Time Limit: 15 seconds A game ...
- JMeter 参数化、检查点、集合点
参数化:简单的来理解一下,我们录制了一个脚本,这个脚本中有登录操作,需要输入用户名和密码,假如系统不允许相同的用户名和密码同时登录,或者想更好的模拟多个用户来登录系统. 这个时候就需要对用户名和密 ...
- [RxJS] Resubscribing to a Stream with Repeat
When you complete a stream, there’s no way to restart it, you must resubscribe. This lesson shows ho ...
- 寒哥细谈之AutoLayout全解
文/南栀倾寒(简书作者)原文链接:http://www.jianshu.com/p/683fbcbfb705著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 看到群中好多朋友还停留在Fr ...
- LVM管理
一.步骤: 1.创建新的分区,并修改分区类型为8e 2.创建物理卷PV 3.将新建的PV添加到要扩展的VG中 4.用命令lvextend或lvresize来将新加入的PE添加到要扩展的LV中 5.用命 ...
- Linux下找不到动态链接库
1.生成静态库 生成静态库使用ar工具,其实ar是archive的意思 $ar cqs libhello.a hello.o 2.生成动态库 用gcc来完成,由于可能存在多个版本,因此通常指定版本号: ...
- nginx使用keepalived实现高可用
环境: 主:linux-node1 110.0.0.137 备:linux-node2 110.0.0.138 VIP: 110.0.0.120 NGINX安装: # rpm -ivh h ...
- Asp.net MVC4 捆绑和压缩
减少加载JavaScript和css文件加载时间 减少http请求次数和数据大小 无需配置 允许自定义和扩展