struts2的工作原理
在学习struts2就必须的了解一下它的工作原理:
首先来看一下这张图
这张工作原理图是官方提供的:
一个请求在Struts2框架中的处理大概分为以下几个步骤
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3、接着StrutsPrepareAndExecuteFilter(在struts2.1中就不用FilterDispatcher)被调用,StrutsPrepareAndExecuteFilter询问ActionMapper来决定这个请是否需要调用某个Action
4、如果ActionMapper决定需要调用某个Action,StrutsPrepareAndExecuteFilter把请求的处理交给ActionProxy
5、ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类 ,这里,我们一般是从struts.xml配置中读取。
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
在调用拦截器的时候是采取回掉模式;
StrutsPrepareAndExecuteFilter是控制器的核心,就是mvc中c控制层的核心。下面粗略的分析下我理解的StrutsPrepareAndExecuteFilter工作流程和原理:StrutsPrepareAndExecuteFilter进行初始化并启用核心doFilter
package com.yc.ycstruts2.web.filter; import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.dom4j.DocumentException; import com.yc.ycstruts2.core.Action;
import com.yc.ycstruts2.core.ActionMapping;
import com.yc.ycstruts2.core.ActionMappingMannager;
import com.yc.ycstruts2.core.ResultMapping;
import com.yc.ycstruts2.core.UriWrapper;
import com.yc.ycstruts2.core.UriWrapper.UriMapping; public class StrutsPrepareAndExecuteFilter implements Filter {
private Map<String,ActionMapping> actionMappings=new HashMap<String,ActionMapping>(); public void destroy() { } public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain chain) throws IOException, ServletException {
//1 取出request对象
HttpServletRequest request=(HttpServletRequest) arg0;
//2 从request中取出uri GET/xxx?xxx HTTP/1.1
String uri=request.getRequestURI();
//3 解析uri(字符串的解析,最好用正则表达式)=》存在一个数据构成
UriWrapper uriWrapper=new UriWrapper();
UriMapping uriWrapping=uriWrapper.parse(uri);
//4 从actionMappings中取出对应的action
ActionMapping actionMapping=actionMappings.get(UriMapping.actionName);
//5 如果不存在这个action ,则chain.doFilter()
try {
if( actionMapping==null){
chain.doFilter(arg0,arg1);
}else{
//6 存在=》反射创建这个action(多例的实现)
String result="";
String classInfo=actionMapping.getClassInfo();
Object actionInstance=Class.forName(classInfo).newInstance();
//7调用excute或是<action method="" 指定的方法
if( actionMapping.getMethod()==null || "".equals(actionMapping.getMethod())){
if( actionInstance instanceof Action){ //查找你要的execute方法
Method execute=actionInstance.getClass().getMethod("execute", null);
result=(String)execute.invoke(actionInstance,null);
}
}else{
//查找你要的execute方法
String methodName=actionMapping.getMethod();
Method execute=actionInstance.getClass().getMethod("execute", null);
result=(String)execute.invoke(actionInstance,null);
}
//8 上面的execute或method的方法调用后,会返回一个String
ResultMapping resultMapping=actionMapping.getResultMappings().get(result);
if( resultMapping.getType()==null|| resultMapping.getType().equals("")|| resultMapping.getType().equals("dispatcher")){
request.getRequestDispatcher(resultMapping.getUri()).forward(arg0,arg1);
}else if( resultMapping.getType().equals("redirect")){
((HttpServletResponse)arg1).sendRedirect( resultMapping.getUri());
} }
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void init(FilterConfig arg0) throws ServletException { ActionMappingMannager amm=new ActionMappingMannager();
try {
actionMappings=amm.parse();
} catch (DocumentException e) {
e.printStackTrace();
} } }
package com.yc.ycstruts2.core; import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map; import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; //
public class ActionMappingMannager {
private Map<String,ActionMapping> actionMappings=new HashMap<String,ActionMapping>(); public Map<String,ActionMapping> parse() throws DocumentException{
//解析struts.xml
InputStream iis=ActionMappingMannager.class.getClassLoader().getResourceAsStream("struts.xml");
System.out.println(iis);
Document doc=new SAXReader().read(iis);
//取根节点
Element root=doc.getRootElement();
Iterator<Element> packagesIterator=root.elements("package").iterator();
//从packagesIterator中取出第一个package
Element firstPackageElement=packagesIterator.next();
if( firstPackageElement==null){
throw new RuntimeException("无配置");
}
//从package中一个一个地区action子节点
for( Iterator<Element> actionsIterator=firstPackageElement.elements("action").iterator(); actionsIterator.hasNext();){
Element actionElement=actionsIterator.next();
//创建actionMapping
ActionMapping actionMapping=new ActionMapping();
String actionName=actionElement.attributeValue("name");
actionMapping.setName(actionName);
actionMapping.setClassInfo( actionElement.attributeValue("class"));
actionMapping.setMethod(actionElement.attributeValue("method"));
//对应的resultMappings
for(Iterator<Element>resultIterator=actionElement.elements("result").iterator(); resultIterator.hasNext();){
Element resultElement=resultIterator.next();
//创建resultMapping对象
ResultMapping resultMapping=new ResultMapping();
String name=resultElement.attributeValue("name");
if( null==name || "".equals(name)){
resultMapping.setName("success");
}else{
resultMapping.setName(name);
}
String type=resultElement.attributeValue("type");
if(null==type || "".equals(type)){
resultMapping.setType("dispatcher");
}else{
resultMapping.setType(type);
}
//取出url
resultMapping.setUri(resultElement.getTextTrim()); //将resultMapping存到actionMapping中
actionMapping.addResutMapping(name,resultMapping); } actionMappings.put(actionName,actionMapping);
}
//取出result
return actionMappings; } }
struts2的工作原理的更多相关文章
- 菜鸟学Struts2——Struts工作原理
在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中 ...
- Struts2的工作原理及工作流程
众所周知,Struts2是个非常优秀的开源框架,我们能用Struts2框架进行开发,同时能 快速搭建好一个Struts2框架,但我们是否能把Struts2框架的工作原理用语言表达清楚,你表达的原理不需 ...
- Struts2的工作原理(图解)详解
Struts2的工作原理 上图来源于Struts2官方站点,是Struts 2 的整体结构. 一个请求在Struts2框架中的处理大概分为以下几个步骤(可查看源码:https://github.com ...
- Struts2 的工作原理
Struts2 的工作原理: 1)client向server发出一个http请求.webserver对请求进行解析,假设在StrutsPrepareAndExecuteFilter的请求映射路径(在w ...
- 第一篇——Struts2的工作原理及HelloWorld简单实现
Struts2工作原理: 一个请求在Struts框架中的处理步骤: 1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求: 2.这个请求经过一系列的过滤器(Filter): 3.接着F ...
- Struts2学习一----------Struts2的工作原理及HelloWorld简单实现
© 版权声明:本文为博主原创文章,转载请注明出处 Struts2工作原理 一个请求在Struts2框架中的处理步骤: 1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求 2.这个请求 ...
- Struts2(二)工作原理
一.概述 1.struts框架本身分为三个部分:核心控制器FilterDispatcher.业务控制器Action和用户实现的企业业务逻辑组件. 2.struts2工作的基本流程: 客户端初始化一个指 ...
- 分享知识-快乐自己:Struts2框架 工作原理及执行流程图(拦截器的使用)
Struts2 架构图: 1):提交请求 客户端通过 HttpServletRequest 向 Servlet (即Tomcat)提交一个请求. 请求经过一系列的过滤器,例如图中的 ActionCon ...
- Struts2(二):工作原理
struts可查看源码:https://github.com/apache/struts 在学习struts2之前,我先看了一些比较早版本对struts2的工作原理相关的介绍,顺便抄写过来,用来帮助自 ...
随机推荐
- 2016年团体程序设计天梯赛-决赛 L2-3. 互评成绩(25)
学生互评作业的简单规则是这样定的:每个人的作业会被k个同学评审,得到k个成绩.系统需要去掉一个最高分和一个最低分,将剩下的分数取平均,就得到这个学生的最后成绩.本题就要求你编写这个互评系统的算分模块. ...
- 【Sort】Merge Sort归并排序
归并排序运行时间O(N log N),但是由于需要线性附加内存,所以很少用于主存排序. 算法核心在于以下三条语句,分治递归,分别对左半边和右半边的数组进行排序,然后把左右半边的数组一一进行比较放入数组 ...
- nginx在linux下的目录结构
配置文件目录 putty 下 whereis nginx /etc/nginx
- 最短路径Shortest Path algorithm
最短路径问题: 如果从图中某一顶点(称为端点)到达另一顶点(称为终点)的路径可能不止一条,如何找到一条路径使得沿此路径上各边上的权值总和达到最小. (1)Dijkstra 算法 (2) Floyd 算 ...
- POJ 2039 To and Fro
To and Fro Description Mo and Larry have devised a way of encrypting messages. They first decide sec ...
- storm的并发机制
storm的并发机制 storm计算支持在多台机器上水平扩容,通过将计算切分为多个独立的tasks在集群上并发执行来实现. 一个task可以简单地理解:在集群某节点上运行的一个spout或者bolt实 ...
- hdu 1028 Ignatius and the Princess III(母函数入门+模板)
Description "Well, it seems the first problem is too easy. I will let you know how foolish you ...
- CSS,height:auto和height:100%有什么区别?
auto是随内容的高度而撑开的.100%是根据父级元素的高度来决定的.例如:<div style="height:100px;width:200px;"> <di ...
- PHP 流程
登录页面 <body> <form action="loginchuli.php" method="post"> <div> ...
- 3. 编写Java应用程序,定义Animal类,此类中有动物的属性:名称 name,腿的数量legs,统计动物的数量 count;方法:设置动物腿数量的方法 void setLegs(),获得腿数量的方法 getLegs(),设置动物名称的方法 setKind(),获得动物名称的方法 getKind(),获得动物数量的方法 getCount()。定义Fish类,是Animal类的子类,统计鱼的数量
//Animal 类 package d922B; public class Animal { private String kind; private int legs,count; public ...