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();
        }
        
    }

    
}
View Code
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;
        
    
        
    }

}
View Code

 

posted @ 2016-03-01 15:06  Animationer  阅读(1107)  评论(0编辑  收藏  举报