Struts2MVC底层的简单实现
一直想写Struts2的底层实现,酝酿了两个星期,今天把它实现。
首先,我们在运用的时候都会使用action,实现跳转,下面我们写一个UserAction:
public class UserAction {public String toAddUser(){return "success";}public String addUser(){return "adduser";} }
我们在使用Struts2的时候,一个很重要的配置文件是:struts.xml,因此我们需要读取它,知道他里面的内容,java解析xml我写过了一篇文章,可以去看看。
下面我们写一个配置文件:
<?xml version="1.0" encoding="UTF-8"?> <struts><package name="user" namespace="/user" ><action name="userAction" class="actions.UserAction" ><result name="success">/success.jsp</result><result name="adduser">/addUser.jsp</result></action></package> </struts>
之后我们就需要去读取这个配置文件,但是之前我们需要我们需要建立几个实体类去存储这些元素,由外到内排列:
1.package的实体类
import java.util.List; public class PackageEntity {private String name;private String namespace;private List<ActionEntity> actions;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getNamespace() {return namespace;}public void setNamespace(String namespace) {this.namespace = namespace;}public List<ActionEntity> getActions() {return actions;}public void setActions(List<ActionEntity> actions) {this.actions = actions;} }
private List<ActionEntity> actions;是吧action实体类的内容放到package中。
2.action的实体类
import java.util.List; public class ActionEntity {private String name;private String classname;private List<ResultEntity> results;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getClassname() {return classname;}public void setClassname(String classname) {this.classname = classname;}public List<ResultEntity> getResults() {return results;}public void setResults(List<ResultEntity> results) {this.results = results;} }
private List<ResultEntity> results;是把result的实体类放到action中。
3.result的实体类
public class ResultEntity {private String name;private String page;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPage() {return page;}public void setPage(String page) {this.page = page;} }
page是指后面的jsp。
经过两个list就把配置文件中所有的元素集中到package中,便于下面的跳转。
下面写一个配置的工具类:
public class ConfigUtils { //new一个package的对象,便于调用元素public static PackageEntity pe=new PackageEntity();public static void config(){SAXReader reader=new SAXReader();try {//读取struts.xmlDocument doc=reader.read(Thread.currentThread().getContextClassLoader().getResourceAsStream("struts.xml"));//读取根元素Element root=doc.getRootElement();//得到根元素下的节点元素Element packageElement=root.element("package");List<ActionEntity> actions=new ArrayList<ActionEntity>();pe.setName(packageElement.attributeValue("name"));pe.setNamespace(packageElement.attributeValue("namespace"));//得到根元素下的节点元素List<Element> listActions=packageElement.elements("action");for(Element actionElement:listActions){ActionEntity ae=new ActionEntity();//得到子节点ae.setName(actionElement.attributeValue("name"));ae.setClassname(actionElement.attributeValue("class"));//得到根元素下的节点元素List<Element> resultElements=actionElement.elements("result");List<ResultEntity> results=new ArrayList<ResultEntity>();for(Element resultEle:resultElements){ResultEntity re=new ResultEntity();//得到子节点re.setName(resultEle.attributeValue("name"));re.setPage(resultEle.getText());results.add(re);}ae.setResults(results);actions.add(ae);}pe.setActions(actions);} catch (DocumentException e) {e.printStackTrace();}} }
写一个index.jsp,为了写跳转链接进行验证:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><title>首页</title></head><body><a href="<%=path%>/user/userAction!toAddUser.action">跳转</a><br/><a href="<%=path%>/user/userAction!addUser.action">添加用户</a></body> </html>
跳转是跳到到success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><title>My JSP 'success.jsp' starting page</title></head><body>This is my JSP page. <br>成功了</body> </html>
添加用户是跳到adduser.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><title>My JSP 'addUser.jsp' starting page</title></head><body>This is my JSP page. <br>添加用户了</body> </html>
写好了jsp之后我们就要过滤这些连接,进行跳转,写一个struts2的过滤器:
public class StrutsFilter implements Filter {@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {HttpServletRequest request=(HttpServletRequest)req;String path=request.getServletPath();System.out.println(path);String[] pathArr=path.split("/");String namespace=pathArr[1];String actionString=pathArr[2];String actionname=actionString.split("!")[0];String methodname=actionString.split("!")[1].split("\\.")[0];System.out.println(actionname+":"+methodname);PackageEntity pe=ConfigUtils.pe;List<ActionEntity> actions=pe.getActions();ActionEntity doAction=null;for(ActionEntity ae:actions){if(ae.getName().equals(actionname)){doAction=ae;break;}}try {Class actioncls=Class.forName(doAction.getClassname());Object actionObj=actioncls.newInstance();Class cls=actionObj.getClass();Method actionMethod=cls.getDeclaredMethod(methodname);String resultValue=(String)actionMethod.invoke(actionObj,null);List<ResultEntity> results=doAction.getResults();ResultEntity re=null;for(ResultEntity result:results){if(resultValue.equals(result.getName())){re=result;break;}}request.getRequestDispatcher(re.getPage()).forward(request, res);} catch (Exception e) {e.printStackTrace();}}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {ConfigUtils.config(); } }
下面建立一个web的过滤器测试一下:
import java.io.IOException; 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; public class TestFilter implements Filter {@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {HttpServletRequest request=(HttpServletRequest)req;HttpServletResponse response=(HttpServletResponse)res;request.getRequestDispatcher("/success.jsp").forward(request,response); }@Override public void init(FilterConfig filterConfig) throws ServletException {} }
建立一个web的servlet测试一下:
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{ request.getRequestDispatcher("/success.jsp").forward(request, response);} }
别忘了把解析xml的包导进去。
希望对你们理解框架有帮助!!!
转载于:https://blog.51cto.com/7915791/1350348
Struts2MVC底层的简单实现相关推荐
- tensorflow入门教程和底层机制简单解说——本质就是图计算,自动寻找依赖,想想spark机制就明白了...
简介 本章的目的是让你了解和运行 TensorFlow! 在开始之前, 让我们先看一段使用 Python API 撰写的 TensorFlow 示例代码, 让你对将要学习的内容有初步的印象. 这段很短 ...
- 第十三章_Java中常用集合大整理(含底层数据结构简单介绍)
第十三章_Java中常用集合大整理 1.集合和数组的区别 集合 既可以存储基本数据类型还可以存储引用数据类型 定长–>是数组最大的特点,也是最大的缺点 数组 只能存储引用数据类型 长度可变 相同 ...
- HashSet底层原理简单详解
1.HashSet底层其实是一个HashMap容器,HashSet的无参构造方法是创建一个HashMap对象 private transient HashMap<E, Object> ma ...
- 【重难点】【Redis 01】为什么使用 Redis、Redis 的线程模型、Redis 的数据类型及其底层数据结构
[重难点][Redis 01]为什么使用 Redis.Redis 的线程模型.Redis 的数据类型及其底层数据结构 文章目录 [重难点][Redis 01]为什么使用 Redis.Redis 的线程 ...
- 简单了解消息中间件及ActiveMQ
最近阅读文献,发现一篇介绍中间件及ActiveMQ的好文章,特此转载留存,同时也分享给大家.原文献地址:https://segmentfault.com/a/1190000014958916?utm_ ...
- 【Go语言学习】——go 数据结构底层原理
go 数据结构底层原理 array底层原理 go中的数组是由固定长度的特定类型元素组成的序列,数组的长度是数据类型的组成方式,所以不同长度和不同类型的元素组成的数组是不同的数组类型.数组属于值类型,因 ...
- Redis从入门到精通之底层数据结构快表QuickList详解
文章目录 0.前言 1. 快表的结构 2. Redis 6.0 快表quicklist 基本结构 2.1 成员变量 2.1 主要操作 2.1 推导结果 3. 快表的操作 3. 快表的优缺点 3.1 优 ...
- 22张精炼图笔记,深度学习专项学习必备
作者 | DL&CV_study9 编辑 | Elle 来源 | CSDN 博客 本文为人工智能学习笔记记录. [深度学习基础篇] 一.深度学习基本概念 监督学习:所有输入数据都有确定的对应输 ...
- ElasticSearch 面试 4 连问,你顶得住么?
点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 者:yanglbme github.com/doocs/ad ...
- Elasticsearch 查询数据的工作原理是什么?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:8rr.co/GsAa 面试题 ES 写入数据的工作原理是什 ...
最新文章
- NLP能否像人脑一样工作?CMU、MIT三篇论文详解机器和大脑范畴下NLP的关系
- IOS开发CALayer隐式动画
- 算法测试—机器学习算法评价指标
- 教你11 周打造全能Python工程师!
- Uiautomator--Uiselector元素定位
- 别再叫我“老工”!!!工程师姓什么很重要!
- 12个有趣的C语言面试题
- Jinja2模板与模板继承
- ASP.NET Web开发框架之八 所有ERP部分的源代码全部开放下载
- SQL Server商业智能功能–创建简单的OLAP多维数据集
- 不可识别的字符转义序列_大庆事业单位车牌识别道闸多少钱,感应小区车牌识别道闸系统...
- 软件质量需要静态代码分析和动态测试
- 【Multisim仿真】LM317-337双路输出可调直流稳压电源电路
- 一个三非渣本的安卓秋招之路
- 烤仔星选·NFT实验室 | 非同质化代币在游戏领域的应用
- 编译小度deng wifi源码出错
- 解决 ImportError: No module named 'serial' 问题
- java生成PDF 导出
- 软件测试之计算机基础
- python计算给定的日期的星期_Python计算给定日期的周内的某一天