zoukankan      html  css  js  c++  java
  • 传智:自己简单实现一个struts2框架的demo

    struts2的结构图:

     代码实现:

    组织结构:

    主要代码:

    package cn.itcast.config;
    
    import org.apache.log4j.Logger;
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * Created by zhen on 2017-08-04.
     * 读取struts.xml配置信息
     */
    public class ConfigurationManager {
        private static final Logger logger = Logger.getLogger(ConfigurationManager.class);
    
        //读取Interceptor
        public static List<String> getInterceptors(){
            List<String> interceptors = null;
            SAXReader saxReader = new SAXReader();
            InputStream inputStream = ConfigurationManager.class.getResourceAsStream("/struts.xml");
            Document document = null;
            try {
                document = saxReader.read(inputStream);
            } catch (DocumentException e) {
                logger.error(e.getMessage());
                throw new RuntimeException("配置文件解析异常" ,e);
            }
            String xpath = "//interceptor";
            List<Element> list = document.selectNodes(xpath);
            if(list != null && list.size() > 0){
                interceptors = new ArrayList<String>();
                for(Element ele: list){
                    String className = ele.attributeValue("class");
                    interceptors.add(className);
                }
            }
            return interceptors;
        }
    
        //读取Constant
        public static String getConstant(String name){
            String value = null;
            SAXReader saxReader = new SAXReader();
            InputStream is = ConfigurationManager.class.getResourceAsStream("/struts.xml");
            Document document = null;
            try {
                document = saxReader.read(is);
            } catch (DocumentException e) {
                logger.error(e.getMessage());
                throw new RuntimeException("配置文件解析异常" ,e);
            }
            String xPath = "//constant[@name='" + name + "']";
            List<Element> ele = document.selectNodes(xPath);
            if(ele != null && ele.size() > 0){
                value = ele.get(0).attributeValue("value");
            }
            return value;
        }
    
        //读取Action
        public static Map<String, ActionConfig> getActions(){
            Map<String, ActionConfig> actions = null;
            SAXReader saxReader = new SAXReader();
            InputStream is = ConfigurationManager.class.getResourceAsStream("/struts.xml");
            Document document = null;
            try {
                document = saxReader.read(is);
            } catch (DocumentException e) {
                logger.error(e.getMessage());
                throw new RuntimeException("配置文件解析异常" ,e);
            }
            String xPath = "//action";
            List<Element> list = document.selectNodes(xPath);
            if(list != null && list.size() > 0){
                actions = new HashMap<String, ActionConfig>();
                for(Element element : list){
                    ActionConfig actionConfig = new ActionConfig();
                    String name = element.attributeValue("name");
                    String method = element.attributeValue("method");
                    String className = element.attributeValue("class");
                    Map<String, String> results = null;
                    List<Element> resultElements = element.elements("result");
                    if(resultElements != null && resultElements.size() > 0){
                        results = new HashMap();
                        for(Element ele: resultElements){
                            String resultName = ele.attributeValue("name");
                            String resultValue = ele.getTextTrim();
                            results.put(resultName, resultValue);
                        }
                    }
                    actionConfig.setName(name);
                    actionConfig.setMethod(method == null || method.trim().equals("") ? "execute" : method.trim());
                    actionConfig.setClassName(className);
                    actionConfig.setResults(results);
                    actions.put(name, actionConfig);
                }
            }
            return actions;
        }
    
    
    
    
    }
    package cn.itcast.invocation;
    
    import cn.itcast.config.ActionConfig;
    import cn.itcast.context.ActionContext;
    import cn.itcast.interceptor.Interceptor;
    import org.apache.log4j.Logger;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    /**
     * Created by zhen on 2017-08-06.
     */
    public class ActionInvocation {
        private static final Logger logger = Logger.getLogger(ActionInvocation.class);
        private Iterator<Interceptor> interceptors;
        private Object action;
        private ActionConfig actionConfig;
        private ActionContext actionContext;
        private String resultUrl;
    
        public ActionContext getActionContext() {
            return actionContext;
        }
    
    
        public ActionInvocation(List<String> classNames, ActionConfig actionConfig, HttpServletRequest request, HttpServletResponse response){
            //装载Interceptor链
            if(classNames != null && classNames.size() > 0){
                List<Interceptor> interceptorList = new ArrayList<Interceptor>();
                for(String className : classNames){
                    try {
                        Interceptor interceptor = (Interceptor) Class.forName(className).newInstance();
                        interceptor.init();
                        interceptorList.add(interceptor);
                    } catch (Exception e) {
                        logger.error(e.getMessage());
                        throw new RuntimeException("创建Interceptor失败,Interceptor Name:" + className ,e);
                    }
                }
                interceptors =  interceptorList.iterator();
            }
    
            //准备action实例
            this.actionConfig = actionConfig;
            try {
                action = Class.forName(actionConfig.getClassName()).newInstance();
            } catch (Exception e) {
                logger.error(e.getMessage());
                throw new RuntimeException("创建Action实例失败!" + actionConfig.getClass(), e);
            }
    
            //准备数据中心
            actionContext = new ActionContext(request, response, action);
        }
    
        public String invoke(){
           if(interceptors != null && interceptors.hasNext() && resultUrl == null){
               Interceptor interceptor = interceptors.next();
               resultUrl = interceptor.invoke(this);
           }else{
               try{
                   Method executeMethod = Class.forName(actionConfig.getClassName()).getMethod(actionConfig.getMethod());
                   resultUrl = (String) executeMethod.invoke(action);
               }catch(Exception ex){
                   logger.error(ex.getMessage());
                   throw new RuntimeException("您配置的action方法不存在" + actionConfig.getClassName());
               }
           }
           return resultUrl;
        }
    }
    package cn.itcast.filter;
    
    import cn.itcast.config.ActionConfig;
    import cn.itcast.config.ConfigurationManager;
    import cn.itcast.context.ActionContext;
    import cn.itcast.invocation.ActionInvocation;
    import org.apache.log4j.Logger;
    import org.junit.Test;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.List;
    import java.util.Map;
    
    /**
     * Created by zhen on 2017-08-06.
     */
    public class StrutsPrepareAndExecuteFilter implements Filter {
        private static final Logger logger = Logger.getLogger(StrutsPrepareAndExecuteFilter.class);
        private List<String> interceptorClassNames;
        private  String extension;
        private Map<String, ActionConfig> actionConfigs;
    
        public void init(FilterConfig filterConfig) throws ServletException {
            //装载配置信息
            interceptorClassNames = ConfigurationManager.getInterceptors();
            extension = ConfigurationManager.getConstant("struts.action.extension");
            actionConfigs = ConfigurationManager.getActions();
        }
    
        public static void main(String[] args){
            Logger logger = Logger.getLogger(StrutsPrepareAndExecuteFilter.class);
        }
    
    
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            //执行
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
    
            String urlPath = request.getRequestURI();
            if(!urlPath.endsWith(extension)){
                filterChain.doFilter(request, response);
                return;
            }
            String actionName = urlPath.substring(urlPath.lastIndexOf("/") + 1).replace("." + extension, "");
            ActionConfig actionConfig = actionConfigs.get(actionName);
            if(actionConfig == null){
                throw new RuntimeException("找不到对应的action!" + actionName);
            }
            ActionInvocation actionInvocation = new ActionInvocation(interceptorClassNames, actionConfig, request, response);
            String result = actionInvocation.invoke();
            String dispatcherPath = actionConfig.getResults().get(result);
            if(dispatcherPath == null || "".equals(dispatcherPath)){
                throw new RuntimeException("找不到对应的返回路径!");
            }
            request.getRequestDispatcher(dispatcherPath).forward(request, response);
            ActionContext.tl.remove();
        }
    
        public void destroy() {
    
        }
    }

    写后感想:

    struts2模拟
    
    1、关注点分离思想。类似java中的解耦合,插拔。将功能拆分成各个拦截器实现。拦截器运行过程中拼接出想要的功能。
    2、MVC思想。 filter-C Action-M jsp_url-V
    
    需要掌握知识:
        XML解析,Xpath表达式(dom4j)
        Servlet技术
        java内省(BeanUtils)
        ThreadLocal线程本地化类
        递归调用
        
    需要补充的知识:
        dom4j解析
        xpath语法
        获取资源文件路径
        
    理解:
        对于值栈的模拟不要拘泥于数组,也可以使用现有的类进行封装,比如使用ArrayList模拟。
        经常递归调用使用的局部变量可以放在循环外或者说是方法外。

    项目路径:

    https://github.com/gzdx/MyStruts2.git

  • 相关阅读:
    Spring boot unable to determine jdbc url from datasouce
    Unable to create initial connections of pool. spring boot mysql
    spring boot MySQL Public Key Retrieval is not allowed
    spring boot no identifier specified for entity
    Establishing SSL connection without server's identity verification is not recommended
    eclipse unable to start within 45 seconds
    Oracle 数据库,远程访问 ora-12541:TNS:无监听程序
    macOS 下安装tomcat
    在macOS 上添加 JAVA_HOME 环境变量
    Maven2: Missing artifact but jars are in place
  • 原文地址:https://www.cnblogs.com/aigeileshei/p/7295819.html
Copyright © 2011-2022 走看看