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的工作原理相关的介绍,顺便抄写过来,用来帮助自 ... 
随机推荐
- html历史
			方法一: location.hash = 'abc' window.onhashchange = function(){} location.hash 返回结果 #abc => locati ... 
- [妙味JS基础]第一课:属性操作、图片切换、短信发送模拟
			知识点总结 HTML的属性操作:读.写 元素.属性名 => “读” 元素.属性名=新的值 => “写” 例如: oBtn.value => “读” oBtn.value='按钮' = ... 
- Eclipse版本区别
			各版本的区别: Eclipse IDE for Java Developers 是Eclipse的platform加上JDT插件,用来java开发的 Eclipse IDE for Java EE D ... 
- display: inline-block兼容性写法
			display:inline-block;*display:inline;*zoom:1; 
- luci-bwc(记录流量功能)
			使用方法如下: root@openwrt:/# luci-bwcUsage: luci-bwc [-t timeout] -i ifname // ifname为 ... 
- P2P直连?经服务器中转?
			当同一个系统的两个客户端A.B相互发送消息给对方时,如果它们之间存在P2P通道,那么消息传送的路径就有两种:直接经P2P通道传送.或者经服务器中转.如下图所示: 通常就一般应用而言,如果P2P通道能够 ... 
- 【笔记】Loadrunner添加OS类型为Windows的服务器(Win7)
			最近在学习Loadrunner,看到“监控Windows资源”,决定小试一把,由于没有找到合适的镜像,暂时没有搞好Windows的虚拟机,so 先用自己小试牛刀了只有,不过这样子好像难度锐减也~只要小 ... 
- 一个简单的servlet小程序
			servlet是不能单独运行的,他是运行在web服务器或应用服务器上的java程序,或者可以说是在servlet容器上运行的,我们经常使用到的tomcat就是一个servlet容器. 他是处理HTTP ... 
- ural 1353. Milliard Vasya's Function(背包/递归深搜)
			1353. Milliard Vasya's Function Time limit: 1.0 second Memory limit: 64 MB Vasya is the beginning ma ... 
- 将json文件转换为字符串
			//从给定位置读取Json文件 public String readJson(String path){ //从给定位置获取文件 File file = new ... 
