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

  • 相关阅读:
    近期用过的Linux口令备份
    使用白鹭引擎遇到的一些问题以及一些工具分享
    隐私政策
    又是一年年终总结
    初次数据整理
    skynet的timer似乎有问题
    golang .(type)语法
    mysqlbinlog输出sql
    Mysql中文字符串提取datetime
    ionic4请求skynet服务器的资源跨域问题
  • 原文地址:https://www.cnblogs.com/aigeileshei/p/7295819.html
Copyright © 2011-2022 走看看