JavaSercer Pages The DataSourceWrapper class implements the DataSource (Web hosting paypal)

January 23, 2007 on 2:40 pm | In Java | No Comments

JavaSercer Pages The DataSourceWrapper class implements the DataSource interface, so that it can be used in place of a pure JDBC 2.0 connection pool implementation. The constructor creates an instance of the real connection pool class, using the provided JDBC driver, URL, user and password information. Besides the constructor, the two most interesting methods are getConnection( ) and returnConnection( ). The pool client application calls the getConnection( ) method, and the DataSourceWrapper relays the call to the connection pool class. It then wraps the Connection object it receives in a ConnectionWrapper object and returns it to the client application. As described earlier, the ConnectionWrapper object calls the return-Connection( ) method when the pool client calls close( ) on the ConnectionWrapper object. The returnConnection( ) method hands over the Connection to the real connection pool so it can be returned to the pool. All other DataSource interface methods are implemented to throw an SQLException. If you use the wrapper classes presented here to wrap a more sophisticated connection pool, you may be able to relay some of these method calls to the real connection pool instead. 17.1.3 Making a Connection Pool Available to Application Components Through a DataSource object, the servlets and JSP pages in an application can get the Connection they need to access a database. What’s missing is how they get access to the DataSource . I touched on this in Chapter 14, but let’s recap and add a few details. The place for resources that all components in an application need access to is the application scope, corresponding to ServletContext attributes in the servlet world. The current versions of the servlet and JSP specifications, 2.2 and 1.1 respectively, do not provide a specific mechanism for automatic creation and release of application scope objects when the application starts and stops (but this is being discussed as a feature for future versions of the specifications). A regular servlet can, however, fill this need nicely.8 As described in Chapter 14, the container can be configured to load and initialize a servlet when the application starts. Such a servlet can create objects and make them available to other application components in its init( ) method before any user requests are received. The servlet is also informed when the application is shut down by a call to its destroy( ) method, allowing it to release all shared objects. Finally, a servlet can read configuration data, defined as servlet initialization parameters, so that it can work in different settings. In this section, we look at how all of this can be used to make a DataSource object available to all components of an application. The servlet used to manage the shared DataSource can be defined like this in the application’s WEBINF/ web.xml file: appInit com.mycompany.AppInitServlet
jdbcDriverClassName sun.jdbc.odbc.JdbcOdbcDriver

jdbcURL jdbc:odbc:example

dbUserName foo

dbUserPassword bar
1
… 8 Theoretically, a web container is allowed to unload a servlet at any time, for instance to preserve memory. This could cause the shared resources to be removed while other parts of the application are still active and need access to them. In practice, though, none of the major web containers unloads a servlet before the application as such is shut down. page 240

Hint: This post is supported by Gama web hosting php services

Java hosting - JavaSercer Pages public void clearWarnings( ) throws SQLException

January 23, 2007 on 6:34 am | In Java | No Comments

