您的位置:首页 > 编程语言 > Java开发

自己实现Struts2(二)加载配置文件

2017-03-25 22:42 453 查看
上一章自己实现Struts2(一)Struts流程介绍和环境搭建我把Struts2框架执行流程简单地介绍了一下,顺便把环境搭建起来了,这一章我们就先来来完成读取配置文件这一块。

准备配置文件

要想读取配置文件,得先有配置文件,我准备了一个
struts.xml
文件,文件内容如下

<?xml version="1.0" encoding="UTF-8"?>
<struts>
<!-- 1.指定请求路径后缀 -->
<constant name="struts.action.extension" value="action" />
<!-- 2.参数拦截器 -->
<interceptor class="edu.jyu.interceptor.ParametersInterceptor" />
<!-- 3.定义一个action -->
<action name="Hello" class="edu.jyu.action.HelloAction" method="execute">
<result name="success">/index.jsp</result>
</action>
</struts>


现在我来介绍一下这个文件。首先大家注意到我并没有写一个dtd文件去约束这个xml,这里大家需要知道的是,我做的这个是精简版,阉割版,超级山寨版,所以……不要在意这么多,关注我们应该关注的。

首先来说一下Struts2的常量
struts.action.extension
,这个用过的都知道,这个常量用来指定Struts2处理的请求规定的后缀,如果不是以这个后缀结尾则不作处理。一般我们都会把这个值设为
.action
或者
.do


然后就是参数拦截器
ParametersInterceptor
,这个大家应该都不陌生了,用于把参数封装到action的属性中。

最后就是action了,这个action并没有在
package
中,简化简化哈,不过这样子我也能让它运行起来。

我就根据上面的配置文件来编写后面的功能,大家就不用期待什么国际化、Json插件什么的功能了哈。

读取常量信息即constant标签

首先要先创建一个
ConfigurationManager
类,这个类就是专门来读取配置文件
struts.xml


读取constant标签代码如下

package edu.jyu.config;

import java.io.InputStream;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
* 读取struts.xml文件中的配置信息的类
*
* @author Jason
*/
public class ConfigurationManager {

/**
* 读取struts.xml中name属性等于传进来name变量的constant标签
*
* @param name
*            匹配content标签中name属性值
* @return 如果存在符合条件的content标签则返回该标签的value属性值,否则返回null
*/
public static String getConstant(String name) {
Document doc = getDocument();
// XPath语句,选取属性name值为name变量的值的constant标签
String xpath = "//constant[@name='" + name + "']";
Element con = (Element) doc.selectSingleNode(xpath);
if (con != null) {
return con.attributeValue("value");
} else {
return null;
}
}

/**
* 加载配置文件
*
* @return 返回配置文件对应的文档对象
*/
private static Document getDocument() {
// 创建解析器
SAXReader reader = new SAXReader();
// 加载配置文件
InputStream is = ConfigurationManager.class.getResourceAsStream("/struts.xml");
Document doc = null;
try {
doc = reader.read(is);
} catch (DocumentException e) {
e.printStackTrace();
throw new RuntimeException("加载配置文件出错");
}
return doc;
}
}


代码并不复杂,提供一个内部使用的方法来加载配置文件,因为等下读取拦截器和action时还得用到呢。然后读取name属性等于传进来name变量的constant标签,整个查找用XPath的话就很简单,不用一个节点一个节点地找。

读取拦截器配置

读取拦截器配置的方法

/**
* 读取struts.xml中所有interceptor标签的信息
*
* @return 包含struts.xml中所有interceptor标签的信息的列表
*/
public static List<String> getInterceptors() {
List<String> interceptors = null;
Document doc = getDocument();
// XPath语句,选取所有 interceptor子元素,而不管它们在文档中的位置。
String xpath = "//interceptor";
List<Element> nodes = doc.selectNodes(xpath);
if (nodes != null && nodes.size() > 0) {
interceptors = new ArrayList<String>();
for (Element ele : nodes) {
// 获得class属性的值
String className = ele.attributeValue("class");
interceptors.add(className);
}
}
return interceptors;
}


也不是很难了,要用集合和存放所有的拦截器全限定名,如
edu.jyu.interceptor.ParametersInterceptor


读取action配置

读取action配置之前,要先创建一个
ActionConfig
类用来代表action,Struts2框架也有这个的。

