在学习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; } }