struts可查看源码:https://github.com/apache/struts

在学习struts2之前,我先看了一些比较早版本对struts2的工作原理相关的介绍,顺便抄写过来,用来帮助自己要弄清这个框架的工作原理。

struts2.1.3之前使用的FilterDispatcher,之后的版本使用StrutsPrepareAndExecuteFilter,而我这里还是以Dispatcher为例来记录的。

依据:

Since Struts 2.1.3, use org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter instead or org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter and org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter if needing using the ActionContextCleanUp filter in addition to this one

To use a custom Dispatcher, the createDispatcher() method could be overriden by the subclass.
Version:$Date$ $Id$See Also:
ActionMapper
ActionContextCleanUp
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter
org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter

下图描述了Struts2的工作原理:

一个请求在Struts2框架中的处理大致分为一下几个步骤:

1、客户端初始化一个纸箱Servlet容器(比如:Tomcat)的请求。

2、这个请求经过一系列的过滤器(Filter)。

备注:这些过滤器中有个叫做ActionContextCleanUp的可选过滤器,它对Struts2和其他框架的集成很有帮助。

3、接着FilterDispatcher被调用,FilterDispatcher询问ActoinMapper来决定这个请求是否需要调用某个Action。FilterDispatcher是控制器的核心,也是MVC的中C控制层的核心。请查看:《摘抄别人对FilterDispatcher工作流程和原理的分析:FilterDispatcher进行初始化并启用核心doFilter》。

4、如果ActionMapper决定要调用某个Action,FilterDispatcher把请求的处理交给ActoinProxy。

5、ActionProxy通过Configuration Manager询问框架配置文件,找到需要调用的Action类,一般是从structs.xml配置中读取。

6、ActionProxy创建一个ActionInvocation的实例。

7、ActoinInvocation实例使用命名模式来调用,在调用Action前后,设计到相关拦截器(Intercepter)的调用。

8、一旦Action执行完毕,ActionInvocation负责根据Struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的Jsp或者FreeMarker的模板。在表示的过程中可以使用Struts2框架中继承的标签。在这个过程中需要设计到ActionMapper。

在以上过程中所有的对象(Action,Results,Interceptors等)都是通过ObjectFactory来创建的。

  • 下面我们来看看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执行前后运行。

这里,我们简单的介绍一下Interceptor

在struts2中自带了很多拦截器,在struts2-core-2.1.6.jar这个包下的struts-default.xml中我们可以发现:

 <interceptors>
<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="clearSession"class="org.apache.struts2.interceptor.ClearSessionInterceptor"/>
<interceptor name="createSession"class="org.apache.struts2.interceptor.CreateSessionInterceptor"/>
<interceptor name="debugging"class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor"/>
<interceptor name="externalRef"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="modelDriven"class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
<interceptor name="scopedModelDriven"class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
<interceptor name="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
<interceptor name="actionMappingParams"class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
<interceptor name="prepare"class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
<interceptor name="staticParams"class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
<interceptor name="scope"class="org.apache.struts2.interceptor.ScopeInterceptor"/>
<interceptor name="servletConfig"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="tokenSession"class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
<interceptor name="validation"class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
<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"/>
<interceptor name="roles"class="org.apache.struts2.interceptor.RolesInterceptor"/>
<interceptor name="jsonValidation"class="org.apache.struts2.interceptor.validation.JSONValidationInterceptor"/>
<interceptorname="annotationWorkflow"class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor"/>

对于sturts2自带的拦截器,使用起来就相对比较方便了,我们只需要在struts.xml的action标签中加入<interceptor-ref name=" logger " />并且struts.xml扩展struts-default,就可以使用,

如果是要自定义拦截器,首先需要写一个拦截器的类:

 package ceshi;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; publicclassAuthorizationInterceptor extends AbstractInterceptor { @Override
public Stringintercept(ActionInvocation ai)throws Exception { System.out.println("abc");
return ai.invoke(); } }

并且在struts.xml中进行配置

 <!DOCTYPEstruts PUBLIC
"-//Apache SoftwareFoundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"> <struts>
<package name="test"extends="struts-default">
<interceptors>
<interceptor name="abc"class ="ceshi.AuthorizationInterceptor"/>
</interceptors>
<action name="TestLogger"class="vaannila.TestLoggerAction">
<interceptor-refname="abc"/>
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
  • 摘抄别人对FilterDispatcher工作流程和原理的分析:FilterDispatcher进行初始化并启用核心doFilter
 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);
}
}
  • FilterDispatcher作用

Master filter for Struts that handles four distinct responsibilities: 
•Executing actions
•Cleaning up the ActionContext (see note)
•Serving static content
•Kicking off XWork's interceptor chain for the request lifecycle

