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

传智:自己简单实现一个struts2框架的demo的更多相关文章

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

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

  2. 第一个struts2框架

    编写步骤: 1.导入有关的包. 2.编写web.xml文件 3.写Action类 4.编写jsp 5.编写struts.xml web.xml <?xml version="1.0&q ...

  3. 利用jdbc简单封装一个小框架(类似DBUtils)

    利用jdbc写的一个类似DBUtils的框架 package com.jdbc.orm.dbutils; import java.io.IOException; import java.io.Inpu ...

  4. 简单创建一个完整的struts2框架小程序

    要完成一个struts2框架的搭建, 1.首先应该从官网上下载最新的jar包,网络连接:http://struts.apache.org/download.cgi#struts2514.1,选择下载F ...

  5. Struts2框架之类型转换 --Struts2框架

    Struts2框架实现了大多数常见的用于类型转换的转换器,开发人员不用自己编写类型转换代码,就可以实现数据类型的转换.下面一个Struts2框架类型转换的简单事例, 本例可在使用validate()方 ...

  6. struts2框架 转载 精华帖

    一.Struts2简介 参考<JavaEE 轻量级框架应用与开发—S2SH> Struts框架是流行广泛的一个MVC开源实现,而Struts2是Struts框架的新一代产品,是将Strut ...

  7. 搭建一个简单struts2框架的登陆

    第一步:下载struts2对应的jar包,可以到struts官网下载:http://struts.apache.org/download.cgi#struts252 出于学习的目的,可以把整个完整的压 ...

  8. 搭建一个简单的Struts2框架

    1  创建一个web项目. 2 导入必要的JAR文件. 放在WEB-INF下lib包里. 3 添加web.xml配置,添加启动配置. <?xml version="1.0" ...

  9. 关于在Struts2框架下实现文件的上传功能

    struts2的配置过程 (1)在项目中加入jar包 (2)web.xml中filter(过滤器)的配置 <?xml version="1.0" encoding=" ...

随机推荐

  1. (转)nginx负载均衡(5种方式)、rewrite重写规则及多server反代配置梳理

    Nginx除了可以用作web服务器外,他还可以用来做高性能的反向代理服务器,它能提供稳定高效的负载均衡解决方案.nginx可以用轮询.IP哈希.URL哈希等方式调度后端服务器,同时也能提供健康检查功能 ...

  2. Spring Boot 全局异常配置

    Spring Boot 全局异常配置,处理异常控制器需要和发生异常的方法在一个类中.使用 ControllerAdvice 注解 package com.li.controller; import o ...

  3. 经验搜索排名---google已经做过类似的了(我想多了)

    由于编程的原因,我们需要经常的查资料,现在转载的文章比较多,我们经常看到的搜索结果的前十名基本上有7名是转载的.这样看起来很没有效率,后来突然想到,如果把大家的浏览结果搜集起来,然后进行权重排名,这样 ...

  4. 找回 linux root密码的几种方法

    第1种方法: 1.在系统进入单用户状态,直接用passwd root去更改  2.用安装光盘引导系统,进行linux rescue状态,将原来/分区挂接上来,作法如下: Java代码  #> c ...

  5. Django小项目web聊天

    WEBQQ的实现的几种方式 1.HTTP协议特点 首先这里要知道HTTP协议的特点:短链接.无状态! 在不考虑本地缓存的情况举例来说:咱们在连接博客园的时候,当tcp连接后,我会把我自己的http头发 ...

  6. 《Clean Code》一书回顾

    <Clean Code>一书从翻开至今,已经差不多两个月的时间了,尽管刨去其中的假期,算下来实在是读得有点慢.阅读期间,断断续续的做了不少笔记.之前,每每在读完了一本技术书籍之后,其中的诸 ...

  7. (15)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第三部分(完)

    引言 程序截图: 在第二部分教程中,Ray教大家如何在地图中制作可碰撞的区域,如何使用tile属性,如何制作可以拾取的物品以及如何动态修改地图.如何使用“Heads up display”来显示分数. ...

  8. 文件下载—SSM框架文件下载

    1.准备上传下载的api组件 <dependency> <groupId>commons-io</groupId> <artifactId>common ...

  9. uva11324 有向图的强连通分量+记忆化dp

    给一张有向图G, 求一个结点数最大的结点集,使得该结点集中任意两个结点u和v满足,要么u可以到达v, 要么v可以到达u(u和v相互可达也可以). 因为整张图可能存在环路,所以不好使用dp直接做,先采用 ...

  10. FlexPaper_1.2.1.swc——Flex在线显示PDF文档(使用FlexPaper)感悟

    http://www.cnblogs.com/wuhenke/archive/2010/03/16/1686885.html 想想自己先前搞PDF转SWF,然后在线浏览功能时,实在是费了不少精力.后来 ...