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的工作原理相关的介绍,顺便抄写过来,用来帮助自 ...
随机推荐
- MySQL字符串类型
VARCHAR类型用于存储变长字符串,它会删除末尾的所有空格,它比定长字符串更省空间,因为它仅使用必要的空间(越短的字符串占用越少),VARCHAR会用1或2个额外字节记录字符串长度(如果字符串长度不 ...
- Xshell4连接,Linux系统中文显示乱码解决办法
Xshell 是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET NetSarang Xshell 4 Build 0120议.使用 ...
- swift中JSon数据的处理
import UIKit class MainTabBarViewController: UITabBarController { override func viewDidLoad() { supe ...
- maven入门(上)
Apache Maven 入门篇 ( 上 ) 作者:George Ma 写这个 maven 的入门篇是因为之前在一个开发者会的动手实验中发现挺多人对于 maven 不是那么了解,所以就有了这个想法.这 ...
- HttpServletRequest对象(一)
一:HttpServletRequest介绍: 代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中, 二:Request常用的方法 1):获得客户端信 ...
- 安装jar包到本地maven仓库
1.打开cmd 直接输入一下命令 自己下载的jar包放在d盘根目录下,jar名字叫spring-context-support-3.1.0.RELEASE.jar DgroupId后面写的是group ...
- linux命令英文缩写的含义(方便记忆)
命令缩写: ls:list(列出目录内容) cd:Change Directory(改变目录) su:switch user 切换用户 rpm:redhat package manager 红帽子打包 ...
- NYOJ-71 独木舟上的旅行 (贪心)
独木舟上的旅行 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 进行一次独木舟的旅行活动,独木舟可以在港口租到,并且之间没有区别.一条独木舟最多只能乘坐两个人,且乘客 ...
- 生成SQL脚本的方法
2点需要注意的关键: (1)选择特定数据库对象不包含用户选项: (2)要编写脚本的数据的类型选择"架构和数据".
- drupal7 上传文件中文乱码
drupal7自带有file模块,可以上传文件. 但是存在问题:如果上传的文件名称是中文,存储在文件下面的文件名称是乱码的,解决办法如下:参考出处 includes/file.inc中,修改两处代码, ...