JavaSercer Pages public void clearWarnings( ) throws SQLException { if (isClosed) { throw new SQLException(”Pooled connection is closed”); } realConn.clearWarnings( ); } … } An instance of this class is associated with a real Connection object, retrieved from a connection pool, through the constructor. The constructor also provides a reference to the DataSourceWrapper instance that creates it, described next. The ConnectionWrapper class implements the Connection interface. The implementations of all the methods except two simply relay the call to the real Connection object so it can perform the requested database operation. The implementation of the close( ) method, however, doesn’t call the real Connect object’s method. Instead, it calls the DataSourceWrapper object’s return-Connection( ) method, to return the Connection to the pool. The isClosed( ) method, finally, returns the state of the ConnectionWrapper object as opposed to the real Connection object. Example 17.2 shows how the com.ora.jsp.sql.DataSourceWrapper gets a connection from a pool, and returns it when the pool client is done with it. Example 17.2. The DataSourceWrapper Class package com.ora.jsp.sql; import java.io.*; import java.sql.*; import javax.sql.*; public class DataSourceWrapper implements DataSource { private ConnectionPool pool; public DataSourceWrapper(String driverClass, String url, String user, String pw) throws ClassNotFoundException, InstantiationException, SQLException, IllegalAccessException { pool = new ConnectionPool(url, user, pw, driverClass, 1, 1); } /** * Gets a connection from the pool and returns it wrapped in * a ConnectionWrapper. */ public Connection getConnection( ) throws SQLException { return new ConnectionWrapper(pool.getConnection( ), this); } /** * Returns a Connection to the pool. This method is called by * the ConnectionWrapper’s close( ) method. */ public void returnConnection(Connection conn) { pool.returnConnection(conn); } /** * Always throws a SQLException. Username and password are set * in the constructor and can not be changed. */ public Connection getConnection(String username, String password) throws SQLException { throw new SQLException(”Not supported”); } public int getLoginTimeout( ) throws SQLException { throw new SQLException(”Not supported”); } public PrintWriter getLogWriter( ) throws SQLException { throw new SQLException(”Not supported”); } public void setLoginTimeout(int seconds) throws SQLException { throw new SQLException(”Not supported”); } public synchronized void setLogWriter(PrintWriter out) throws SQLException { throw new SQLException(”Not supported”); } } page 239
Note: If you are looking for good and quality webspace to host and run your java application check professional java hosting services

Comcast web hosting - JavaSercer Pages The interaction between the wrapper classes

January 23, 2007 on 1:34 am | In Java | No Comments

