在学习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 MapactionMappings=new HashMap (); 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或是
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 MapactionMappings=new HashMap (); public Map 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 packagesIterator=root.elements("package").iterator(); //从packagesIterator中取出第一个package Element firstPackageElement=packagesIterator.next(); if( firstPackageElement==null){ throw new RuntimeException("无配置"); } //从package中一个一个地区action子节点 for( Iterator 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 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; }}