下面是ActionConfig类的代码

package edu.jyu.config;

import java.util.LinkedHashMap;
import java.util.Map;

/**
* 映射struts.xml中action标签的实体类
*
* @author Jason
*/
public class ActionConfig {

private String name;
private String method;
private String className;

private Map<String, String> results = new LinkedHashMap<String, String>();

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getMethod() {
return method;
}

public void setMethod(String method) {
this.method = method;
}

public String getClassName() {
return className;
}

public void setClassName(String className) {
this.className = className;
}

public Map<String, String> getResults() {
return results;
}

public void setResults(Map<String, String> results) {
this.results = results;
}

@Override
public String toString() {
return "ActionConfig [name=" + name + ", method=" + method + ", className=" + className + ", results=" + results
+ "]";
}

}


不用写备注都知道它的每个字段对应配置文件action标签的哪些属性了吧。其中需要注意的结果集
results
要用
Map<String, String>
存储,因为result可能有多个,而且每个都是一个名字一个值(当然这只是最简单的情况,可能还会有type属性呢),实现类我用的是
LinkedHashMap
,Struts2也是用这个的。

下面就是读取action了

/**
* 读取struts.xml中所有action标签的信息
*
* @return 包含struts.xml中所有action标签的信息的映射,其中key为action的name
*/
public static Map<String, ActionConfig> getActions() {
Map<String, ActionConfig> actionMap = null;
Document doc = getDocument();
// XPath语句,选取所有 action子元素,而不管它们在文档中的位置。
String xpath = "//action";
List<Element> nodes = doc.selectNodes(xpath);
if (nodes != null && nodes.size() > 0) {
actionMap = new HashMap<String, ActionConfig>();
for (Element ele : nodes) {
ActionConfig ac = new ActionConfig();
ac.setName(ele.attributeValue("name"));
ac.setClassName(ele.attributeValue("class"));
String method = ele.attributeValue("method");
// 判读是否有填写方法名,没有的话就默认为execute
method = (method == null || method.trim().equals("")) ? "execute" : method;
ac.setMethod(method);
// 获取当前action标签下的所有result标签
List<Element> results = ele.elements("result");
for (Element res : results) {
ac.getResults().put(res.attributeValue("name"), res.getText());
}
actionMap.put(ac.getName(), ac);
}
}
return actionMap;

}


方法也是很容易看懂的,主要是用
Map<String, ActionConfig>
来存储所有的action信息,这样就可以根据action的name来查找action信息。

测试

ConfigurationManager类写完了,现在写个类来测试一下里面的三个读取方法。我新建了一个
Source Folder
命名为test

package edu.jyu.config;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.junit.Test;

/**
* 测试读取配置文件类ConfigurationManager
*
* @author Jason
*/
public class TestConfigurationManager {

/**
* 测试读取constant标签信息
*/
@Test
public void testGetConstant() {
String extension = ConfigurationManager.getConstant("struts.action.extension");
String encoding = ConfigurationManager.getConstant("struts.i18n.encoding");
System.out.println("struts.action.extension = " + extension);
System.out.println("struts.i18n.encoding = " + encoding);
}

/**
* 测试读取拦截器信息
*/
@Test
public void testGetInterceptors() {
List<String> interceptors = ConfigurationManager.getInterceptors();
for (String str : interceptors) {
System.out.println(str);
}
}

/**
* 测试读取action信息
*/
@Test
public void testGetActions() {
Map<String, ActionConfig> actions = ConfigurationManager.getActions();
Set<Entry<String, ActionConfig>> entrySet = actions.entrySet();
for (Entry<String, ActionConfig> entry : entrySet) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}


A、测试读取constant标签信息,输出结果

struts.action.extension = action
struts.i18n.encoding = null


B、测试读取拦截器信息,输出结果

edu.jyu.interceptor.ParametersInterceptor


C、测试读取action信息

Hello = ActionConfig [name=Hello, method=execute, className=edu.jyu.action.HelloAction, results={success=/index.jsp}]


老铁,没毛病呀

好了,加载配置文件大功告成,项目已经上传到Github上

https://github.com/HuangFromJYU/JStruts2

如果大家有什么问题或者发现什么错误可以发邮件到jasonwong_hjj@qq.com,共同学习共同进步
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  struts 框架 struts2.0