对于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. NOI2015

    D1T1 并查集. #include<cstdio> #include<cstdlib> #include<iostream> #include<fstrea ...

  2. joomla安装插件报错:上传文件到服务器发生了一个错误。 过小的PHP文件上传尺寸

    在安装joomla的AKeeba插件的时候报错如下:上传文件到服务器发生了一个错误. 过小的PHP文件上传尺寸.解决方法是修改php.ini文件,打开文件后搜索upload_max_filesize! ...

  3. 【hihoCoder第十五周】最近公共祖先·二

    老实说我没有读题,看见标题直接就写了,毕竟hiho上面都是裸的算法演练. 大概看了下输入输出,套着bin神的模板,做了个正反map映射,但是怎么都得不了满分.等这周结束后,找高人询问下trick. 若 ...

  4. You don't have permission to access / on this server for debian_8

    Forbidden You don't have permission to access / on this server. Apache/2.4.10 (Debian) Server at www ...

  5. (转载)图片左右滚动控件(带倒影)——重写Gallery

    今天在网上找了些资料,做了一个图片左右滚动的Demo,类似幻灯片播放,同时,图片带倒影效果,运行效果如下图: 实现方式是重写Gallery,使用自定义的Gallery来实现这一效果,工程一共三个文件, ...

  6. [RxJS] Completing a Stream with TakeWhile

    Subscribe can take three params: subscribe( (x)=> console.log(x), err=> console.log(err), ()=& ...

  7. [RxJS] Combining Streams with CombineLatest

    Two streams often need to work together to produce the values you’ll need. This lesson shows how to ...

  8. hdu1047(模拟大量的循环添加)

    标题信息:总结多个大整数,(使用add循环相加的功能) http://acm.hdu.edu.cn/showproblem.php? pid=1047 AC代码: /**  *大数的循环加法,转化为字 ...

  9. Android 打造形形色色的进度条 实现可以如此简单

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43371299 ,本文出自:[张鸿洋的博客] 1.概述 最近需要用进度条,秉着不重 ...

  10. 转载:android——eclipse如何去除Ctrl+shift+R组合键查找到的.class文件

    转载自:http://blog.csdn.net/virgilli/article/details/22500409 AS里面的build文件下一堆的.class 文件,当你要定位资源文件的时候,有些 ...