doFilter分析
当Web请求到达服务器时,请求就会被Servlet容器(Tomcat)派发到相应的Servlet中去,而调用这些Servlet之前,满足一定条件的Filter也会被调用,我们之前在web.xml中配置的StrutsPrepareAndExeuteFilter就属于满足条件的Filter,因为它会拦截所有URL。当Filter被Servlet容器调用时,doFilter方法就开始执行了。我们现在prepare.setEncodingAndLocale(request, response);这一行打一个断点,这样就可以观察到每一个步骤的细节问题。
了解prepare
从字面上理解prepare.setEncodingAndLocale、prepare.createActionContext和prepare.assignDispatcherToThread的作用分别是用于处理编码与本地化、Action关联文信息、关联当前的Dispatcher与当前线程。
关于编码与本地化处理相关内容请参考源码与下图来理解:
方法createActionContext的作用就是创建一个与当前请求相关的ActionContext对象,后续的请求处理操作都会从这里取得相关信息。至于它到底把哪些东西进行了处理,是如何处理的,不在这里讲解,只说一下与ActionContext相关的技术问题。Struts1的一个缺陷就是Action是非线程安全的,也就是说,如果我们在Action中定义了共享资源,在并发请求时就可能会出现资源访问冲突的现象。举个例子来说,比如在Action中定义一个私有成员userName,这个userName每次都会从request中取得数据,当两个请求A和B先后到达后,B所得到的内容就会覆盖之前A所写入的内容,原因就是Action在内存中是唯一的,userName这个属性是共享!那么如何让两次请求可以互相独立呢,Struts2中的ActionContext就可以解决这个问题。
解读ActionContext
其实ActionContext并不是什么高级货,我们同样可以在Struts1中编写自己的ActionContext。下面我们详细解读一下ActionContext的源码。先看一下类图:
从类图上可以看出,ActionContext总共有两个部分,第一部分就是静态常量以及成员变量的定义,第二部分为操作方法定义。actionContext是一个精通的包级访问ThreadLocal类型变量,也就是说它仅对同包内的访问开放,拒绝其他访问。ThreadLocal在多线程访问中是一个很重要的概念,它将存储与每个线程管理起来,回顾一下上面A、B请求的例子,因为它们存放内容都在同一处,所以才会产生数据被覆盖的情况。而有了ThreadLocal之后,A可以把数据保存在与A线程相关的地方,B可以把数据保存在与B线程相关的地方,互不干扰。但为了能在一个地方储存更多的信息,Map结构可能就成为我们的首选数据结构了,所以类图中context就是一个Map类型的变量。存取数据时,最常用的就是get和put方法,而其他操作方法则是对Web程序的一种特定封装。(如果不了解ThreadLocal的话,先参考相关的JavaDoc,之后再来阅读ActionContext源码会收获更多)
如果真的明白了ActionContext的话,prepare.assignDispatcherToThread也就可以理解了,只是为当前Action要访问的Dispatcher找一个临时住所而已。
纯粹的Filter
excludedPatterns就是让StrutsPrepareAndExecuteFilter跳过某些URL不做后续的Struts处理,它的用法请参考Struts2相关文档说明。假设现在满足excludedPatterns的条件,那程序就会走入chain.doFilter中,也就是说,我们配置的Struts2实际上什么都没干,纯粹的一个Filter而已,没有使用到Struts2的任何功能。
资源清理
由于ActionContext和Dispatcher都使用到ThreadLocal,所以必须手动清理本次请求相关的内容,否则可能会因资源耗尽而产生内存溢出。具体的细节还是得参考ThreadLocal相关的文档。
请求处理 -StaticContentLoader VSActionMapping
在正式进入处理之前,Struts2先对request对象进行包装:
下面为Dispatcher.wrapRequest方法实现。主要与文件上传有关,如果对文件上传原来与实现有兴趣,可以参考http://www.servlets.com/和http://www.servlets.com/cos/:
ActionMapping
接下来就要正式进入Struts2流程控制的核心了,这些核心组件会在ActionMapping所提供的信息下互相协作,完成请求处理。ActionMapping从哪里来呢?深入PrepareOperations.findActionMapping就会发现,它是从Dispatcher的Container中取出的,进一步分析Dispatcher的Container,我们就会发现,实现的核心内容是依赖于xwork的ConfigurationManager,这部分内容在下节会进行详细分析,这里只需要知道ActionMapping是根据xwork的ConfigurationManager读取struts.xml返回的就足够了。ActionMapping返回后,处理就被分为两部分,根据当前所请求的URL,如果ActionMapping找到时,请求就被转发至Action处理,否则会根据静态配置信息来尝试取得静态资源。
静态资源处理
当以下面形式配置静态内容时,demo里所存放的内容就会被直接访问,这个打破了WEB-INF中内容不允许外部访问的常规。访问URL为:http://your_site:port/static/demo/your_static_resource
Action处理
当ActionMapping被成功的访问且不为空时,Action的处理就正式开始了。调用情况如下,基本上是利用xwork的功能,我们在下节,详细解读一下xwork的工作原理。
分享到:
相关推荐
Struts2 源码分析 Struts2 是一个基于MVC 模式的Web 应用程序框架,它...Struts2 的源码分析可以帮助我们更好地理解框架的内部机制和工作流程,掌握 Struts2 的源码可以让我们更好地使用这个框架来开发 Web 应用程序。
本文将深入探讨Struts2的源码分析,特别是关于StrutsPrepareAndExecuteFilter的初始化过程,这是Struts2的核心组件之一,负责处理HTTP请求。 首先,我们来看`StrutsPrepareAndExecuteFilter`的初始化。这个过滤器...
Struts2源码分析--请求处理.pdf
总的来说,Struts2的源码分析可以帮助开发者深入理解其内部机制,包括请求处理流程、拦截器的运作方式以及视图组件的实现。这有助于提高应用的可维护性,优化性能,并使开发者能够更好地定制和扩展框架。对于熟悉...
struts2源码详细解析51CTO下载-struts2源代码分析(个人觉得非常经典)
Struts2源码分析--请求处理[汇编].pdf
总的来说,Struts2的源码分析涉及Action的创建与执行、Interceptor的调用链、FilterDispatcher的请求调度以及Result的展示机制。通过对这些关键组件的深入理解和代码研究,开发者可以更好地掌握Struts2框架,提高...
本文将深入探讨Struts2的核心概念、类和请求处理流程。 首先,我们来看Struts2的架构流程。当客户端发起一个请求时,请求会经过一系列的Filter,首先是`ActionContextCleanUp`过滤器,它的主要任务是清理当前线程的...
在Struts2中,请求的处理流程涉及多个组件和步骤,确保了请求的正确路由、业务逻辑的执行以及响应的生成。以下是Struts2请求处理的详细分析: 1. **初始化请求**:客户端发起一个HTTP请求到Servlet容器,如Tomcat或...
总的来说,这篇“Struts2源码解读”的博文应该是对Struts2核心机制进行了详细的解析,包括Action、Interceptor、Result等关键组件的工作原理,以及整个请求处理流程。通过学习这些内容,开发者可以深化对Struts2的...
- **请求处理流程**:用户通过浏览器向服务器发送请求,服务器接收到请求后,Struts2框架负责解析请求参数,并根据配置文件找到对应的Action对象。 - **Action处理**:找到Action对象后,Struts2会调用Action对象的`...
2. **拦截器(Interceptors)**:Struts2的一个强大特点是使用拦截器来处理请求。拦截器链允许开发者在Action执行前后插入自定义的处理逻辑,如日志、权限检查、数据验证等。 3. **插件体系**:Struts2支持丰富的...
通过分析这个Struts2项目源码,你可以学习以下技能: 1. 如何创建Action类,并定义其方法与用户请求对应。 2. 理解配置文件`struts.xml`的结构和作用。 3. 掌握Action与视图的交互,了解结果类型的应用。 4. 学习...
在Struts 1.2.x中,请求处理流程是整个框架的核心部分,它涉及到了从用户发起请求到服务器响应的完整过程。下面将详细解释这个流程。 1. **请求开始**: 当用户通过浏览器向服务器发送HTTP请求时,请求通常会指向一...
1. **Action类**:在Struts 2中,Action类是处理用户请求的核心。开发者通常需要继承`org.apache.struts.action.Action`或`com.opensymphony.xwork2.ActionSupport`,并重写`execute()`方法来实现业务逻辑。 2. **...
1. **Action**:在Struts2中,Action类是业务逻辑处理的主要部分,它是请求处理的中心。Action类通常继承自`com.opensymphony.xwork2.ActionSupport`,并重写execute方法来执行特定的业务逻辑。 2. **Action ...
Struts2是一个基于MVC(Model...通过阅读这些关键类的源码,你可以理解Struts2内部的流程控制和数据传递,从而更好地利用这个框架。同时,学习源码还可以帮助你解决实际开发中遇到的问题,提升你的问题定位和调试能力。
`org.apache.struts2.dispatcher`包包含了Struts2的核心类,如Dispatcher,它是处理请求的关键组件。`org.apache.struts2.impl`包是对WebWork的扩展,提供了StrutsActionProxy、StrutsActionProxyFactory和...