JSP tag libraries provide a simple, elegant way of embedding dynamic server-side request handling into a JSP page. WebLogic Server provides a tag library with custom tags that you may use in your JSP pages; this library defines the cache, repeat, and process tags. Other tags also are supplied, though these are not discussed, as much of their functionality can now be found in more standard tag library implementations, such as the Java Standard Template Library (JSTL). WebLogic also provides a tool to automatically generate a tag library for an EJB.
2.4.1 WebLogic's Tag Library
WebLogic's tag library JAR (weblogic-tags.jar) is located in WL_HOME/server/ext. It packages the tag library descriptor, the tag handler classes, and several other support classes. In order to use these tags in your JSP pages, you need to make the library available to your web application. Copy the JAR to the /WEB-INF/lib folder under the document root of the web application, and define a taglib element in the standard web.xml deployment descriptor:
/weblogic-tags /WEB-INF/lib/weblogic-tags.jar
Now you can import the tag library into your JSP pages as follows:
<%@ taglib uri="/weblogic-tags" prefix="wl" %>
Let's take a closer look at the features and capabilities of these three tags.
2.4.1.1 The cache tag
The cache tag enables you to cache the output generated within the body of the tag. Because the output is usually some function of parameter or attribute values, the tag also allows you to cache the values of input parameters or attributes that uniquely generate a particular response. The caches are implemented using soft references to prevent the cache mechanism from hogging memory. Let's examine important attributes of the cache tag.
A cache tag may specify a unique name for the cache, if it is to be used across multiple JSP pages. A random name is generated if you do not specify one. By default, the cache tag uses an application-wide scope. You may specify a custom scope for the cache tag using one of the following values for the scope attribute: page, request, session, or application. For example, if you need to cache the contents of the tag's body for each HTTP session, you should use the cache tag as follows:
...
The tag's body content will be evaluated once when the JSP is requested after an HTTP session has been created, and then cached forever until the session is invalidated (or the cache is manually flushed).
You may also specify a timeout value, after which the cache contents become invalid. The tag content is not refreshed automatically after the timeout. Instead, it is reevaluated only when the JSP is invoked for the first time after the timeout occurs. You may use any of the following time units, as appropriate: ms (milliseconds), s (seconds), m (minutes), h (hours), or d (days). The default timeout value is -1, which implies that the cache data will never be refreshed. The following example illustrates how you can use the cache tag to refresh news content every 15 minutes:
<%-- HTML News Feed --%>
Often the contents of the tag's body will be evaluated based on the value of a certain request parameter or perhaps an object associated with the request or session attribute. For instance, you could generate news items on the basis of a URL submitted via a request parameter to the JSP. In that case, you need to be able to associate the content generated with the name of that parameter or the object attribute used to evaluate the content. The key attribute allows you to specify the name of a parameter/attribute, whose value will be used as a key to locate the cached response generated within the tag's body. In fact, you may specify a comma-separated list of key values. The following example shows how to cache the tag contents, using the value of the url request parameter as the key:
key="parameter.url" timeout="15m" size="10"> <%-- JSP body that uses the url parameter, perhaps to fetch a news item --%>
The contents of the tag's body are evaluated the first time a JSP is invoked, and the response is cached using the specified value for the url parameter. If the JSP is subsequently invoked with the same value for the url parameter, the cached response will be returned as long as it's not more than 15 minutes old. Otherwise, the contents of the tag will be reevaluated and the cache updated. The size attribute instructs the JSP container to cache the content for no more than 10 unique url values. The least recently used items are expelled from the cache if new items need to be inserted and the cache has reached maximum capacity. The default value for the size attribute is -1, which means the cache supports an unlimited number of entries.
The following example caches the contents of the tag's body based on the value of a session attribute:
key="session.userid"> <%-- JSP body that generates HTML form with details of current user --%>
In this case, the output is cached until the particular session is invalidated. Notice how the key uses a prefix to specify a scope for the parameter or attribute. You can choose from the following prefixes: parameter, page, request, session, and application. If the key does not have a scope prepended to it, the container will search through the scopes in the same order listed earlier.
The cache tag also supports input caching, whereby the tag caches values that are calculated within the tag's body. The vars attribute allows you to specify a list of the names of variables whose values should be cached along with the body of the tag. Just like the key attribute, you may prefix the variable name with a scope. When the cache is retrieved, the values that were cached are restored, allowing you to access them from their respective scopes outside the cache tag body. For instance, say that we calculate some value, calculatedvalue, and store it as a request attribute. The calculated value will then be made available after the cache tag:
Attribute value before is: <%= request.getAttribute("calculatedvalue") %> <% request.setAttribute("calculatedvalue", new Date( ).toString( )); %> Attribute value after is: <%= request.getAttribute("calculatedvalue") %>
Here is the output when we access this page a number of times over a 10-second window:
Attribute value before is: null Attribute value after is: Mon Feb 10 09:27:58 GMT 2003 Attribute value before is: null Attribute value after is: Mon Feb 10 09:27:58 GMT 2003 Attribute value before is: null Attribute value after is: Mon Feb 10 09:27:58 GMT 2003 Attribute value before is: null Attribute value after is: Mon Feb 10 09:28:08 GMT 2003
Notice how the attribute value is retained by the cache and reinserted into the request scope after execution of the cache tag, making it available to the rest of the JSP page.
You also can set the async attribute to true, which means WebLogic will attempt to update the cache asynchronously if the cached entries are set to time out. In this case, a JSP request that generates a cache hit may still use the old cached response while the new values are concurrently evaluated and cached for future use.
Finally, the cache tag enables you to flush all cached values. If you set the flush attribute's value to true, the JSP container will flush all entries associated with the cache. Whenever you set the flush attribute, the cache tag must have an empty body. The following example shows how to flush a cache with session scope:
If the cache does not have a name, you must identify the cache using its vars, keys, and scope attributes.
You can refresh all caches in a particular scope by setting the _cache_refresh attribute's value to true. For instance, if you want to refresh all caches associated with a user's session, you should invoke the following from a session-aware JSP page:
<% session.setAttribute("_cache_refresh", "true"); %>
If you want all caches to be refreshed, you should set the attribute in the application scope. And, if you want to flush all caches associated with the current request, you should set the request attribute (or parameter) to true.
Table 2-3 provides a summary of the cache options.
Parameter name |
Description |
---|---|
name |
You can use this parameter to provide a unique name for the cache, allowing it to be shared across multiple JSP pages. |
timeout |
The timeout determines the time after which the cache will be refreshed if accessed again. |
scope |
The scope determines the scope in which the data is cached. It can be one of page, parameter, request, session, or application. |
key |
The key specifies additional values that should be used when evaluating whether to cache the values contained within the tag. |
async |
If this parameter is true, the cache will be updated asynchronously if possible. |
size |
This parameter determines the maximum size of the cache. If set to -1, it is unlimited. Otherwise, an LRU scheme is used to maintain the cache. |
vars |
This parameter specifies a set of scoped variables that should be cached along with the contents of the cache tag, and made available to the rest of JSP after execution of the tag. |
flush |
If this parameter is set to true, the cache is flushed. |
2.4.1.2 The process tag
The process tag allows you to customize the flow control within a JSP page using query parameters supplied to it. You can configure the tag to include the body based on the following:
name="foo"> notname="foo">
Clearly, process tags provide a simple, declarative way of including/excluding JSP portions.
2.4.1.3 The repeat tag
The repeat tag allows you to repeatedly evaluate the body of a tag, while iterating over the elements in a collection. The tag supports all kinds of collections arrays, vectors, enumerations, JDBC result sets, hash-table keys, etc. The set attribute allows you to specify the collection that will be used to iterate over. The body of the tag will be evaluated for each iteration, using the current element of the configured set. Let's look at few examples of how you can use the repeat tag:
" type="com.foo.bar.AUser" count="10"> <%--print details of each user--%> Username: <%= user.getUsername( ) %> Full Name: <%= user.getFullname( ) %> DOB: <%= user.getDob( ) %>
"> <%--print all products--%><%= product %>
The id attribute defines the name of the object that holds a reference to the element of the set during each iteration. You can specify the type of each element in the collection using the type attribute. By default, the repeat tag expects the type of each element to be String. You also can specify a count attribute, which forces the tag to iterate only over the first count entries.
2.4.2 Building Tag Libraries for EJBs
WebLogic Server provides a tool that generates a tag library from an EJB JAR file one for each EJB in the JAR file. The custom tags in the library provide an easy, elegant way for invoking methods on the enterprise bean. Take, for example, the following remote interface for a session bean:
public interface User extends javax.ejb.EJBObject { public AUser[] list(int realmid) throws java.rmi.RemoteException; public boolean add(int realmid, AUser user) throws java.rmi.RemoteException; public boolean update(int realmid, AUser user) throws java.rmi.RemoteException; public boolean delete(int realmid, String userid) throws java.rmi.RemoteException; }
Using the EJB-to-JSP integration tool, you can generate a tag library that is custom-made for the session bean. The tag library will contain a tag for each method, so you can invoke the EJB from within a JSP page as follows:
<% taglib uri="/WEB-INF/user-tags.tld" prefix="user" %> List Users: <%-- value of _return attribute is the scripting variable that will hold the return value for the EJB method --%> Username: <%= user.getUsername( ) %> Full Name: <%= user.getFullname( ) %> DOB: <%= user.getDob( ) %>
The attributes for the tags correspond to the parameters for the EJB method call. The tag handlers for the custom tags provide the implementation for the actual EJB invocations. Because the custom tag hides away all the messy details of invoking an EJB method, the resulting JSP is clean and elegant. The EJB-JSP integration tool supports tag libraries for session beans (stateful and stateless) and for entity beans.
2.4.2.1 The ejb2jsp tool
You can run the EJB-to-JSP integration tool in graphical mode as follows:
java weblogic.servlet.ejb2jsp.gui.Main
Initially, no project files are loaded, so you need to create a new ejb2jsp project by choosing an EJB JAR file. Once you have created an ejb2jsp project, you can modify the project settings, save the project, and reload ejb2jsp projects created earlier. The structure of the tag library is fairly straightforward:
You can use the Project Build Options panel to configure how the ejb2jsp tool will generate the associated tag library. In fact, you must specify the following items:
When you create a new ejb2jsp project using the selected EJB JAR file, the ejb2jsp tool cannot generate the tags based only on information acquired from introspecting the bean interface classes. It needs the source for the EJB classes as well, before it can assign meaningful names for the tag attributes. You can adjust the source path for the EJB JAR under the Project Build Options panel. By default, the ejb2jsp tool assumes that the source files are in the same folder that contains the EJB JAR file. Once you have set the source path, you can select File/Resolve Attributes to resolve the tag attribute names to method parameter names. You can build the tag library only after you have meaningful names for all tag attributes.
2.4.2.2 Resolving conflicts
The ejb2jsp tool tries to resolve attribute names based on the EJB source and compiled classes. Despite this, a project may generate errors or conflicts while building the tag library. This may happen for several reasons:
|
Once you have generated the tag library, you can save the current project for later use. You even can configure certain attributes of the custom tag to accept default values. The ejb2jsp tool allows you to set the default value for an attribute in two ways:
Attributes with default values need not be specified when their associated custom tag is used in a JSP page.
2.4.2.3 Custom tags for stateful beans and entity beans
In a typical scenario involving stateful beans or entity beans, a client looks up the bean in the JNDI tree and acquires a reference to the EJB's home interface; it then invokes multiple methods on the bean instance. The custom tags generated for the enterprise bean preserve the same semantics. Custom tags corresponding to methods of the bean's remote interface must be nested within the tag associated with the find( ) or create( ) method of the bean's home interface. So, all EJB methods are invoked using the bean instance created (or found) by the enclosing create (or find) tag. WebLogic's JSP container generates a runtime exception if the EJB method tag is not enclosed within the tag of one of the EJB's home methods.
Consider the following EJB code:
/** bean home interface */ public interface UserHome extends EJBHome { public User create(String userid, String fullname, String username, String password, boolean alive); public User findByPrimaryKey(String userid); public Collection findDeadUsers( ); } /** bean remote interface */ public interface User extends EJBObject { public String getUserID( ); public String getFullName( ); public void changePassword(String oldpw, String newpw); }
After generating the tag library, you can invoke the entity bean from a JSP page as follows:
<% taglib uri="/WEB-INF/user-ejb.tld" prefix="user" %> useruserid") %>" fullname="<%= request.getParameter("fullname") %>" username="<%= request.getParameter("username") %>" password="<%= request.getParameter("password") %>" alive="<%= true %>" _return="user"> " newpw="<%= request.getParameter("newpw") %>" /> <%= user.getFullName( ) %>: Your password has been successfully changed.
The _return attribute in the home-create tag determines the name of the page variable that holds a reference to the newly created (or found) bean instance. Entity bean finder methods will typically return a collection of EJB instances that match the select criteria. If a home tag for an entity bean returns a collection of EJB instances, the body of the tag will be evaluated for each item in the collection. In this case, the _return attribute for the find tag corresponds to the bean instance used in the current iteration. The following example generates an HTML list of all deceased users:
All Deceased Users:
The ejb2jsp tool is useful for generating reusable tag libraries for your enterprise beans. It allows for rapid prototyping of JSP pages and provides a quick way for testing EJB functionality. Custom tags for the EJB methods hide all the details of invoking the bean.
Introduction
Web Applications
Managing the Web Server
Using JNDI and RMI
JDBC
Transactions
J2EE Connectors
JMS
JavaMail
Using EJBs
Using CMP and EJB QL
Packaging and Deployment
Managing Domains
Clustering
Performance, Monitoring, and Tuning
SSL
Security
XML
Web Services
JMX
Logging and Internationalization
SNMP