在学习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的工作原理的更多相关文章

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

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

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

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

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

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

  4. Struts2 的工作原理

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

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

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

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

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

  7. Struts2(二)工作原理

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

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

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

  9. Struts2(二):工作原理

    struts可查看源码:https://github.com/apache/struts 在学习struts2之前,我先看了一些比较早版本对struts2的工作原理相关的介绍,顺便抄写过来,用来帮助自 ...

随机推荐

  1. js-json教程从入门到使用

    json教程从入门到使用 2.json例子: var today_data={"city":"上海","area":"6400&q ...

  2. spring security 1

    首先我们为Spring Security专门建立一个Spring的配置文件,该文件就专门用来作为Spring Security的配置.使用Spring Security我们需要引入Spring Sec ...

  3. CSS3背景颜色渐变效果

    1.firefox浏览器: background-image: -moz-linear-gradient(top , #eef9fe, #d1ecff); 2.safari.chrome浏览器: ba ...

  4. YII学习第二十三天,accessRules用法

    访问控制过滤器(Access Control Filter)访问控制过滤器是检查当前用户是否能执行访问的controller action的初步授权模式. 这种授权模式基于用户名,客户IP地址和访问类 ...

  5. jquey(判断文本框输入的网址链接是否符合规则)

    今天遇到一个问题,我要在文本框中输入一个网址链接,使其跳转.但是如何验证,我首先想到了正则表达式.对的,就是你想的那样,我对正则一知半解,但在我哥哥帮助下,最终是 实现 了效果.在此,来一发,分享一下 ...

  6. Android 安装镜像

    1. 关机 2. 按住音量减键和电源键,直到进入fastboot模式 3. 连接上PC 4. PC端输入sudo fastboot devices验证已识别到设备 5. PC端输入sudo fastb ...

  7. delphi 容错提示语句汇总

    打开文件失败的容错提示语句 try if OpenDialog1.Execute then begin MyList.Clear; MyList.LoadFromFile(OpenDialog1.Fi ...

  8. 不完善的css怦然心动,有待改进...

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  9. 关于 JAVA 中使用 Preferences 读写注册表时要注意的地方

    要注意的只有一个地方,那就是键名或者项名不要包含大写字母,否则读不到数据. 代码是这样的: 1: Preferences preferences = Preferences.systemRoot(); ...

  10. JavaScript获取浏览器信息的方法

    Window有navigator对象让我们得知浏览器的全部信息.我们可以利用一系列的API函数得知浏览器的信息. JavaScript代码如下: ? 1 2 3 4 5 6 7 8 9 10 11 1 ...