Apache Digester示例–轻松配置

解决问题–硬编码,需要为您的应用程序创建自定义配置,例如struts配置文件,以仅通过更改文件来改变应用程序行为。 Apache Digester可以轻松为您完成此任务。

使用Apache Digester相当容易将XML文档转换为相应的Java bean对象层次结构。 请参阅下面的“摘要”。
Digester引入了三个重要概念:

  1. 元素匹配模式
  2. 处理规则
  3. 对象堆栈。

元素匹配模式将 XML元素与处理规则相关联。

范例:
你有什么:

  1. Java类
  2. 包含数据的XML文件

您有Java类和相应的xml文件。 您希望从xml数据创建Java类实例。

您需要编写哪些额外的代码。
分步任务:

  1. 在类路径中添加Apache Digester 3 jar文件,Commons日志jar,Beanutils jar,cglib jar
  2. 如果没有Java类,则为相应的xml文件创建Java类。或者,如果没有xml文件,则根据java类创建。注-属性名称,xml和java类中的层次结构应匹配,否则,需要在此处未提及的摘要XML规则中提供映射。
  3. 如以下示例中所述,创建摘要规则XML文件
  4. 用几行来从XML加载Java对象

现在在行动–

这是我的Eclipse项目结构:

任务2 –如下创建数据xml文件,您要从中加载数据, 例如– chain-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<catalogs>

    <!-- Default Catalog: "Path Info" example -->
    <catalog>

        <!-- Command that maps "Path Info" patterns to Commands -->
        <chain name="COMMAND_MAPPER">
            <command                       className="org.apache.commons.chain.web.servlet.PathInfoMapper"/>
            <command forward="/pathinfo.jsp"  className="org.apache.commons.chain.apps.example.ForwardCommand"/>
        </chain>

        <!-- Foo Command -->
        <chain name="/foo">
            <command attribute="pathinfoFooCount" className="org.apache.commons.chain.apps.example.CountCommand"/>
        </chain>

        <!-- Bar Command -->
        <chain name="/bar">
            <command attribute="pathinfoBarCount" className="org.apache.commons.chain.apps.example.CountCommand"/>
        </chain>

    </catalog>

    <!-- Catalog for "Request Parameter" example -->
    <catalog name="reqparam">

        <!-- Command that maps a "Request Parameter" to Commands -->
        <chain name="COMMAND_MAPPER">
            <command catalogName="reqparam"  className="org.apache.commons.chain.web.servlet.RequestParameterMapper"/>
            <command forward="/reqparam.jsp" className="org.apache.commons.chain.apps.example.ForwardCommand"/>
        </chain>

        <!-- Foo Command -->
        <chain name="foo">
            <command attribute="reqparamFooCount" className="org.apache.commons.chain.apps.example.CountCommand"/>
        </chain>

        <!-- Bar Command -->
        <chain name="bar">
            <command attribute="reqparamBarCount" className="org.apache.commons.chain.apps.example.CountCommand"/>
        </chain>

    </catalog>

</catalogs>


创建相应的Java类 Catalog.java:

import java.util.ArrayList;
import java.util.List;



public class Catalog {

    /**
     * @uml.property  name="name"
     */
    private String name;

    /**
     * Getter of the property <tt>name</tt>
     * @return  Returns the name.
     * @uml.property  name="name"
     */
    public String getName() {
        return name;
    }

    /**
     * Setter of the property <tt>name</tt>
     * @param name  The name to set.
     * @uml.property  name="name"
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @uml.property  name="chains"
     */
    
    private List<Chain> chains=new ArrayList<Chain>();
    
    public void addChains(Chain chain)
    {
        this.chains.add(chain);
    }

}


Chain.java:

import java.util.ArrayList;
import java.util.List;



public class Chain {

    /**
     * @uml.property  name="name"
     */
    private String name;

    /**
     * Getter of the property <tt>name</tt>
     * @return  Returns the name.
     * @uml.property  name="name"
     */
    public String getName() {
        return name;
    }

    /**
     * Setter of the property <tt>name</tt>
     * @param name  The name to set.
     * @uml.property  name="name"
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @uml.property  name="commands"
     */
    private List<Command> commands=new ArrayList<Command>();
    

    /**
     * Setter of the property <tt>commands</tt>
     * @param commands  The commands to set.
     * @uml.property  name="commands"
     */
    public void addCommands(Command command) {
        this.commands.add(command);
    }

}


Command.java:

import java.util.ArrayList;
import java.util.List;



public class Chain {

    /**
     * @uml.property  name="name"
     */
    private String name;

    /**
     * Getter of the property <tt>name</tt>
     * @return  Returns the name.
     * @uml.property  name="name"
     */
    public String getName() {
        return name;
    }

