In the previous articleArticle, We willJakarta commonsThe components are divided into five categories, and the Web class and other classes are introduced. This article introduces the XML class and the packaging class. The last article will introduce the tool class. Note that commons does not perform this classification. The classification here is purely for the convenience of the Organization. I. Packaging This type includes two components: codec and Modeler. 1.1 Codec ■ Overview: provides common encoder and decoder. ■ Official resources:Home Page,Binary,Source code. ■ When to apply: when you need the standard implementation of base64 and Hex Encoding functions. ■ Example application: codecdemo. java. Requires that classpath must contain a commons-codec-1.1.jar. ■ Note: The classes in codec are divided into two packages, one of which implements the commonly used base64 and Hex Encoding mechanisms, and the other is the language and speech encoding. The usage of the two packages is similar. Given that language and Speech Encoding are not very common, the first package is introduced below. Base64 encoding is mainly used for email transmission. Define the MIME file transferRFCIt specifies the Base 64 encoding so that any binary data can be converted into printable ASCII character sets for secure transmission. For example, if you want to transmit a graphic file via email, the email client will use base64 encoding to convert the binary data of the graphic file into ASCII code. In base64 encoding, every three 8-bit bytes are encoded into a 4-character group, each of which contains 6 of the original 24-bit, the size of the encoded string is 1.3 times that of the original one, and the "=" symbol is appended to the end of the file. In addition to mime files, base64 encoding is also used for the "user: Password" string of the HTTP Authentication Header in the basic authentication mechanism. Base64 is quite simple to use. The two main static methods are base64.encodebase64 (byte [] bytearray), which is used to encode the specified content in the byte array; base64.decodebase64 (byte [] bytearray) is used to perform base64 decoding on the specified content in the byte array. In addition, base64 also has a static method base64.isarraybytebase64 (byte [] bytearray), which is used to check whether the specified byte array can pass the base64 test (that is, whether it contains base64-encoded data, as mentioned above, base64 encoding only contains printable ASCII characters ).
Byte [] encodedbytes = base64.encodebase64 (teststring. getbytes (); string decodedstring = new string (base64.decodebase64 (encodedbytes); system. err. println ("\ '^ \' is a legal base64 character? "+ Base64.isarraybytebase64 (invalidbytes )); |
Hex Encoding/decoding is the conversion between byte data and the equivalent hexadecimal representation. The encoding and decoding process of Hex Encoding is similar to that of base64. 1.2 Modeler ■ Overview: according to the definition of the JMX (Java Management Extensions) specification, model mbean (managed bean) can be configured and instantiated. ■ Official resources:Home Page,Binary,SourceCode. ■ When to apply: When you want to create and manage model mbeans, you can use standard Management APIs to manage applications. ■ Example application: modelerdemo. Java, demomanagedbean. Java and mbeans-descriptors.xml. Require classpath to contain commons-modeler-1.0.jar, commons-logging.jar, commons-digester.jar, commons-collections.jar, commons-beanutils.jar, and Sun's JMX reference to implement jmxri. jar. ■ Note: The following instructions require readers to have a certain understanding of JMX. Managed Bean (mbean) is a type of association to applications.ProgramIs a type of abstraction for resources. Model mbean is a special mbean with highly dynamic and configurable features. However, this capability of model mbean comes at a cost, programmers need to set a large amount of metadata to tell JMX how to create model mbean. These metadata includes component attributes, operations, and other information. Modeler aims to reduce the workload of programmers to implement model mbean. It provides a set of functions to facilitate the processing of metadata information. In addition, modeler provides a registration tool and a basic model mbean. Modeler allows you to define metadata in the form of an XML file, which should comply with the DTD definition provided along with Modeler. Metadata information is used to create registration information at runtime. Registration Information is the central knowledge base of all model mbeans, which is actually equivalent to a factory that creates such beans. Next we will first create this XML file for a managed Bean (demomanagedbean. Demomanagedbean has a name attribute that can be read and written.
As you can see, this XML file provides a lot of information about managedbean, including its attributes, constructor, and its operations (but this example is not shown ), this is the so-called metadata information. If you want to extend the standard mbean (called basemodelmbean) provided along with modeler, you can specify the class name of model mbean in the form of attributes in the mbean element: . In the previous example, the standard model mbean simply passes all calls directly to the managedbean class. Next, we need to register the above information. Note that after the registration information is loaded through the description file, we use a static method to extract the formatted registration information:
// Create a registryregistry registry = NULL; try {URL url = modelerdemo. class. getresource ("mbeans-descriptors.xml"); inputstream stream = URL. openstream (); registry. loadregistry (Stream); stream. close (); Registry = registry. getregistry ();} catch (throwable t) {T. printstacktrace (system. out); system. exit (1 );} |
After the registry is created, we need to create a model mbean and register it with the default Management Server. In this way, any JMX client program can call the managed bean function through model mbean.
// Obtain the handle of a managed bean instance demomanagedbean mbean = new demomanagedbean (); // create a model mbean and register it with mbean server mbeanserver mserver = registry. getserver (); managedbean managed = registry. findmanagedbean ("managedbean"); try {modelmbean = managed. creatembean (mbean); string domain = mserver. getdefadomain domain (); objectname oname = new objectname (domain + ": TYPE = managedbean"); mserver. registermbean (modelmbean, oname);} catch (exception e) {system. err. println (E); system. exit (0);} Try {objectname name = new objectname (mserver. getdefadomain domain () + ": TYPE = managedbean"); modelmbeaninfo info = (modelmbeaninfo) mserver. getmbeaninfo (name); system. err. println ("classname =" + info. getclassname (); system. err. println ("Description =" + info. getdescription (); system. err. println ("mbeandescriptor =" + info. getmbeandescriptor (); system. err. println ("==== test ==="); system. err. println ("original name value:" + mserver. getattribute (name, "name"); mserver. setattribute (name, new attribute ("name", "Vikram"); system. err. println ("New Value of name:" + mserver. getattribute (name, "name");} catch (exception e) {system. err. println (E); system. exit (0 );} |
Although this example is relatively simple, it still clearly describes the convenience of using Modeler. It may be compared with creating a similar model mbean without using Modeler. Describing modelmbeaninfo using XML files is not only flexible and convenient, but also easy to expand, which is much better than writing such information manually. Ii. xml The XML class contains classes related to Java and XML technologies, including betwixt, digester, jelly, and jxpath. 2.1 betwixt ■ Overview: ing between XML and JavaBean. ■ Official resources:Home Page,Binary,Source code. ■ When to apply: When you want to implement XML and bean ing in a flexible way, you need a data binding framework. ■ Example application: betwixtdemo. Java, mortgage. Java, and mortgage. xml. Requires that classpath must contain a commons-betwixt-1.0-alpha-1.jar, A commons-logging.jar, A commons-beanutils.jar, A commons-collections.jar, and a commons-digester.jar. ■ Note: If you used to bind data with Castor, you will certainly appreciate the flexibility of betwixt. Castor is suitable for performing conversions between beans and XML based on a schema. But if you only want to perform conversions between data and XML, the best choice is betwixt. Betwixt is flexible and can easily output data into readable XML. Betwixt is quite simple to use. If you want to convert a bean to XML, first create a beanwriter instance, set its attributes, and then output the bean. If you want to convert XML to bean, first create a beanreader instance, set its properties and use digester to perform the conversion. Convert bean to XML:
// Use betwixt to convert beans into XML instances that must have beanwriter. // Because beanwriter constructor requires a writer object, // we start from creating a stringwriter outputwriter = new stringwriter (); // note that the output result is not in good format, so you need to write the following content at the start position: outputwriter. write ("<? XML version = '1. 0'?> "); // Create a beanwriterbeanwriter writer = new beanwriter (outputwriter); // you can set various attributes of the writer. // Write ID is prohibited in the first row. // The second row allows formatting of the output writer. setwriteids (false); writer. enableprettyprint (); // create a bean and output it mortgage = new mortgage (6.5f, 25); // write the output result to the output device try {writer. write ("mortgage", mortgage); system. err. println (outputwriter. tostring ();} catch (exception e) {system. err. println (E);} converts XML to Bean: // use betwixt to read XML data and create // bean based on this. The beanreader class must be used. Note that the beanreader class extends the digester class of the // digester package. Beanreader reader = new beanreader (); // registration class try {reader. registerbeanclass (mortgage. Class); // parse it... Mortgage mortgageconverted = (mortgage) reader. parse (new file ("mortgage. XML "); // check whether the converted mortgage contains the value system in the file. err. println ("rate:" + mortgageconverted. getrate () + ", years:" + mortgageconverted. getyears ();} catch (exception ee) {ee. printstacktrace ();} |
Note: When Using beanreader to register a class, if the top-level element name is different from the class name, you must use another method to register and specify an accurate path, such as reader. registerbeanclass ("toplevelelementname", mortgage. class ). 2.2 Digester ■ Overview: Provides friendly and event-driven advanced XML document processing APIs. ■ Official resources:Home Page,Binary,Source code. ■ When to apply: When you want to process an XML document and want to perform certain operations according to a set of rules triggered by a specific mode in the XML document. ■ Example applications: digesterdemo. Java, employee. Java, company. Java, rules. XML, and company. xml. Requires that classpath must contain a commons-digester.jar, A commons-logging.jar, A commons-beanutils.jar, and a commons-collections.jar. ■ Note: Digester is most useful when parsing configuration files. In fact, digester was initially developed to read the struts configuration file and then moved to the commons package. Digester is a powerful pattern matching tool that allows developers to process XML documents at a higher level than the sax or DOM APIs. When a specific pattern is found (or the pattern cannot be found) can trigger a group of rules. The basic idea of using digester is: first create a digester instance, use it to register a series of patterns and rules, and finally pass the XML document to it. After that, digester will analyze the XML document and trigger rules according to the registration order. If an element in the XML document matches more than one rule, all rules are triggered in order of registration. Digester has 12 predefined rules. Do you want to call a method when a specific mode is found in the XML document? It's easy to use the predefined callmethodrule! In addition, you do not have to use predefined rules. digester allows you to define your own rules by extending the rule class. When specifying the mode, the element must be given with an absolute name. For example, the root element is directly specified by name, and the next element is extracted by the "/" symbol. For example, if company is the root element, Company/employee is the pattern that matches one of its child elements. Digester allows wildcard characters. For example, */employee matches all the employee elements in the XML document. When a matching mode is found, four callback methods are called in the rule associated with the matching mode, which are: Begin, end, body, and finish. The time when these methods are called is shown in its name. For example, the time when the begin and end methods are called is when the start and end tags of the elements are met, body is called when the text in the matching mode is encountered, and finish is called after all the matching modes are processed. Finally, the pattern can be specified within an external rule XML document (using the digester-rules.dtd), or within the code, the first approach is used below, as this approach is more commonly used. Before using digester, you must create two XML documents. The first is the data or configuration file, which is the file for applying rules to it. The following is an example (company. XML)
<? XML version = "1.0" encoding = "gb2312"?> <Company> <Name> my company </Name> <address> Zhejiang, China </address> <employee> <Name> Sun Wukong </Name> <employeeno> 10000 </employeeno> </employee> <Name> </Name> <employeeno> 10001 </employeeno> </employee> </company> |
The second file is the rule file rules. xml. Rules. xml tells digester what to look for in company. xml and what to perform after finding it:
What does this file mean? The first rule, <Object-create-Rule pattern = "company" classname = "company"/> tells digester that if the mode company is met, the object-create-rule must be followed, that is, to create an instance of the class! What kind of instance is to be created? The classname = "company" attribute specifies the class name. Therefore, when parsing company. XML, we have an instance of the company class created by digester when the top-level company elements are met and the execution of the object-create-rule is completed. Now it is not that difficult to understand the call-method-rule, here, the call-method-rule function calls a method in the company/name or company/address mode (the method name is specified through the methodname attribute ). The last pattern matching is worth noting that it embeds rules into the matching pattern. The two rules and modes are accepted by digester. You can choose either of them based on your needs. In this example, when the rule defined in the pattern encounters the company/employee pattern, an object of the employee class is created and its attributes are set, finally, use set-next-rule to add the employee to the top-level company. After the preceding two XML files are created, you only need to use two lines of code to call digester:
Digester = digesterloader. createdigester (rules. tourl (); Company = (company) digester. parse (inputxmlfile ); |
The first line of code loads the rule file and creates a digester. The second line of code uses the digester to apply the rule. See the complete source code of digesterdemo. Java provided later in this article. 2.3 jelly ■ Overview: a Java and XML-based scripting language. ■ Official resources:Home Page,Binary,Source code. ■ When to apply: Simply put, when you want a flexible and scalable XML script tool. ■ Example applications: jellydemo. Java, jellydemo. XML, and trivialtag. java. Require that the classpath must have a commons-jelly-1.0-dev.jar, dom4j. jar, commons-logging.jar, commons-beanutils.jar, and commons-collections.jar. ■ Note: It is not easy to understand what jelly is and what role it plays. Jelly tries to provide a general XML script engine, which can be extended by developers through custom actions and tags. Elements in XML documents can be mapped to JavaBean, the attributes of XML elements are mapped to the attributes of JavaBean. In a sense, Jelly is a tool that combines betwixt and digester, but jelly is more powerful and has better scalability. A jelly system consists of multiple components. The first component is the jelly script, which is an XML document parsed by the jelly engine. The parsed XML document elements are bound to the jelly tag for dynamic processing. The second component is the jelly tag, which is a JavaBean that implements the jelly tag interface. Any jelly tag can implement the dotag method, this dotag method is used when the Script Engine encounters a specific element in the XML document. Jelly uses this mechanism to implement dynamic script processing capabilities. In a sense, it is a bit similar to digester's working mechanism. Jelly carries many predefined tags, some of which provide support for the core jelly, and others are used to provide support for parsing, looping, and conditional Execution Code. In addition, Jelly also provides extensive support for ant tasks. To use jelly in a Java application, you must first create a jellycontext instance, for example, jellycontext context = new jellycontext ();. We can regard the jellycontext object as a runtime environment for compiling and running jelly scripts. With jellycontext, you can run the jelly script. The jellycontext output is actually an xmloutput class instance: context. runscript (new file ("jellydemo. xml"), output );. When creating a custom tag, we can either overwrite the dotag method mentioned above (as shown in the following example) or provide an execution method, such as invoke () or run ():
Public void dotag (xmloutput output) throws exception {// Add the operation to be executed here, // such as setting attributes and accessing the file system... This. intprop = 3 ;} |
The following provides an example of an XML file that defines the jelly script:
<J: Jelly xmlns: J = "JELLY: Core" xmlns: Define = "JELLY: Define" xmlns: TR = "trivialtag"> <define: taglib uri = "trivialtag"> <define: jellybean name = "trivial" classname = "trivialtag"/> </define: taglib> <TR: trivial intprop = "1" stringprop = "ball"> Hello World </TR: trivial> </J: Jelly> |
This example uses the jelly: define and jelly: Core tags, and a trivialtag tag. When the trivial tag instance is encountered, Jelly creates the corresponding JavaBean instance and executes the dotag method (or a call method such as run or invoke ). Jelly has many other functions that can be run directly from the command line or ant script, or embedded into the application code. For more information, see the jelly documentation. 2.4 jxpath ■ Overview: The XPath interpreter in Java. ■ Official resources:Home Page,Binary,Source code. ■ When to apply: When you want to apply XPath queries to structures consisting of JavaBean, Dom, or other objects. ■ Example application: jxpathdemo. Java, Book. Java, and author. java. Requires that classpath must contain a commons-jxpath-1.1.jar. ■ Note: The following description requires that you have basic XPath knowledge. XPath is a language used to query XML documents. jxpath applies the same concept to queries of other Java objects, such as JavaBean, collection, array, and map. Jxpathcontext is the core class in jxpath. It uses a factory method to locate and create a context instance. With this mechanism, developers can insert a new jxpath implementation if necessary. To use jxpathcontext, simply pass a JavaBean, collection, or map to it, for example, jxpathcontext context = jxpathcontext. newcontext (book );. Use jxpathcontext to execute many tasks. For example, you can also set access or nested attributes:
System. err. println (context. getvalue ("title"); system. err. println (context. getvalue ("author/authorid"); context. setvalue ("author/authorid", "1001 "); |
Jxpath can also be used to search for other types of objects. However, the methods for creating context objects are the same. The static methods described above are used to obtain a new context and pass in the objects to be queried. Conclusion: the introduction of the packaging class and XML class ends here. In the next and last articles, we will learn about tool packages. Download the code here:Jakartacommons2code.zip.
|