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

来源:互联网 发布:阿里云服务器宕机 编辑:程序博客网 时间:2024/06/05 07:48

上一章自己实现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,这里大家需要知道的是,我做的这个是精简版,阉割版,超级山寨版,所以……不要在意这么多,关注我们应该关注的。

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

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

  3. 最后就是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 = actionstruts.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,共同学习共同进步

0 0
原创粉丝点击