    /**
     * Setter of the property <tt>name</tt>
     * @param name  The name to set.
     * @uml.property  name="name"
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @uml.property  name="commands"
     */
    private List<Command> commands=new ArrayList<Command>();
    
    /**
     * Getter of the property <tt>commands</tt>
     * @return  Returns the commands.
     * @uml.property  name="commands"
     */
    public List getCommands() {
        return commands;
    }

    /**
     * Setter of the property <tt>commands</tt>
     * @param commands  The commands to set.
     * @uml.property  name="commands"
     */
    public void addCommands(Command command) {
        this.commands.add(command);
    }

}

任务3 –创建 摘要程序 规则 digester-catalog-rules.xml

<?xml version="1.0"?>
<!DOCTYPE digester-rules PUBLIC
  "-//Apache Commons //DTD digester-rules XML V1.0//EN"
  "http://commons.apache.org/digester/dtds/digester-rules-3.0.dtd">
<digester-rules>

  <pattern value="catalogs/catalog">

    <object-create-rule classname="Catalog"/>



    <set-properties-rule/>

   <!-- comment :

  <bean-property-setter-rule pattern="name"/>  

use as shown above  if say  <catalog><name>reparam</name> </catalog> instead of <catalog name="reparam"> </catalog>

-->


    

    <!-- Nested Pattern for Characters -->

    <pattern value="chain">

      <object-create-rule classname="Chain"/>


      <set-properties-rule/>                 
                     

 <!-- Nested Pattern for Characters -->
                             <pattern value="command">

      <object-create-rule classname="Command"/>


                           <set-properties-rule/>

                          <set-next-rule methodname="addCommands"  paramtype="Command"/>
</pattern>
      <set-next-rule methodname="addChains" paramtype="Chain"/>
</pattern>
    <set-next-rule methodname="add" paramtype="Catalog"/>
</pattern>
</digester-rules>

任务4 –加载xml数据的客户端程序

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import org.apache.commons.digester3.Digester;
import org.apache.commons.digester3.binder.DigesterLoader;
import org.apache.commons.digester3.xmlrules.FromXmlRulesModule;
import org.xml.sax.SAXException;

import java.util.ArrayList;
import java.util.List;

public class runProgram {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        
        // Create an instance of the Digester from the XML rule set



        DigesterLoader  digesterLoader = DigesterLoader.newLoader(new FromXmlRulesModule() {
            
            @Override
            protected void loadRules() {
                // TODO Auto-generated method stub
                loadXMLRules( getClass( ).getResource("/com/tatu/resources/digester-catalog-rules.xml"));

            }
        });
Digester digester = digesterLoader.newDigester();

List<Catalog> catalogs = new ArrayList<Catalog>();

        // Push a reference to the plays List on to the Stack

        digester.push(catalogs);



        // Parse the XML document

        InputStream input = Digester.class.getClass().getResourceAsStream("/com/tatu/resources/chain-config.xml");

        try {
            Object root = digester.parse(input);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

做完了 因此,已经用xml数据加载了catalogs对象。
上述解决方案要注意的几点:

  1. object-create-rule创建一个对象
  2. 其余规则如其名称所暗示的那样简单明了:object-create-rule创建一个新实例,set-properties-rule从xml属性(如目录元素的name属性)设置对象的属性,而bean-property-setter-rule设置嵌套xml元素中对象的属性,例如<catalog> <name> reparam </ name> </ catalog>而不是<catalog name ='reparam'> </ catalog>
  3. set-next-rule :(用于递归)set-next-rulerule移至下一个目录,链和命令标签。 您还指定了每种情况下要调用的方法,该方法会将对象添加到父类中定义的集合中,例如:<set-next-rule methodname ='addCommands'paramtype ='Command'/>,此处为addCommands()方法将命令对象添加到父链类中定义的命令收集对象。
  4. 您需要新的自定义规则,请创建自摘要器Rule类派生的自己的Rule类。

有任何问题,请发表您的评论。

再想一想,您不希望在xml文件和java类之间出现所有这些问题。 猜猜怎么着,有个避免的办法。 但是除非您着急,否则我不喜欢这个把戏。 但是,每次使用快捷方式时,都必须失去灵活性。

技巧是使用Apache Betwixt。 记住要使用Betwixt,您需要使用Apache Digester 2.1。 有关更多信息,请访问apache Betwixt网站。

使用Betwixt BeanWriter将Java Bean写入文件,然后使用BeanReader从该文件读取。 从BeanWriter生成文件后,就可以更改值,并在BeanReader中加载该文件。 (需要在此处省略配置之间的映射)

祝您编程愉快,别忘了分享!

参考:我的软件开发博客博客上,来自我们的JCG合作伙伴 Bijay Deo的示例中使用Apache Digester-轻松进行配置


翻译自: https://www.javacodegeeks.com/2012/09/apache-digester-example-make-easy.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值