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的工作原理相关的介绍,顺便抄写过来,用来帮助自 ...
随机推荐
- WOT2016大数据技术峰会——千人技术盛宴
WOT2016大数据技术峰会是一场聚焦大数据领域最前沿的的技术及经验分享.2016年11月25-26日北京粤财JW万豪酒店如约而至,会议规模达到1000人! 由51CTO主办的千人技术盛宴--WOT2 ...
- POJ 2485 Highway(Prim+邻接矩阵)
( ̄▽ ̄)" //求最短总路径中的最大边长,Prim还需要一个Max变量 #include<iostream> #include<cstdio> #include&l ...
- hdu_5858_Hard problem(数学题)
题目链接:hdu_5858_Hard problem 题意: 让你求阴影部分面积 题解: 推推公式就行 #include<stdio.h> #include<math.h> # ...
- IOS 类似网易新闻客户端内容滚动菜单跟随居中组件
需求分析: 1.类似网易新闻客户端页面滚动组件.菜单栏对应菜单项一直居中 2.点击菜单栏可以切换到对应的page 3.滑动页面可以自动切换相应的菜单.并且对应的菜单栏居中显示 4.初始化时可以自定义菜 ...
- Delphi用ADOquery主从表例子(转总结)
http://blog.csdn.net/kandy_zheng/article/details/1639184 在sql server 的northwide 中建立主表 create table s ...
- digitalocean教程:你应该知道的10件事
DigitalOcean VPS性价比高,全球拥有多处机房,无须备案,非常适合守规矩的中国用户使用.digitalocean优惠码.digitalocean速度.digitalocean评测是网友关心 ...
- ural 1118. Nontrivial Numbers
1118. Nontrivial Numbers Time limit: 2.0 secondMemory limit: 64 MB Specialists of SKB Kontur have de ...
- docker私服
1.下载私服镜像docker pull registry 2.启动容器docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registr ...
- PHP实现中文截取无乱码
字符串的处理是编程中比较常见的,各种编程语言对字符串的处理也提供了大量函数,像php中mb_substr()函数可以实现对中文字符串的截取,如何使用自定义方法实现中文字符串截取无乱码这也是面试经常遇到 ...
- RPC简介与Thrift框架
RPC,全称是remote process call,远程过程调用,简单来讲就是调用部署在另一台服务器上的服务或者被部署在另一台服务器上的服务调用.由于各服务部署在不同机器,服务间的调用免不了网络通信 ...