IMPORTANT: this filter must be mapped to all requests. Unless you know exactly what you are doing, always map to this URL pattern: /*

Executing actions 
This filter executes actions by consulting the ActionMapper and determining if the requested URL should invoke an action. If the mapper indicates it should, the rest of the filter chain is stopped and the action is invoked. This is important, as it means that filters like the SiteMesh filter must be placed before this filter or they will not be able to decorate the output of actions.

Cleaning up the ActionContext 
This filter will also automatically clean up the ActionContext for you, ensuring that no memory leaks take place. However, this can sometimes cause problems integrating with other products like SiteMesh. See ActionContextCleanUp for more information on how to deal with this.

Serving static content 
This filter also serves common static content needed when using various parts of Struts, such as JavaScript files, CSS files, etc. It works by looking for requests to /struts/*, and then mapping the value after "/struts/" to common packages in Struts and, optionally, in your class path. By default, the following packages are automatically searched: 
•org.apache.struts2.static
•template

This means that you can simply request /struts/xhtml/styles.css and the XHTML UI theme's default stylesheet will be returned. Likewise, many of the AJAX UI components require various JavaScript files, which are found in the org.apache.struts2.static package. If you wish to add additional packages to be searched, you can add a comma separated (space, tab and new line will do as well) list in the filter init parameter named "packages". Be careful, however, to expose any packages that may have sensitive information, such as properties file with database access credentials.

This filter supports the following init-params: 
•config - a comma-delimited list of XML configuration files to load.
•actionPackages - a comma-delimited list of Java packages to scan for Actions.
•configProviders - a comma-delimited list of Java classes that implement the ConfigurationProvider interface that should be used for building the Configuration.
•loggerFactory - The class name of the LoggerFactory implementation.
•* - any other parameters are treated as framework constants.

参考:http://blog.csdn.net/laner0515/article/details/27692673/

Struts2(二):工作原理的更多相关文章

  1. Struts2(二)工作原理

    一.概述 1.struts框架本身分为三个部分:核心控制器FilterDispatcher.业务控制器Action和用户实现的企业业务逻辑组件. 2.struts2工作的基本流程: 客户端初始化一个指 ...

  2. Struts2的工作原理及工作流程

    众所周知,Struts2是个非常优秀的开源框架,我们能用Struts2框架进行开发,同时能 快速搭建好一个Struts2框架,但我们是否能把Struts2框架的工作原理用语言表达清楚,你表达的原理不需 ...

  3. 菜鸟学Struts2——Struts工作原理

    在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中 ...

  4. Struts2的工作原理(图解)详解

    Struts2的工作原理 上图来源于Struts2官方站点,是Struts 2 的整体结构. 一个请求在Struts2框架中的处理大概分为以下几个步骤(可查看源码:https://github.com ...

  5. Struts2 的工作原理

    Struts2 的工作原理: 1)client向server发出一个http请求.webserver对请求进行解析,假设在StrutsPrepareAndExecuteFilter的请求映射路径(在w ...

  6. struts2的工作原理

    在学习struts2就必须的了解一下它的工作原理: 首先来看一下这张图 这张工作原理图是官方提供的: 一个请求在Struts2框架中的处理大概分为以下几个步骤 1.客户端初始化一个指向Servlet容 ...

  7. 第一篇——Struts2的工作原理及HelloWorld简单实现

    Struts2工作原理: 一个请求在Struts框架中的处理步骤: 1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求: 2.这个请求经过一系列的过滤器(Filter): 3.接着F ...

  8. Struts2学习一----------Struts2的工作原理及HelloWorld简单实现

    © 版权声明:本文为博主原创文章,转载请注明出处 Struts2工作原理 一个请求在Struts2框架中的处理步骤: 1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求 2.这个请求 ...

  9. HDSF主要节点解说(二)工作原理

    HDFS(Hadoop Distributed File System )Hadoop分布式文件系统. 是依据google发表的论文翻版的.论文为GFS(Google File System)Goog ...

  10. 分享知识-快乐自己:Struts2框架 工作原理及执行流程图(拦截器的使用)

    Struts2 架构图: 1):提交请求 客户端通过 HttpServletRequest 向 Servlet (即Tomcat)提交一个请求. 请求经过一系列的过滤器,例如图中的 ActionCon ...

随机推荐

  1. 【BZOJ3224】Tyvj 1728 普通平衡树 Splay

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...

  2. 20145330第五周《Java学习笔记》

    20145330第五周<Java学习笔记> 这一周又是紧张的一周. 语法与继承架构 Java中所有错误都会打包为对象可以尝试try.catch代表错误的对象后做一些处理. 使用try.ca ...

  3. DockerFile 参数详解

    Docker 指令: From --- ENV ---设置环境变量ENV App_DIR /appp Add 和 Copy 可以复制文件到容器里面 .区别 Add 可以写网络的链接地址 Add 支持解 ...

  4. CentOS转的服务器磁盘规划

    我的服务器是500G.最重要的是/var分区一定要大(不论postfix邮件,还是LAMP的WEB 服务器等).最好是400G以上.具体的/boot 只要100M就足够了.下面是我的分区方案:硬盘50 ...

  5. Curl参数一览

    * 目录 1. 介绍 2. curl扩展的安装 3. curl_init 4. curl_setopt 5. curl_exec 6. curl_close 7. curl_version * 介绍 ...

  6. Java面向对象编程

    面向对象的软件开发: 面向对象的开发把软件系统看成各种对象的集合,对象就是最小的子系统,一组相关的对象能够组合成复杂的子系统. 面向对象的开发方法具有以下优点: 1.把软件系统看成是各种对象的集合,更 ...

  7. sbt commands

    速查手册 常用命令 actions – 显示对当前工程可用的命令 update – 下载依赖 compile – 编译代码 test – 运行测试代码 package – 创建一个可发布的jar包 p ...

  8. Jquery的优势

    (1)轻量级.jQuery非常轻巧,采用Dean Edwards的Packer(http://dean.edwards.name/packer/)压缩后,只有不到30KB的大小,如果服务器端启用gzi ...

  9. Ajax请求中的Redirect()

    页面中有一个IsLogin()方法,用以判断该请求的触发者是否登录,如果登录了,则执行查询操作,如果没有登录,则Redirect()至登录界面 页面使用了较多的Ajax请求来获取数据,而在Ajax请求 ...

  10. c#面向对象基础 类、方法、方法重载

    C#是纯粹的面向对象编程语言,它真正体现了“一切皆为对象”的精神.在C#中,即使是最基本的数据类型,如int,double,bool类型,都属于System.Object(Object为所有类型的基类 ...