最近闲来无事,就想着模拟一下struts2的工作机制,也没怎么去查看struts2的源码,大概了解它实现的机制,所以就磕磕碰碰的去写了一下这个东西,也许和struts2的实现机制不一样,但是目的总是一样的。
struts2首先也是装载相应的配置文件才能工作,当然struts2还有它的零配置也能完成工作,但是我模拟的是装载xml配置文件,要写xml文件当然也得写一个xsd文件来规范xml文件,现附上xsd文件。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.myblogs.org" elementFormDefault="qualified" targetNamespace="http://www.myblogs.org">
<!-- 元素定义 -->
<xs:element name="webwork" type="webworkType" />
<xs:element name="action" />
<xs:element name="result" />
<xs:element name="param" />
<xs:complexType name="webworkType">
<xs:sequence>
<xs:element name="action" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="result" minOccurs="1" maxOccurs="unbounded">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="param" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" default="root"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="resultValue" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="actionValue" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:attributeGroup name="actionValue">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="class" type="xs:string" use="required" />
<xs:attribute name="method" type="xs:string" default="execute" />
</xs:attributeGroup>
<xs:attributeGroup name="resultValue">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="type" type="xs:string" default="jsp" />
</xs:attributeGroup>
</xs:schema>
xsd文件主要是规范xml文件中的元素以及各个属性,当然在eclipse中编写xml文件的时候,xsd将会验证xml文件是否符合xsd规范,如果是使用notepad来写xml文件的话,当然也只能用相应的语言来验证xml文件的规范了。
接着附上webwork.xml文件,类似于struts2中的struts2.xml
<?xml version="1.0" encoding="UTF-8"?>
<webwork xmlns="http://www.myblogs.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.myblogs.org webwork.xsd">
<action name="AjaxAction" class="test.ajax.AjaxAction">
<!-- result元素中目前支持jsp与json类型 -->
<result name="ajaxResponse" type="json">
<param name="root">user</param>
</result>
</action>
<action name="LoginAction" class="blog.login.action.LoginAction">
<result name="login" type="jsp">login.jsp</result>
</action>
</webwork>
result元素中目前支持jsp与json类型,支持json类型的返回调用主要是为了ajax的支持,在ajax中使用json来传值当然方便很多,当然以后可以扩展更多的返回类型,比如freemarker等等。
下面来看看如何装载xml文件中的各个元素。为了以后方便扩展,分别写了4个相应的bean配置。
actionConfig.java,resultConfig.java,paramConfig.java,WebworkXmlConfig.java
package blog.base.config;
/**
* @author 张廷 2011-5-18下午06:24:11
*
*/
public class ActionConfig {
private String actionName;
private Object actionClass;
private String method;
//省略getter 和setter
}
ResultConfig.java
package blog.base.config;
/**
* @author 张廷 2011-5-18下午06:25:47
*
*/
public class ResultConfig {
private String resultName;
private String resultType;
private String toUrl;
private List<ParamConfig> paramConfigs;
//省略getter 和setter
}
ParamConfig.java
package blog.base.config;
/**
*
* @author 张廷 2011-5-18下午06:27:13
*
*/
public class ParamConfig {
private String paramName;
private String paramVarible;
//省略getter和setter
}
WebworkXmlConfig.java
package blog.base.config;
import java.util.List;
/**
* @author 张廷 2011-5-18下午08:25:53
*
*/
public class WebworkXmlConfig {
private ActionConfig actionConfig;
private List<ResultConfig> resultConfigs;
//声裂getter和setter
}
最终操作在action的访问以及result返回时所操作的类全都是操作WebworkXmlConfig.java这个类,下面来看下装载xml文件的类,该类使用的是dom4j来解析xml文件。
/**
*
*/
package blog.base.util;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import blog.base.config.ActionConfig;
import blog.base.config.ParamConfig;
import blog.base.config.ResultConfig;
import blog.base.config.WebworkXmlConfig;
/**
* @author 张廷 2011-5-18下午02:59:27
*
*/
public class WebWorkXmlParser {
private static WebworkXmlConfig webworkConfig;
private static Logger logger = Logger.getLogger(WebWorkXmlParser.class);
/**
* 装载webwork.xml中action节点的所有元素
*
* @param path
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static Map<String, WebworkXmlConfig> readActions(String configLocation) throws Exception {
// 取得配置文件Url
URL url = WebWorkXmlParser.class.getClassLoader().getResource(configLocation);
SAXReader saxReader = new SAXReader();
Map<String, WebworkXmlConfig> actionMapping = new HashMap<String, WebworkXmlConfig>();
try {
Document doc = saxReader.read(new File(path));
Element rootElement = doc.getRootElement();
if ("webwork".equals(rootElement.getName())) {
for (Iterator<Element> actions = rootElement.elementIterator("action"); actions.hasNext();) {
Element actionElmt = actions.next();
webworkConfig = new WebworkXmlConfig();
ActionConfig action = new ActionConfig();
action.setActionName(actionElmt.attributeValue("name"));
action.setActionClass(newInstance(actionElmt.attributeValue("class")));
String method = actionElmt.attributeValue("method");
// 访问action时是否指定相应方法,默认执行execute
if ("".equals(method) || null == method) {
action.setMethod("execute");
} else {
action.setMethod(method);
}
// 创建一个results,一个action会包含多个result
List<ResultConfig> resultList = iterationResult(actionElmt);
webworkConfig.setResultConfigs(resultList);
webworkConfig.setActionConfig(action);
actionMapping.put(action.getActionName(), webworkConfig);
}
} else
throw new Exception("没有找到webwork标签!");
} catch (DocumentException e) {
e.printStackTrace();
}
return actionMapping;
}
/**
* 迭代action元素下的所有result
*
* @param actionElmt
* @return
*/
@SuppressWarnings("unchecked")
private static List<ResultConfig> iterationResult(Element actionElmt) {
List<ResultConfig> resultList = new ArrayList<ResultConfig>();
for (Iterator<Element> results = actionElmt.elementIterator("result"); results.hasNext();) {
Element resultElmt = results.next();
ResultConfig result = new ResultConfig();
result.setResultName(resultElmt.attributeValue("name"));
result.setResultType(resultElmt.attributeValue("type"));
// 判断result下是否还有元素,如果还有元素,继续扫描
if ("".equals(resultElmt.getTextTrim())) {
// 创建一个params,一个result会包含多个param
List<ParamConfig> paramList = iterationParam(resultElmt);
result.setParamConfigs(paramList);
} else {
result.setToUrl(resultElmt.getTextTrim());
}
resultList.add(result);
}
return resultList;
}
/**
* 迭代result元素下的所有param
*
* @param resultElmt
* @return
*/
@SuppressWarnings("unchecked")
private static List<ParamConfig> iterationParam(Element resultElmt) {
List<ParamConfig> paramList = new ArrayList<ParamConfig>();
// 迭代result下的每个param
for (Iterator<Element> params = resultElmt.elementIterator("param"); params.hasNext();) {
Element paramElmt = params.next();
ParamConfig param = new ParamConfig();
param.setParamName(paramElmt.attributeValue("name"));
param.setParamVarible(paramElmt.getTextTrim());
paramList.add(param);
}
return paramList;
}
/**
* 创建一个实例
*
* @param clazz
* @return
*/
private static Object newInstance(String clazz) {
Object handler = null;
try {
handler = Class.forName(clazz).newInstance();
} catch (InstantiationException e) {
logger.fatal("对象无法被实例化!", e);
e.printStackTrace();
} catch (IllegalAccessException e) {
logger.error("该实例无法访问!", e);
e.printStackTrace();
} catch (ClassNotFoundException e) {
logger.error("没有找到具有指定名称的类的定义!", e);
e.printStackTrace();
}
return handler;
}
}
这里将配置文件中的所有信息都注入到了WebworkXmlConfig这个实体中,以后要在servlet中访问action以及跳转到相应的jsp页面或者是使用json来响应客户端都要经过WebworkXmlConfig这个类来控制,这一节就到这,
下一节将会涉及到servlet中如何使用此类来做访问响应工作。
分享到:
相关推荐
下面我们将探讨如何利用Java反射模拟Struts2的工作原理。 首先,Struts2在启动时会读取配置文件,通常是`struts.xml`,该文件定义了各个Action及其对应的处理方法和结果页面。在模拟这个过程时,我们需要创建一个...
在本主题中,我们将深入探讨如何利用Java反射来模拟Struts框架中的中央控制器。 Struts框架是基于Model-View-Controller(MVC)设计模式的,它的中央控制器是`ActionServlet`,它负责接收HTTP请求,解析请求参数,...
在本主题"Servlet简单模拟Struts2"中,我们将探讨如何利用Servlet来实现类似Struts2框架的一些关键功能,包括请求拦截、XML配置解析、动态代理以及日志拦截。 首先,让我们了解一下Struts2框架的核心特性。Struts2...
这个过程不仅加深了对Struts工作原理的理解,也锻炼了Java反射和XML解析的能力。不过,实际开发中,使用成熟的Struts框架能提供更多的便利和优化,如AOP(面向切面编程)支持、更丰富的插件等。
总的来说,模拟Struts2环境是学习和理解MVC框架以及Java Web开发的一个良好途径。通过对配置文件的调整和实际代码的编写,开发者可以深入掌握Struts2的工作原理和最佳实践。同时,熟悉反射机制对于理解框架的内部...
模拟Struts** Struts是一个基于MVC(Model-View-Controller)设计模式的Java Web框架。在这个练习的最后部分,我们将尝试理解Struts的工作原理,并用简单的Java类模拟其关键组件,如Action和ActionForm。 - **...
Java反射机制是Java语言提供的一种强大的能力,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这种灵活性使得Java成为一种半静态半动态的语言,能够在一定程度上模拟...
[学习资料] 09年Java认证考试:JAVA反射机制的简单应用 [学习资料] 09年Java认证考试:JFreeChart做题杂谈 [学习资料] 09年Java认证考试:struts2.0的标签库(简介) [考试试题] 09年Java认证考试:5道JAVA题 [考试...
**Struts2框架的工作流程**: 1. 客户端发起HTTP请求到Servlet容器。 2. 请求经过一系列过滤器,包括ActionContextCleanUp,为与其他框架集成提供便利。 3. FilterDispatcher作为核心控制器被调用,它会询问...
在`myStruts1`项目中,你可能已经实现了这些核心组件,并通过编写自定义的Action、FormBean和XML配置文件来模拟Struts的功能。这将帮助你深入理解Struts的工作原理,为今后使用或优化Struts框架打下坚实的基础。此外...
反射(Reflection)是Java中的一个高级特性,它允许在运行时访问类的信息,如类名、构造函数、字段和方法等。反射可以动态创建和操作对象,常用于框架开发、插件系统、序列化等领域,但它也可能影响性能和安全性。 ...
#### 一、Java技术体系概览 Java作为一种广泛使用的编程语言,在IT行业中占有举足轻重的地位。为了帮助那些希望在Java领域发展的技术人员更好地理解和掌握Java的相关知识和技术,本文将根据“Java技术体系图”展开...
这些题目涵盖了最新的技术和趋势,旨在为求职者提供一份真实的模拟体验,让他们能够在实际面试中更加自信和从容。 此外,作者还将自己在职场上的经验和感悟融入其中,希望通过这种方式引导读者更好地规划自己的职业...
Struts框架是Java Web开发中一个非常重要的MVC(Model-View-Controller)框架,它为开发者提供了一种结构化的方式来组织和管理应用程序。在早期的Struts版本中,`DispatchAction`类是一个核心组件,它允许我们通过...
Java是世界上最流行的编程语言之一,尤其在企业级应用开发领域占据主导地位。SSM(Spring、Struts和MyBatis)是Java后端开发中常用的三大框架,它们各自负责应用程序的不同层面,如Spring管理依赖注入和业务逻辑,...
面向对象分析与设计(OOA/OOD)是Java开发的核心概念之一,它强调通过对象来模拟现实世界的问题解决方案。设计模式则是解决特定问题的模板,如GOF(Gang of Four)设计模式和J2EE设计模式,它们提供了可复用的代码...
Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(后被Oracle收购)开发,以其“一次编写,到处运行”的特性受到全球程序员的喜爱。本Java培训资料集合了多位知名讲师的精华内容,包括比向东、方力勋、...
2. **面向对象编程**:Java是一种纯面向对象的语言,所以你需要理解类、对象、封装、继承、多态等概念。掌握如何创建和使用类,以及如何通过继承和多态实现代码重用。 3. **异常处理**:Java中的异常处理机制用于...
13. **模拟Struts1/2和Spring MVC**:模拟Struts框架或Spring MVC框架进行开发实践。 #### 六、JavaEE核心技能 1. **Struts2**:介绍Struts2框架的架构及使用方法。 2. **Spring MVC**:讲解Spring MVC框架的基本...
- **反射与注解**:反射是Java动态特性的体现,注解则是元数据的一种形式,二者都是Java高级编程的重要组成部分。 #### 二、数据库&JDBC编程 **1. SQL基础(重点)** - **SQL基础**:包括SQL语句的基本结构、数据...