使用Apache Digester相当容易将XML文档转换为相应的Java bean对象层次结构。 请参阅下面的“摘要”。
Digester引入了三个重要概念:
- 元素匹配模式
- 处理规则
- 对象堆栈。
元素匹配模式将 XML元素与处理规则相关联。
范例:
你有什么:
- Java类
- 包含数据的XML文件
您有Java类和相应的xml文件。 您希望从xml数据创建Java类实例。
您需要编写哪些额外的代码。
分步任务:
- 在类路径中添加Apache Digester 3 jar文件,Commons日志jar,Beanutils jar,cglib jar
- 如果没有Java类,则为相应的xml文件创建Java类。或者,如果没有xml文件,则根据java类创建。注-属性名称,xml和java类中的层次结构应匹配,否则,需要在此处未提及的摘要XML规则中提供映射。
- 如以下示例中所述,创建摘要规则XML文件
- 用几行来从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 setDigesterLoader digesterLoader = DigesterLoader.newLoader(new FromXmlRulesModule() {@Overrideprotected void loadRules() {// TODO Auto-generated method stubloadXMLRules( 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 Stackdigester.push(catalogs);// Parse the XML documentInputStream input = Digester.class.getClass().getResourceAsStream("/com/tatu/resources/chain-config.xml");try {Object root = digester.parse(input);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SAXException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
做完了 因此,已经用xml数据加载了catalogs对象。
上述解决方案要注意的几点:
- object-create-rule创建一个对象
- 其余规则如其名称所暗示的那样简单明了:object-create-rule创建一个新实例,set-properties-rule从xml属性(如目录元素的name属性)设置对象的属性,而bean-property-setter-rule设置嵌套xml元素中对象的属性,例如<catalog> <name> reparam </ name> </ catalog>而不是<catalog name ='reparam'> </ catalog>
- – set-next-rule :(用于递归)set-next-rulerule移至下一个目录,链和命令标签。 您还指定了每种情况下要调用的方法,该方法会将对象添加到父类中定义的集合中,例如:<set-next-rule methodname ='addCommands'paramtype ='Command'/>,此处为addCommands()方法将命令对象添加到父链类中定义的命令收集对象。
- 您需要新的自定义规则,请创建自摘要器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