zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    BZOJ 4815: [Cqoi2017]小Q的表格
    BZOJ 3676: [Apio2014]回文串
    BZOJ 4503: 两个串
    BZOJ 2618: [Cqoi2006]凸多边形
    BZOJ 1137: [POI2009]Wsp 岛屿
    BZOJ 4824: [Cqoi2017]老C的键盘
    BZOJ 3167: [Heoi2013]Sao
    BZOJ 4033: [HAOI2015]树上染色
    1003. 我要通过!(20)
    1002. 写出这个数 (20)
  • 原文地址:https://www.cnblogs.com/yaobolove/p/5231099.html
Copyright © 2011-2022 走看看