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);//读取Interceptorpublic 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;}//读取Constantpublic 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;}//读取Actionpublic 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

传智:自己简单实现一个struts2框架的demo相关推荐

  1. 08_传智播客iOS视频教程_Foundation框架

    比如产生随机数.这个功能要你写吗?不用,因为苹果已经写好了.后面想开发一个ios程序,往界面上放一个按钮,实际上这个按钮不用你写别人已经写好了,你就拿过来拖一下就可以了. 框架是1个功能集 苹果或者第 ...

  2. 传智播客PHP笔记05-thinkphp框架-视图渲染、display,fetch,模板替换,模板变量的赋值与实现,系统变量,模板函数,模板运算符,foreach,if,比较标签,volist标签

    1.视图概述 将具体的视图模板进行输出显示,有两个方法 display:获取具体要输出的内容,然后直接输出 fetch:获取具体要输出的内容,但不会自动输出 2.display的使用(输出模板内容) ...

  3. 传智黑马Java → 16集合的框架

  4. struts2框架单文件、多文件上传实例详解

    版权声明:本文为博主原创文章,如需转载,请标明出处. https://blog.csdn.net/alan_liuyue/article/details/79390681 简介 1.上一篇博客讲解了J ...

  5. java struts2 框架 入门简介

    目录 一.Struts2框架执行流程 二.Struts2的快速入门 1.导入jar包 2.配置web.xml文件 3.配置struts.xml文件 4.创建Action来完成逻辑操作 三.Struts ...

  6. java struts2国际化代码下载_【Java框架】java struts2框架中页面表示国际化的方法 - 思诚科技...

    在struts2框架中,前端页面表示国际化的实现更加简单.简单的应用struts2框架提供的支持国际化的表达式即可快速方便的进行页面的国际化的实现.如何做呢?本文以英文和中文为例进行说明. 1,自定义 ...

  7. 传智播客还收费 兄弟会都是免费的

    [传智播客还收费 兄弟会都是免费的 兄弟连兄弟会it开发培训 www.itxdh.net 企鹅群:499956522 高端人才培养就到[兄弟连兄弟会it开发培训]纯免费的高端IT人才培养] 传智播客, ...

  8. 给传智播客的一份感谢信

    我是一名从传智播客培训机构出来的学员,这是我写给咱们传智播客学校的一份感谢信.感谢传智播客对我的栽培,让我的人生从此改变,得到一个新的世界,让我有了一对能够飞翔的翅膀. 我不是一名大学生,我是一个你们 ...

  9. 传智播客对大学的期许

    现在是9月初,一年一度的开学季拉开帷幕.在最近的一段时间,将有数以百万计的大一新生满怀着对未来的渴望,怀着指点江山,造福一方的心态踏入他们梦寐以求的大学校园,去接受大学教育的洗礼.我由衷的希望,在4年 ...

  10. 传智播客就是牛人培养牛人的地方!

    今天不经意间被朋友问了一下,我才突然意识到自己在传智播客培训已经快有三个月了,时间过得真快啊!         在这三个月左右的时间,仿佛是我目前人生中最最充实的三个月,也让我默默的有了很大的提高,回 ...

最新文章

  1. Git_Eclipse:[3]Git初始化工程
  2. SNMP协议介绍和操作截图
  3. SQLite的ADO.NET Provider支持ADO.NET Entity Framework
  4. 两种获取Stream流的方式
  5. 《南方都市报》:三鹿集团300万摆平搜索引擎?
  6. docker 学习记录
  7. 动态二维数组外圈元素值的和_C语言 | 用指向元素的指针变量输出二维数组元素的值...
  8. CSDN 输入公式的方法
  9. 开培训会没人来,是正常的
  10. Docker 容器监控Cadvisor+Prometheus+Grafana
  11. 200plc与施耐德ATV610变频器modbus通讯
  12. 网站监控服务都包括哪些具体内容?
  13. 计算机丢失MSVCR100.dll文件的解决办法
  14. VLAN与三层交换机
  15. 活动回顾 | Mini XMan线上快闪活动圆满结束!
  16. 怎么删除日历每日重复提醒事项
  17. JavaScript(第三天)—爱创课堂专业前端培训
  18. Go语言学习之net/http包(The way to go)
  19. 新疆库尔勒市杜鹃河上演人禽共泳和谐相处画卷
  20. 最简单的python使用ddddocr模块在线识别验证码后登录

热门文章

  1. 基于中国新能源汽车税收政策下成都市场发展路线研究
  2. Python 结构体数组初始化代码示例
  3. 抖音快手免费去水印方法技巧
  4. 【6】python生成数据曲线平滑处理——(Savitzky-Golay 滤波器、convolve滑动平均滤波)方法介绍,推荐玩强化学习的小伙伴收藏
  5. 微积分总结(数列与无穷级数)
  6. Air720H模块MQTT协议的AT指令流程
  7. 传感器实验——超声波测距
  8. 机器学习(MACHINE LEARNING)MATLAB实现层次分析法案例【AHP】
  9. 机器学习sklearn(13)层次聚类
  10. latex 混淆矩阵