Jakarta commons: clever use of classes and components 3

Source: Internet
Author: User
Tags map class
Jakarta commons: clever use of classes and components 3
2003-10-10 Browsing times: 1175

In the first article of this series, we divided the components contained in the Commons project into five categories, including Web and other categories. The second article deals with XML and packaging. This is the last article, discussing the components of the tool class. Note that commons does not perform this classification. The classification here is purely for the sake of illustration and organization convenience.

Tools include beanutils,

Logging, DBCP, pool, and

Validator components.

1. beanutils

■ Overview: provides tools for dynamic operations on JavaBean.

■ Official resources:Home Page,Binary,Source code.

■ When applicable: When you need to dynamically access the JavaBean, but for the compiled accessor and

When modifier knows nothing about it. The dynamically accessed JavaBean must follow the JavaBeans

Specification defines the naming design specifications.

■ Example application: beanutilsdemo. Java, applayer1bean. Java,

Applayer2bean. Java, subbean. java. Requires that classpath must contain a commons-beanutils.jar,

Commons-logging.jar and commons-collections.jar.

■ Note:

In the dynamic Java application design environment, we may not be able to know the various set and get methods of the JavaBean in advance. Even if you already know the names of these methods, writing the setxxx or getxxx method in sequence for each attribute of bean is also very troublesome. Consider this situation: Several beans that are almost identical are transferred from one layer of the application to another. Will you call bean1.setxxx (bean2.getxxx () for each attribute? Although you can do this, you do not have to do this because you can let beanutils do these tedious operations for you! Beanutils can help developers dynamically create, modify, and copy JavaBean.

Beanutils can operate JavaBean that meets the following conditions:

(1) JavaBean must provide a constructor without parameters.

(2) attributes of JavaBean must be accessible and modified using the getxxx and setxxx methods. For Boolean attributes, isxxx and setxxx are also allowed. JavaBean attributes can be read-only or write-only. That is to say, only set or get methods of attributes can be provided.

(3) If you do not use the traditional naming method (get and set) and use other methods to name the accessor and modifier of the JavaBean, you must declare this through the beaninfo class associated with the JavaBean.

The following is a simple example.

To obtain and set simple properties of JavaBean, use propertyutils.

Getsimpleproperty (Object bean, string name) and propertyutils.

Setsimpleproperty (Object bean, string name, object Value) method. As shown in the following example, applayer1bean. Java and applayer2bean. Java define two Java containers for testing.


             PropertyUtils.setSimpleProperty(app1Bean,"intProp1",  new Integer(10));System.err.println("App1LayerBean, stringProp1: " +    PropertyUtils.getSimpleProperty(app1Bean,    "stringProp1"));

Since we can directly call the bean method (app1bean. getstringprop1 () or

App1bean. setintprop1 (10) to obtain or set bean attributes. Why do we need to use the setsimpleproperty and getsimpleproperty methods? This is because we do not necessarily know the name of the JavaBean attribute in advance, so we do not necessarily know which methods should be called to obtain/set the corresponding attribute. The names of these attributes may come from variables set by other processes or external applications. Therefore, once you understand the name of the JavaBean attribute and save it to a variable, you can pass the variable to propertyutils, you no longer need to rely on other developers to get the correct method name in advance.

What if the JavaBean attribute is not a simple data type? For example, the JavaBean attribute may be a collection or a map. In this case, use propertyutils. getindexedproperty or propertyutils. getmappedproperty. For set class attribute values, we must specify an index value to specify the position of the value to be extracted or set in the set. For map class attributes, we must specify a key, indicates the value to be extracted. The following are two examples:


             Propertyutils. setindexedproperty (app1bean, "listprop1 [1]", "New String 1"); system. err. println ("app1layerbean, listprop1 [1]:" + propertyutils. getindexedproperty (app1bean, "listprop1 [1]");

Note that for indexed attributes, the index value is passed through square brackets. For example, in the above example, we set the value of Index 1 in the list of JavaBean (app1bean) to "New String 1 ", the subsequent code line extracts the same value from Index 1. Another way to achieve the same goal is to use propertyutils. setindexedproperty (Object bean, string name, int index, object value) and propertyutils. the getindexedproperty (Object bean, string name, int index) method, in which the index value is passed as a parameter of the method. Similar methods are available for map attributes. You only need to use keys instead of indexes to obtain or set the specified values.

Finally, the bean attribute may also be a bean. So how can we get or set the attribute beans that belong to the main bean in the form of attributes? You only need to use the propertyutils. getnestedproperty (Object bean, string name) and propertyutils. setnestedproperty (Object bean, string name, object Value) methods. An example is provided below.


             // Access and set the nested property propertyutils. setnestedproperty (app1bean, "subbean. stringprop", "information from subbean, set through setnestedproperty. "); System. Err. println (propertyutils. getnestedproperty (app1bean," subbean. stringprop "));

The preceding example shows that the attributes of the subordinate bean are accessed by a period symbol.

The preceding access attributes can be used in combination, and the nested depth is not limited. The following two methods are used: propertyutils. getproperty (Object bean, string name) and propertyutils. setproperty (Object bean, string name, object value ). For example, propertyutils. setproperty (app1bean, "subbean. listprop [0]", "attribute value ");.

In this example, the nested bean object and the Indexable attribute are combined for access.

Beanutils is often used to Dynamically Access Request Parameters in Web applications. In fact, beanutils triggers the idea of dynamically converting request parameters into system JavaBean in the struts project: using code to convert user-filled forms into a map, the parameter name is changed to the key in map, and the value of the parameter is derived from the data entered by the user in the form, and then a simple beanutils. populate calls to convert these values into a system bean.

Finally, beanutils provides a one-step method to copy data from one bean to another:


             // Copy the data of app1bean to app2beanbeanutils. copyproperties (app2bean, app1bean );

Beanutils also has some practical methods that are not mentioned here. Don't worry, though. beanutils is one of the more comprehensive components in commons documentation. We recommend that you refer to the javadoc documentation in the beanutils package to learn more about other methods.

Ii. Logging

■ Overview: A code library that encapsulates many popular log tools and provides unified Log Access interfaces.

■ Official resources:Home Page,Binary,Source code.

■ When to apply: when your application requires more than one log tool, or is expected to have such a need in the future.

■ Example application: loggingdemo. Java, commons-logging.properties. The classpath must contain

Commons-logging.jar, sometimes also need log4j. jar.

■ Note:

Logging allows us to debug and track the behavior and status of an application at any time. Logging is an indispensable part of any large-scale application. Therefore, there are already many third-party logging tools that allow developers to write their own logging APIs. In fact, even JDK has a constructed logging API. Since there are already so many options (log4j, JDK, logkit, and so on), we can always find the ready-made API that best suits our application requirements.

However, exceptions may also occur. For example, a familiar logging API cannot be compatible with the current application, either due to a rigid rule or the application architecture. The logging component of the Commons project encapsulates the logging function into a set of standard APIs, but its underlying implementation can be modified and changed at will. Developers use this API to execute the commands that record log information. The API decides to pass these commands to appropriate underlying handles. Therefore, for developers, the logging component is neutral for any specific underlying implementation.

If you are familiar with log4j, there should be no problems using the commons logging API. Even if you are not familiar with log4j, as long as you know that logging must be used to import two classes and create a static log instance, the code for this operation is shown below:


             import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;public class LoggingDemo {    private static Log log = LogFactory.getLog    (LoggingDemo.class);    // ...}

It is necessary to describe in detail what happened when logfactory. getlog () is called. Calling this function starts a discovery process, that is, to find the implementation of the required underlying logging function. The specific discovery process is listed below. Note that no matter how the underlying log tool finds it, it must be a class that implements the log interface and must be in classpath. The commons logging API directly provides support for the following underlying logging tools: jdk14logger, log4jlogger, logkitlogger, and nooplogger (directly discarding all log information), and a simplelog.

(1) commons logging first looks for a commons-logging.properties file in classpath. This attribute file must at least define the org. Apache. commons. Logging. Log attribute. Its value should be the complete qualified name implemented by any of the preceding log interfaces.

(2) If the above step fails, the logging of commons will then check the system attribute org. Apache. commons. Logging. log.

(3) If the org. Apache. commons. Logging. Log System attribute cannot be found, logging searches for the log4j class in classpath. If logging is found, it is assumed that the application uses log4j. However, the log4j attributes must be correctly configured through the log4j. properties file.

(4) If no appropriate logging API can be found for the above search, but the application is running on JRE 1.4 or later, the logging function of JRE 1.4 is used by default.

Finally, if all the above operations fail, the application will use the built-in simplelog. Simplelog directly outputs all log information to system. Err.

After obtaining the appropriate underlying logging tool, you can start to record the log information. As a standard API, commons

The main advantage of the logging API is that an abstraction layer is established based on the underlying Log Mechanism and calls are converted into log record commands related to specific implementations through the abstraction layer.

The sample program provided in this article will output a prompt to tell you which underlying log tool is currently in use. Run this program in different environment configurations. For example, if you run this program without specifying any attributes

Jdk14logger; then specify the system property-Jorg. Apache. commons. Logging. log = org. Apache. commons.

Logging. impl. simplelog then runs the program, and the logging tool will be simplelog; finally, put the log4j class into classpath, as long as the log4j log4j is set correctly. properties configuration file to obtain the information output by log4jlogger.

Iii. Pool

■ Overview: the code library used to manage the object pool.

■ Official resources:Home Page,Binary,Source code.

■ When applicable: When you need to manage an object instance pool.

■ Example applications: pooldemo. Java and myobjectfactory. java. The classpath must contain

Commons-pool.jar and commons-collections.jar. ■ Note:

The pool component defines a set of interfaces for the object pool. It also provides several common object pool implementations and some basic classes that help developers create their own object pools.

For most developers, the object pool should not be a new concept. Maybe many readers have used the database connection pool when accessing the database, and the object pool concept is similar. The object pool allows developers to create a group of objects in the buffer (Object creation can be completed through the application configuration file or in the application startup phase ), when an application needs to use an object, it can quickly get a response. If the application no longer needs an object, it still returns the object to the buffer pool and extracts it from the buffer pool the next time it needs to use the object.

The pool component allows us to create an object (Instance) pool, but it does not limit the use of a specific implementation. The pool component itself provides several implementations, and we can also create our own implementations if necessary.

The pool component contains three basic classes: objectpool, which is an interface for defining and maintaining the object pool; objectpoolfactory, which is responsible for creating the objectpool instance; and poolableobjectfacotry, it defines a set of lifecycle methods for instances used within the objectpool.

As mentioned above, the pool component contains several common implementations, one of which is genericobjectpool. The following uses an instance to see its usage.

① Create a poolableobjectfactory. This factory class defines how objects are created, removed, and verified.


             Import Org. apache. commons. pool. poolableobjectfactory; public class myobjectfactory implements poolableobjectfactory {Private Static int counter; // return a new string public object makeobject () {return string. valueof (counter ++);} public void destroyobject (Object OBJ) {} public Boolean validateobject (Object OBJ) {return true;} public void activateobject (Object OBJ) {} public void passivateobject (Object OBJ ){}}

In this example, a pool of string objects with an increasing serial number is created. The verification operation (validateobject) always returns true.

② Use poolableobjectfactory to create a genericobjectpool, and use the default values for options such as maxactive and maxidle.


             GenericObjectPool pool = new GenericObjectPool (new MyObjectFactory());

③ Borrow an object from the object pool.


             System.err.println("Borrowed: " + pool.borrowObject());

④ Return the object to the object pool.


             pool.returnObject("0");

The status of the Object pool can be known in multiple ways, for example:


             // How many objects have been activated (borrowed )? System. Err. println ("number of objects currently active:" + pool. getnumactive ());

The pooldemo. Java provided later in this article provides the complete source code.

  Iv. DBCP

■ Overview: database connection pool. Built on the pool component.

■ Official resources:Home Page,Binary,Source code.

■ When applicable: When you need to access a relational database.

■ Example application: dbcpdemo. java. Requires that the classpath must have a commons-dbcp.jar, A commons-pool.jar, and a commons-collections.jar. In addition, you must be able to access the database and configure the JDBC driver suitable for the database. The example application tests a MySQL database connection and the driver is MySQL JDBC driver. Note that running this program requires the overnight version of the binary file. The current official release lacks some required classes. Finally, when running this sample program, make sure that the system property (-djdbc. Drivers = com. MySQL. JDBC. Driver) has been set for the JDBC driver ).

■ Note:

DBCP is built on the pool component and provides a database connection buffer pool mechanism. Compared with conventional connection pools, the use of DBCP is a little more complex, because its idea is to provide a general system in the form of a pseudo JDBC driver. However, we have learned the basic knowledge of the pool component before, and now it is easy to understand the usage of DBCP.


             //... // ① Create an instance of the genericobjectpool class. Genericobjectpool pool = new genericobjectpool (null );//... // ② In the previous discussion about the pool component, we mentioned that genericobjectpool // requires a poolableobjectfactory to create an instance of the object to be buffered. For DBCP, // This function is currently provided by poolableconnectionfactory //, as shown in the following example: drivermanagerconnectionfactory cf = new drivermanagerconnectionfactory ("JDBC: mysql: // host/DB", "username ", "password"); poolableconnectionfactory PCF = new poolableconnectionfactory (CF, pool, null, "select * From MySQL. DB ", false, true );//... // ③ now, we only need to create and register poolingdriver: New poolingdriver (). registerpool ("mypool", pool );

Next we can extract the connection from this connection pool. Note that the default values of maxactive and maxidle options are used to create this connection pool. If necessary, you can customize these values when creating a genericobjectpool instance in step 1. Dbcpdemo. Java provides a complete instance.

  V. validator

■ Overview: an API that collects common user input verification functions.

■ Official resources:Home Page,Binary,Source code.

■ When applicable: when regular verification is performed on the JavaBean.

■ Example application: validatordemo. Java, myvalidator. Java, myformbean. Java, and validation. xml. Require that the classpath must contain a commons-validator.jar, A commons-beanutils.jar, A commons-collections.jar, A commons-digester.jar, and a commons-logging.jar.

■ Note:

If you have used struts to develop Web applications, you should have used the validator package. The validator package greatly simplifies the test of user input data. However, validator is not limited to Web applications. It can also be easily used in other scenarios where Javabean is used.

Validator allows users to enter fields to define verification conditions, enable international error information, and allow users to create custom validators. In addition, the validator package also provides some predefined validators that can be used directly.

Verification rules and verification methods are defined in XML files (one or more XML files can be defined, but they are generally better separated ). The verification method file defines the validators to be used and specifies the Java classes that actually implement the validators (these classes are not required to implement certain specific interfaces, these classes are not required to be derived from a specific class. You only need to follow the definition declared in the method definition file ).

Next we will construct a custom validators. Its function is to check whether a string attribute of bean contains a specific character ("*").


             Import Org. apache. commons. validator. *; public class myvalidator {public static Boolean validatecontainschar (Object bean, field) {// first obtain the bean attribute (that is, a string value) string val = validatorutil. getvalueasstring (bean, field. getproperty (); // returns true or false based on whether the property contains the "*" character. Return (Val. indexof ('*') =-1 )? False: True );}}

The validatorutil class provides many practical methods. For example, validatorutil. getvalueasstring is used to extract the bean property value and return a string. Now we need to declare the myvalidator validator in the XML file.


             <! -- Define the validator Method --> <global> <validator name = "containsstar" classname = "myvalidator" method = "validatecontainschar" methodparams = "Java. lang. object, org. apache. commons. validator. field "/> </Global>

As you can see, the XML file defines in detail the features of the verification method, including the input parameters of the method. Next let's take a look at the steps to use this validator.

① Add the verification rules we want to implement to the XML file above.


             <! -- Define verification rules --> <FormSet> <! -- Check whether the bean name attribute can pass the containsstar test --> <form name = "myformbean"> <field property = "name" depends = "containsstar"> <arg0 key = "myformbean. name "/> </field> </form> </FormSet>

As you can see, all verification rules are declared within the FormSet element. The FormSet element first declares the form to be verified. The form lists the input fields to be verified and their verification conditions. In this example, we want to verify the name attribute of myformbean and check whether the attribute can pass the containsstar verification (that is, whether the value of the name attribute contains the "*" character ).

② Create A validator instance based on the XML file and initialize it.


             // Load the validators XML file inputstream in = getclass (). getresourceasstream ("validator. XML "); // create a validatorresourcesvalidatorresources resources = new validatorresources (); // initialize the validatorresourcesinitializer resource. initialize (Resources, in); // create validatorvalidator validator = new validator (resources, "myformbean"); validator. addresource (validator. bean_key, bean );

③ Verify the bean. The verification result is validatorresults, which contains the validation results for each property requiring verification according to their respective verification criteria.


             // Execute verification validatorresults Results = validator. Validate ();

④ Process validationresults.


             // The verification result object validationresults may also contain the result of verifying other form attributes. // For each attribute, we can extract the verification result separately. Validatorresult result = results. getvalidatorresult ("name"); // For each attribute, we can check the results of each verification condition. // For example, has the name attribute passed the containsstar verification? System. Err. println ("test result with name attribute containing" * "character:" + result. isvalid ("containsstar "));

For each validationresult instance, we can query whether it has passed a specific check. For example, in the above Code, we use the result. isvalid ('ininsstart') expression to check the validatorresult instance of the name attribute to see if it has passed the containsstar verification.

Validator is a useful component for Web applications. It provides a set of predefined validators, greatly facilitating the verification of user input legitimacy. The predefined validators can be used (but not limited to) to check the range, data type, length, e-mail address, and geographic location of input values. In addition, we can also define the validator and add it to the validator framework.

Conclusion: This is the third (and the last) article about Jakarta commons. Although the articles in this series only involve the basic knowledge of each component, I hope they are enough for you to start further research.

Download the code here:Jakartacommons3code.zip.

Comment
Related Materials
  • Common Verification System -- commons-validator 2003-11-12
  • Jakarta commons: clever use of classes and components 2 2003-10-10
  • Jakarta commons: clever use of classes and components 1 2003-10-10
  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.