对于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调用的更多相关文章

  1. struts2源代码学习之初始化(一)

    看struts2源代码已有一段时日,从今天開始,就做一个总结吧. 首先,先看看怎么调试struts2源代码吧,主要是下面步骤: 使用Myeclipse创建一个webproject 导入struts2须 ...

  2. struts2源代码分析(个人觉得非常经典)

    读者如果曾经学习过Struts1.x或者有过Struts1.x的开发经验,那么千万不要想当然地以为这一章可以跳过.实际上Struts1.x与Struts2并无我们想象的血缘关系.虽然Struts2的开 ...

  3. Struts2基于注解的Action配置

    使用注解来配置Action的最大好处就是可以实现零配置,但是事务都是有利有弊的,使用方便,维护起来就没那么方便了. 要使用注解方式,我们必须添加一个额外包:struts2-convention-plu ...

  4. Struts2(四):在Action中如何访问Web资源

    1.什么WEB资源? HttpServletRequest,HttpServletRespone,HttpApplication,ServletContext,HttpSession等原生Servle ...

  5. linux内核奇遇记之md源代码解读之四

    linux内核奇遇记之md源代码解读之四 转载请注明出处:http://blog.csdn.net/liumangxiong 运行阵列意味着阵列经历从无到有,建立了作为一个raid应有的属性(如同步重 ...

  6. Apache OFbiz entity engine源代码解读

    简单介绍 近期一直在看Apache OFbiz entity engine的源代码.为了能够更透彻得理解,也由于之前没有看人别人写过分析它的文章,所以决定自己来写一篇. 首先,我提出一个问题,假设你有 ...

  7. Struts2利用注解实现action跳转

    使用注解来配置Action的最大好处就是可以实现零配置,但是事务都是有利有弊的,使用方便,维护起来就没那么方便了. 要使用注解方式,我们必须添加一个额外包:struts2-convention-plu ...

  8. Struts2基础学习(二)—Action

    一.ActionSupport      为了让用户开发的Action类更加规范,Struts2提供了一个Action接口,这个接口定义了Struts2的Action处理类应该实现的规范.下面是标准A ...

  9. Struts2之配置文件中Action的详细配置

    在Struts2之配置一文中,我们知道一个struts配置文件可以分为三部分:常量配置    包含其他配置文件的配置    Action配置  . 这其中 常量配置  和 包含其他配置文件的配置  二 ...

随机推荐

  1. DSP与单片机的区别

    以前刚学习单片机时,经过一订的编程,能实现很多不同的功能,当时就觉得单片机真的是神通广大.后来接触到DSP,发现DSP处理数字在通信上,更加方便.于是我就很好奇的问自己,DSP和单片机,究竟有什么区别 ...

  2. Joomla 3.x. How to edit registration page

    Adding registration form fields In order to add new fields to the registration form, database and fi ...

  3. Codeforces Round #322 (Div. 2) —— F. Zublicanes and Mumocrates

    It's election time in Berland. The favorites are of course parties of zublicanes and mumocrates. The ...

  4. 关于我们-EIBOA易博男装-互联网品质男装品牌-在线销售男士西服,衬衫,外套,西裤,领带|全场免运费,30天退换货保障

    关于我们 - 网站底部 | ELLE中国 | ELLE China 关于赫斯特国际集团 男人尚--专注男人时尚 关于男人尚 这些数据,你知道吗? 1.全国至少1亿男人的衬衫尺码错误: 2.57%的男人 ...

  5. c语言结构体2之变量赋值于字符串

    #include <stdio.h> #include <stdlib.h> struct dangdang { ]; ]; ]; int num; int bugnum; ] ...

  6. mysql 从data文件恢复数据库

    安装在D:\mysql\mysql-5.6.24-winx64下的mysql 由于系统坏了,移到另外一台机器上启动 步骤如下 1.复制以前的mysql安装文件及data文件下:2.全新安装mysql3 ...

  7. 升级IOS9,提示滑动升级,卡在password锁屏界面,无反应了

    注:升级之前一定要把锁屏password取消掉 若遇上述问题.可通过进入DFU 模式解决 进入DFU具体步骤.(进入成功后,屏幕为全黑) 注:在进入DFU操作时务必与电脑连接好数据线. 1.按住pow ...

  8. [置顶] 强制访问控制内核模块Smack

    Smack(Simplified Mandatory Access Control Kernel)是Casey Schaufler[15]于2007年在LSM基础上实现的Linux强制访问控制安全模块 ...

  9. read(),write() 读/写文件

    read read()是一个系统调用函数.用来从一个文件中,读取指定长度的数据到 buf 中. 使用read()时需要包含的头文件: <unistd.h> 函数原型: ssize_t re ...

  10. Node.js 之 express 入门 ejs include公共部分

    1. 直接进入express安装 因为之前有一篇文章我已经讲过怎么安装node了 而网上的教程也是非常多.所有直接进入到express.教程简陋 由于我比较笨 所有只要写到我自己明白就行. 这里有个教 ...