JavaSercer Pages The interaction between the wrapper classes and a connection pool implementation is illustrated in Figure 17.2. Figure 17.2. A JDBC 1.0 connection pool wrapped with JDBC 2.0 interface classes Figure 17.2 can be explained like this: the application calls the DataSourceWrapper getConnection( ) method. The DataSourceWrapper obtains a Connection object from its ConnectionPool object. The ConnectionPool either finds an available Connection in its pool or creates a new one. The DataSourceWrapper creates a new ConnectionWrapper object for the Connection it obtained, and returns the ConnectionWrapper to the application. The application uses the ConnectionWrapper object as a regular Connection. The ConnectionWrapper relays all calls to the corresponding method in the Connection it wraps, except for the close( ) method. When the application calls the close( ) method, the ConnectionWrapper returns its Connection to the DataSourceWrapper, which in turn returns it to its ConnectionPool. In this example, I show you how to wrap the connection pool described in Jason Hunter and William Crawford’s Java Servlet Programming (O’Reilly). It’s a simple implementation, intended only to illustrate the principles of connection pooling. The source code for the connection pool is included with the code for this book, but I will not discuss the implementation of the pool itself, only how to make it look like a JDBC 2.0 connection pool. For production use, I recommend that instead of this code, you use a pool intended for real use, such as one of the implementations mentioned earlier. The first wrapper class is called com.ora.jsp.sql.ConnectionWrapper , shown in Example 17.1. Example 17.1. The ConnectionWrapper Class package com.ora.jsp.sql; import java.sql.*; import java.util.*; class ConnectionWrapper implements Connection { private Connection realConn; private DataSourceWrapper dsw; private boolean isClosed = false; public ConnectionWrapper(Connection realConn, DataSourceWrapper dsw) { this.realConn = realConn; this.dsw = dsw; } /** * Inform the DataSourceWrapper that the ConnectionWrapper * is closed. */ public void close( ) throws SQLException { isClosed = true; dsw.returnConnection(realConn); } /** * Returns true if the ConnectionWrapper is closed, false * otherwise. */ public boolean isClosed( ) throws SQLException { return isClosed; } /* * Wrapped methods. */ page 238

Hint: If you are looking for very good and affordable webspace to host and run your j2ee hosting application check Sandzak.com j2ee web hosting services

Comcast webspace - JavaSercer Pages javax.sql.ConnectionPoolDataSource A DataSource implementation that provides

January 22, 2007 on 6:13 pm | In Java | No Comments

JavaSercer Pages javax.sql.ConnectionPoolDataSource A DataSource implementation that provides pooling capabilities uses a class that implements the ConnectionPoolDataSource interface. A ConnectionPoolDataSource is a factory for PooledConnection objects. Figure 17.1 outlines how an application uses implementations of these interfaces to obtain a pooled connection and how to return that connection to the pool. Figure 17.1. Application using a JDBC 2.0 connection pool The application calls the DataSource getConnection( ) method. The DataSource looks for an available PooledConnection object in its pool. If it doesn’t find one, it uses its ConnectionPoolDataSource object to create a new one. It then calls the getConnection( ) method on the PooledConnection object and returns the Connection object associated with the PooledConnection. The application uses the Connection, and calls its close( ) method when it’s done. This results in a notification event being sent to the DataSource, which puts the corresponding PooledConnection object back in the pool. If you would like to learn more about the JDBC 2.0 connection pool model, you can download the JDBC 2.0 Optional Package specification from http://java.sun.com/products/jdbc/. The real beauty of these interfaces is that the application doesn’t have to be aware that it’s using a connection pool. All configuration data, such as which JDBC driver and JDBC URL to use, the initial and maximum numbers of pooled connections, and the database account name and password, can be set by a server administrator. The completely configured DataSource object is registered as a JNDI resource, and the application can obtain a reference to it with the following code: Context ctx = new InitialContext( ); DataSource ds = (DataSource) ctx.lookup(”jdbc/EmployeeDB”); It then gets a Connection, uses it, and returns it with the following code: Connection conn = ds.getConnection( ); // Uses the Connection conn.close( ); // Returns the Connection to the pool By implementing these JDBC 2.0 interfaces, JDBC driver and middleware vendors can offer portable connection pooling implementations. Sun’s JDBC driver list contains roughly ten different companies that claim to either offer implementations of connection pools today or have announced products to be delivered during 2000. 17.1.2 Making a JDBC 1.0 Connection Pool Behave as a JDBC 2.0 Connection Pool If you can’t find a JDBC 2.0 connection pool implementation for your database, there are plenty of implementations based on JDBC 1.0 available. I describe one in an article I wrote for the Web Developer’s Journal, titled “Improved Performance With a Connection Pool,” available at http://www.webdevelopersjournal.com/columns/connection_pool.html. Another is the DBConnectionBroker , available at http://www.javaexchange.com. It’s easy to develop a couple of wrapper classes for one of these implementations so that it can be used in place of a JDBC 2.0 connection pool implementation. This way, you can switch out the JDBC 1.0 pool with a JDBC 2.0 pool when one becomes available from your database vendor or a third party. page 237

Hint: This post is supported by Gama web hosting php mysql provider

Frontpage hosting - JavaSercer Pages A connection is expensive to keep

January 22, 2007 on 12:14 pm | In Java | No Comments

JavaSercer Pages A connection is expensive to keep open in terms of server resources such as memory. Many commercial database products also use licenses that are priced based on the number of simultaneously open connections, so a connection can also be expensive in terms of real money. Therefore, it’s wise to try to minimize the number of connections the application needs. An alternative to the “one Connection per resource” approach is to create a Connection for each user when the first request is received and keep it as a session scope object. However, a drawback with this approach is that the Connection will be inactive most of the time, since the user needs time to look at the result of one request before making the next. The best alternative is to use a connection pool. A connection pool contains a number of Connection objects shared by all servlets and JSP pages. For each request, one Connection is checked out, used, and checked back in. Using a pool solves the problems described for the other alternatives: It’s time-consuming to create a Connection. A pooled Connection is created only once and then reused. Most pool implementations let you specify an initial number of Connection objects to create at startup, as well as a max number. New Connection objects are created as needed up to the max number. Once the max number has been reached, the pool clients wait until an existing Connection object becomes available instead of creating a new one. There are multithreading problems with a shared Connection. Each request gets its own Connection, so it’s used by only one thread at a time, eliminating any potential multithreading issues. A Connection is a limited resource. With a pool, each Connection is used efficiently. It never sits idle if there are requests pending. If the pool allows you to specify a max number of Connection objects, you can also balance a license limit for the number of simultaneous connections against acceptable response times. A connection pool, however, doesn’t solve all problems. Since all users are using the same Connection objects, you cannot rely on the database engine to limit access to protected data on a per-user basis. Instead, you have to define data access rules in terms of roles (groups of users with the same access rights). You can then use separate pools for different roles, each pool creating Connection objects with a user account that represents the role. 17.1.1 Using a JDBC 2.0 Optional Package Connection Pool Connection pools exist in many forms. You can find them in books, articles, and on the Web. Yet prior to JDBC 2.0, there was no standard defined for how a Java application would interact with a connection pool. The JDBC 2.0 Optional Package (formerly known as a Standard Extension) changes this by introducing a set of interfaces that connection pools should implement: javax.sql.PooledConnection The objects that a DataSource keeps in its pool implement the PooledConnection interface. When the application asks the DataSource for a Connection, it locates an available PooledConnection object, or gets a new one from its ConnectionPoolDataSource if the pool is empty. The PooledConnection provides a getConnection( ) method that returns a Connection object. The DataSource calls this method and returns the Connection to the application. This Connection object behaves like a regular Connection with one exception: when the application calls the close( ) method, instead of closing the connection to the database, it informs the PooledConnection it belongs to that it’s no longer being used. The PooledConnection relays this information to the DataSource, which returns the PooledConnection to the pool. javax.sql.DataSource A DataSource represents a database. This is the interface the application always uses to get a Connection. The class that implements the interface can provide connection pooling capabilities or hand out regular, unpooled Connection objects; the application code is identical for both cases, as described later. page 236
Note: If you are looking for best hosting provider to host and run your tomcat application check Astra tomcat hosting services

JavaSercer Pages Chapter 17. Developing Database Access Components (Web hosting ssh)

January 22, 2007 on 4:33 am | In Java | No Comments

JavaSercer Pages Chapter 17. Developing Database Access Components In this final chapter, we look at more examples of how to develop custom actions, namely the database custom actions introduced in Chapter 9. Before digging into the code for these actions, a number of fundamental Java database access features are discussed. First, we take a look at the JDBC Connection class, and how pooling Connection objects helps solve a number of common problems. We look at two ways to provide connection pooling capabilities to an application: with JDBC 2.0, and by letting a JDBC 1.0 connection pool simulate a JDBC 2.0 pool. The purpose of a connection pool is to be able to share database connections between all components of an application. The approach discussed in this chapter is to use an application initialization servlet that makes the pool available to all servlets and JSP pages. No matter if you use a servlet or a custom action in a JSP page to access the database, there are a number of things to think about. We look at a generic database access bean and related classes that take care of datatype issues and make the result of a query easy to access. Next, we look at how the bean is used by the database access custom actions described in Chapter 9. You can also use the bean directly in servlets, as described in Chapter 15, or in your own application-specific database access actions. The last section contains an example of an application-specific custom action using the bean. To really appreciate the material in this chapter, you should already be familiar with JDBC. If this is not the case, I recommend that you look at the JDBC documentation online at http://java.sun.com/products/jdbc/ or read a book about JDBC, such as George Reese’s Database Programming with JDBC and Java (O’Reilly). 17.1 Using Connections and Connection Pools In a JDBC-based application, a lot revolves around the java.sql.Connection interface. Before any database operations can take place, the application must create a Connection to the database. It then acts as the communication channel between the application and the database, carrying the SQL statements sent by the application and the results returned by the database. A Connection is associated with a database user account, to allow the database to enforce access control rules for the SQL statements submitted through the Connection. Finally, the Connection is also the boundary for database transactions. Only SQL statements executed through the same Connection can make up a transaction. A transaction consists of a number of SQL statements that must either all succeed or all fail as one atomic operation. A transaction can be committed (the changes resulting from the statements are permanently saved) or rolled back (all changes are ignored) by calling Connection methods. In a standalone application, a Connection is typically created once and kept open until the application is shut down. This is not surprising, since a standalone application serves only one user at a time, and all database operations initiated by a single user are typically related to each other. In a server application that deals with unrelated requests from many different users, it’s not so obvious how to deal with connections. There are three things to consider: a Connection is time-consuming to create, it must be used for only one user at a time to avoid transaction clashes, and it is expensive to keep open. Creating a Connection is an operation that can actually take a second or two to perform. Besides establishing a network connection to the database, the database engine must authenticate the user and create a context with various data structures to keep track of transactions, cached statements, results, and so forth. Creating a new Connection for each request received by the server, while simple to implement, is far too time- consuming in a high-traffic server application. One way to minimize the number of times a connection needs to be created is to keep one Connection per servlet or JSP page that need access to the database. A Connection can be created when the web resource is initialized, and kept in an instance variable until the application is shut down. As you will discover when you deploy an application based on this approach, this route will lead to numerous multithreading issues. Each request executes as a separate thread through the same servlet or JSP page. Many JDBC drivers do not support multiple threads accessing the same Connection, causing all kinds of runtime errors. Others support it by serializing all calls, leading to poor scalability. An even more serious problem with this approach is that requests from multiple users, all using the same Connection, operate within the same transaction. If one request leads to a rollback, all other database operations using the same Connection are also rolled back. page 235
Note: If you are looking for cheapest and affordable webspace to host and run your servlet application check Astra j2ee hosting services

JavaSercer Pages The WEB-INF/web.xml file must then contain (Tomcat hosting)

January 21, 2007 on 9:24 pm | In Java | No Comments

JavaSercer Pages The WEB-INF/web.xml file must then contain the following elements: /orataglib /WEB-INF/lib/orataglib_1_0.jar The element contains the symbolic name, and the element contains the path to either the JAR file or the extracted TLD file. page 234
Quick Hint: If you are looking for cheap and reliable provider to host and run your servlet application check Vision servlet hosting plans

JavaSercer Pages 16.10 Packaging and Installing a Tag

January 21, 2007 on 1:26 pm | In Java | No Comments

JavaSercer Pages 16.10 Packaging and Installing a Tag Library During development, you may want to let the tag library classes and the TLD file reside as-is in the filesystem, since it makes it easy to change the TLD and modify and recompile the classes. Just make sure the class files are stored in a directory that’s part of the classpath for the JSP container, such as the WEBINF/ classes directory for the web application. The TLD must also be in a directory where the JSP container can find it. The recommended location is the WEB-INF/tlds directory. To identify the library with the TLD stored in this location, use a taglib directive in the JSP pages like this: <%@ taglib uri="/WEB-INF/tlds/orataglib_1_0.tld" prefix="ora" %> Here the uri attribute refers directly to the TLD file’s location. When you’re done with the development, you may want to package all tag handler classes, TagExtraInfo classes, beans used by the tag handler classes, and the TLD in a JAR file. This makes it easier to install the library in an application. The TLD must be saved as /META-INF/taglib.tld within the JAR file. To create the JAR file, first arrange the files in a directory with a structure like this: META-INF/ taglib.tld com/ ora/ jsp/ tags/ generic/ EncodeHTMLTag.class … util/ StringFormat.class … The structure for the class files must match the package names for your classes. Here a few of the classes in the tag library for this java blog are shown as an example. With the file structure in place, use the jar command to create the JAR file: jar cvf orataglib_1_0.jar META-INF com This command creates a JAR file named orataglib_1_0.jar containing the files in the META-INF and com directories. Use any JAR filename that makes sense for your own tag library. Including the version number for the library is also a good idea, since it lets the users know which version of the library they are using. You can now use the packaged tag library in any application. Just copy the JAR file to the application’s WEBINF/ lib directory and use a taglib directive like this in the JSP pages: <%@ taglib uri="/WEB-INF/lib/orataglib_1_0.jar" prefix="ora" %> Note that the uri attribute now refers to the JAR file instead of the TLD file. A JSP 1.1 container is supposed to be able to find the TLD file in the JAR file, but this is a fairly recent clarification of the specification. If the JSP container you use doesn’t support this notation yet, you have to extract the TLD file from the JAR file, save it somewhere else, for instance in WEB-INF/tlds, and let the uri attribute refer to the TLD file instead. Instead of letting the taglib directive point directly to the TLD or JAR file, you can specify a symbolic name as the uri attribute value, and provide a mapping between this name and the real location in the WEBINF/ web.xml file for the application: <%@ taglib uri="/orataglib" prefix="ora" %> page 233

Hint: This post is supported by Gama web hosting php mysql provider

JavaSercer Pages 16.9 How Tag Handlers May Be (Comcast hosting)

January 21, 2007 on 6:08 am | In Java | No Comments

JavaSercer Pages 16.9 How Tag Handlers May Be Reused Creating new objects is a relatively expensive operation in Java. For high-performance applications, it’s common to try to minimize the number of objects created and reuse the same objects instead. The JSP 1.1 specification describes how a tag handler instance can be reused within the code generated for a JSP page if the same type of custom action appears more than once. The reuse is subject to a number of restrictions and relies on tag handler classes dealing with their internal state as specified. It’s important to understand the reuse rules, so your tag handler classes behave as expected in a JSP implementation that takes advantage of this mechanism. As discussed in the previous sections of this chapter, a tag handler’s state is initiated through property setter methods corresponding to the action element’s attributes. The tag handler is then offered a chance to do its thing in various stages, represented by the doStartTag( ), doInitBody( ), doAfterBody( ), and doEndTag( ) methods. It’s clear that the property values must be kept at least until the tag handler has done what it intends to do. But when can it safely reset its state? If a tag handler implements all logic in the doStartTag( ) method, can it reset all instance variables before it returns from this method? Or should it wait until the doEndTag( ) method is called? The answer is that it must not reset the state until the release( ) method is called. Let’s use a JSP page fragment to discuss why: In this case, a JSP container is allowed to use one instance of the tag handler for both action elements, with generated code similar to this: // Code for first occurrence MyActionTag _jspx_th_test_myAction_1 = new MyActionTag( ); _jspx_th_test_myAction_1.setPageContext(pageContext); _jspx_th_test_myAction_1.setParent(null); _jspx_th_test_myAction_1.setAttr1(”one”); _jspx_th_test_myAction_1.setAttr2(”two”); _jspx_th_test_myAction_1.doStartTag( ); if (_jspx_th_test_myAction_1.doEndTag( ) == Tag.SKIP_PAGE) return; // Code for second occurrence _jspx_th_test_myAction_1.setAttr2(”new”); _jspx_th_test_myAction_1.doStartTag( ); if (_jspx_th_test_myAction_1.doEndTag( ) == Tag.SKIP_PAGE) return; _jspx_th_test_myAction_1.release( ); As you can see, all the property setter methods are called to initialize the instance for the first occurrence of the element. But for the second occurrence, only the setter method for the property with a different value is called. The release( ) method is called when the tag handler has been used for both occurrences. If the tag handler class resets all property variables in any method other than release( ), the processing of the second action element fails. The only scenario in which a tag handler can be reused in JSP 1.1 is the one described above. If the same action element is used multiple times on the same page but with different sets of attributes, the state of the tag handler is not guaranteed to be correct if the same instance is reused. Reuse between pages, using a tag handler object pool, is not explicitly supported in JSP 1.1. For this reason, most JSP containers do not implement tag handler pooling today. To get your tag handler classes to work with the few that do, you must reset all properties before the tag handler is used to handle a new request. I recommend that you do this in the release( ) method, as shown in the examples in this chapter. Note that if some properties must have a default value set instead of null, you must set it in the release( ) method as well. A typical example is a primitive type property, such as an int property: public void release( ) { aStringProperty = null; anIntProperty = -1; } To make it easier for a container to reuse tag handlers, both within a page and between pages, a future version of JSP will likely introduce a method that resets all properties in a controlled manner. page 232
Note: If you are looking for cheap and inexpensive provider to host and run your tomcat application check professional tomcat hosting services

JavaSercer Pages Another optional element is . It (Buy webspace)

January 21, 2007 on 1:07 am | In Java | No Comments

JavaSercer Pages Another optional element is . It can contain one of three values. A value of empty means that the action body must be empty. If the body can contain JSP elements, such as standard or custom actions or scripting elements, the JSP value should be used. All JSP elements in the body are processed, and the result is handled as specified by the tag handler (i.e., processed by the tag handler or sent through to the response body). This is also the default value, in case you omit the element. The third alternative is tagdependent. This value means that possible JSP elements in the body are not processed. Typically, this value is used when the body is processed by the tag handler and the content may contain characters that could be confused with JSP elements, for example, SELECT * FROM MyTable WHERE Name LIKE ‘<%>‘. If a tag that expects this kind of body content is declared as JSP, the <%> is likely to confuse the JSP container. The tagdependent value can be used to avoid this risk for confusion. The element can optionally be used to describe the purpose of the action. The element must also contain an element for each action attribute. Each element in turn contains other elements that describe the attribute: , , and . The mandatory element contains the attribute name. The optional element tells if the attribute is required or not. The values true, false, yes, and no are valid, with false being the default. Finally, the element is an optional element that can have the same values as the element. If the value is true or yes, a request-time attribute expression can be used to specify the attribute value, for instance ‘attr=”<%= request.getParameter("par") %>‘. The default value is false. 16.8 Validating Syntax The TLD for a tag library contains information about the attributes each action element supports. Therefore, the JSP container can help by verifying that the custom action is used correctly by the page author, at least with respect to the attributes. When the JSP container converts a JSP page to a servlet, it compares each custom action element to the specification of the action element in the TLD. First, it makes sure that the action name matches the name of an action specified in the TLD corresponding to the action element’s prefix. It then looks at the attribute list in the page and compares it to the attribute specification in the TLD. If a required attribute is missing, or an attribute is used in the page but not specified in the TLD, it reports it as an error so the page author can correct the mistake. But for some actions, it’s not that simple. Some attributes may depend on the presence of other attributes. Attributes may be mutually exclusive, so that if one is used, the other must not be used. Or an optional attribute may require that another optional attribute is used as well. To be able to verify these kinds of dependencies, the JSP container asks the tag handler’s TagExtraInfo subclass for assistance. After the JSP container has checked everything it can on its own, it looks for a TagExtraInfo subclass, defined by the element, for the action. If one is defined, it puts all attribute information in an instance of the TagData class and calls the TagExtraInfo isValid( ) method: public boolean isValid(TagData data) { // Mutually exclusive attributes if (data.getAttribute(”attr1″) != null && data.getAttribute(”attr2″ != null) { return false; } // Dependent optional attributes if (data.getAttribute(”attr3″) != null && data.getAttribute(”attr4″ == null) { return false; } return true; } A TagExtraInfo subclass can use the TagData instance to verify that all attribute dependencies are okay, as in this example. In JSP 1.1, unfortunately, there’s no way to generate an appropriate error message; the method can only return false to indicate that something is not quite right. This will hopefully be rectified in a future version of JSP. page 231
Note: If you are looking for best hosting provider to host and run your tomcat application check Astra tomcat hosting services

« Previous PageNext Page »