In Java programming, most of the configuration files are organized using XML files. So the tools for working with XML in the Java language are particularly numerous.
There are several ways to parse XML in Java, which should all be known. On the basis of these analytic techniques, several excellent object/xml related techniques have been developed, such as the object binding technology (JAXB), and then the digester. Here's a quick look at Digester technology.
If the use of Digester the most superb application, not Tomcat. Several of the important configuration files in Tomcat, such as Server.xml, Web. XML, Context.xml, use digester to accomplish the transformation of a Java object.
Digester only need to set up the corresponding processing rules, you can get the desired object structure. Its greatest advantage is the ability to customize various processing rules. However, if you do not understand digester design principles, then you will only use Digester to provide you with a few rules.
digester Example
Java Object Design:
Packagecom.fjn.frame.digester.list; Public classXxobject {PrivateString ID; PrivateString name; Private intnum; PublicString getId () {returnID; } Public voidsetId (String id) { This. ID =ID; } PublicString GetName () {returnname; } Public voidsetName (String name) { This. Name =name; } Public intGetnum () {returnnum; } Public voidSetnum (intnum) { This. num =num; } @Override PublicString toString () {return"ID:" + ID + "\tname:" + name + "\tnum:" +num; }}
This class does not have any meaning, just I write casually.
A simple XML file:
<?XML version= "1.0" encoding= "UTF-8"?><xxobjects> <XxobjectID= "id001"name= "Hello1"Num= "1" /> <XxobjectID= "id002"name= "Hello2"Num= "2" /> <XxobjectID= "id003"name= "Hello3"Num= "3" /> <XxobjectID= "id004"name= "Hello4"Num= "4" /> <XxobjectID= "id005"name= "Hello5"Num= "5" /> <XxobjectID= "id006"name= "Hello6"Num= "6" /> <XxobjectID= "id007"name= "Hello7"Num= "7" /> <XxobjectID= "id008"name= "Hello8"Num= "8" /> <XxobjectID= "id009"name= "Hello9"Num= "9" /></xxobjects>
the next task is to convert the XML file into a collection of objects.
Packagecom.fjn.frame.digester.list;Importjava.io.IOException;Importjava.util.List;ImportJavax.xml.parsers.FactoryConfigurationError;Importjavax.xml.parsers.ParserConfigurationException;ImportJavax.xml.parsers.SAXParser;Importjavax.xml.parsers.SAXParserFactory;ImportOrg.apache.commons.digester3.Digester;Importorg.junit.Test;Importorg.xml.sax.SAXException; Public classconvertor {@Test Public voidTest ()throwsparserconfigurationexception, Saxexception, Factoryconfigurationerror, IOException {SAXParser pars ER=saxparserfactory.newinstance (). Newsaxparser (); Digester digester=Newdigester (parser); Digester.addobjectcreate ("Xxobjects", "Java.util.LinkedList"); Digester.addobjectcreate ("Xxobjects/xxobject", "Com.fjn.frame.digester.list.XxObject"); Digester.addsetproperties ("Xxobjects/xxobject"); //digester.addsetnext ("Xxobjects/xxobject", "Add");Digester.addrule ("Xxobjects/xxobject",Newaddtocollectionrule ()); List<XxObject> ret = Digester.parse (convertor.class. getResourceAsStream ("Xxobjects.xml")); for(Xxobject obj:ret) {System.out.println (obj); } }}
The Addtocollectionrule rule is my custom rule:
Packagecom.fjn.frame.digester.list;Importjava.util.Collection;ImportOrg.apache.commons.digester3.Rule;Importorg.xml.sax.Attributes; Public classAddtocollectionruleextendsRule {@Override Public voidbegin (String namespace, string name, Attributes Attributes)throwsException {Object top= This. Getdigester (). Peek (); Object o= This. Getdigester (). Peek (1); if(O! =NULL) {Collection colls=(Collection) o; System.out.println (top); Colls.add (top); } }}
program Run Result:
Id:id001name:hello1num:1id:id002name:hello2num:2id:id003name:hello3num:3id:id004name:hello4num:4id:id005name: Hello5num:5id:id006name:hello6num:6id:id007name:hello7num:7id:id008name:hello8num:8id:id009name:hello9num:9i D:id001name:hello1num:1id:id002name:hello2num:2id:id003name:hello3num:3id:id004name:hello4num:4id:id005name: Hello5num:5id:id006name:hello6num:6id:id007name:hello7num:7id:id008name:hello8num:8id:id009name:hello9num:9
using Digester to convert XML to Java objects is as simple as that.
It's so easy to use, how does it work?
Digester Design principle
If you're using DOM parsing, I'm sure that as long as you understand the DOM tree, you're sure to be able to do this easy task, which is why it's easier for the program to accept DOM parsing. But imagine what you would do if you were to convert an XML file into a Java object using Sax parsing.
Before I looked at the source code of Digester, I did this idea. Because of the way sax is parsed, the most we use should be startelement and endelement. Sax parsing is event-based, encounters a start element, executes the Startelement method, and encounters an end element to execute the EndElement method.
In general, an XML element corresponds to a Java object, and the attributes of the XML element correspond to the properties of the Java object. When an element is encountered, the object can be created based on the element name. Sets the properties of an object based on the attributes of the element. This is very simple, but after the end of an element, that is, after the creation of the object is done, how to store it? Can not be resolved to complete, generated a lot of objects, I can not get one, that the interpretation of what is the use of it. Consider a complex XML, such as Tomcat's Server.xml file, Server\service\engine, and so on, where objects are nested, and when an object Service is created, how do you set it to Server? After creating an object engine, how do you set it to service? To do this, it is necessary to use a data structure: Stack. If you can think of this place, digester you have learned 80%.
Java object in Startelement to create a merge stack in the EndElement complete all operations and out of the stack.
Example description
In the example above, when parsing to the root element, a linkedlist is created and then put into the stack. Because there is no end element, it will certainly be in the stack, and it is at the bottom. Then it's parsing each xxobject. When parsing the xxobject element, there are 3 operations, which are performed sequentially:
1) Create the Xxobject object. Into the stack, then this object must be at the top of the stack.
2) Set the properties. Digester uses the Beanutils tool to complete the setting of the property, so the Java class needs getter and setter at design time.
3) Call my custom addtocollection rule. It is also very simple to execute this rule, get the current object (the top element of the stack), and then remove the second element from the top of the stack, which is linkedlist. You can then add it to the collection.
4) EndElement, object out of the stack, only the LinkedList object is left in the stack.
Finally, it encounters the end of Xxobejcts, which is the bottom of the stack at the end of the resolution. What is returned is the bottom object. So the result is a list.
The addtocollection rule I've customized is just a way to explain how digester works and how to use custom rules. In fact, like the usual rules of this, Digester has been defined well, setnetrule.
Here, the main content of this article has been finished. As for how to use the various rule in digester, you need to understand it on your own.
A class diagram is attached below:
Digester:a Java Object Builder based XML