Oracle® Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference
10g Release 2 (10.1.2) B14016-02 |
|
Previous |
Next |
This chapter describes the Web Object Cache, an application-level caching mechanism supplied with OC4J. For Web applications written in Java, you can use the Web Object Cache in conjunction with the Oracle Application Server Web Cache for increased speed and scalability.
The chapter consists of the following sections:
For an overview of Web caching, including a discussion of the OracleAS Web Cache and Oracle Application Server Java Object Cache, see "Summary of Oracle Caching Support for Web Applications".
The OC4J Web Object Cache is a mechanism that allows Web applications written in Java to capture, store, reuse, post-process, and maintain the partial and intermediate results generated by a dynamic Web page, such as a JSP or servlet. For programming interfaces, it provides a tag library and a Java API.
The Web Object Cache works at the Java level and is closely integrated with the HTTP environment of JSP and servlet applications. Cached objects might consist of HTML or XML fragments, XML DOM objects, or Java serializable objects.
With the Web Object Cache programming interfaces, you can split Web pages into page blocks that define separate cache objects for finer control of caching. (The terms block and object are used somewhat interchangeably in this sense.) In this way, the application itself can control life span and other behavior of individual cache entities during runtime. Application developers have the best understanding of the life cycle patterns of their application Web pages, so are best suited to determine how to split pages into cache blocks. You can specify maintenance policies for cached objects either declaratively in an external file, the cache policy descriptor, or programmatically within the application itself.
The following sections provide an overview of the Web Object Cache:
Note: The Web Object Cache is useful in particular scenarios and does not replace the need for other caching mechanisms, including the OracleAS Web Cache. For an overview of the Web Object Cache and how it relates to the OracleAS Web Cache and the Oracle Application Server Java Object Cache, including a discussion of when it is appropriate to use each one, see "Summary of Oracle Caching Support for Web Applications". |
Using the Web Object Cache can significantly reduce the amount of time spent in constructing page blocks or Java objects in dynamic applications, such as those with expensive intermediate operations like querying a database and formatting or transforming the results. Subsequent queries pull the information out of the cache, so the query and formatting do not have to be repeated.
Furthermore, developers can closely control the cache programmatically, through API calls or custom JSP tags. This can include controlling when cache entries are created, what they are named, when they expire, which users can see which cached data, and what operations can be applied to cached data before the results are served to the user.
Some kinds of Web applications benefit more than others by using the Web Object Cache, depending on the nature and use of their data. For example, applications such as catalog and directory browsing, delayed stock quotes, and personalized portals would particularly benefit. Applications such as real-time stock trading or real-time stock quotes, however, would not benefit, because the data has to be updated so frequently that the overhead of the caching operations would outweigh the benefits. (In these circumstances, however, the OracleAS Web Cache might still be useful because of its lighter overhead.)
In general, the Web Object Cache is most useful in the following situations:
For special post-processing on cached data objects, such as XSLT or XML DOM operations
For sharing data in a non-HTTP situation, such as reusing cached XML data or Java objects and sending the data to others through SMTP, JMS, AQ, or SOAP
For special storage needs, such as storing cached data in a file system or database for persistent storage of data with a long lifetime
For application-specific authorization, allowing different users to have different access rights to different data items, such as for a Web-based groupware application
The application can have its own authorization scheme. The Web Object Cache is embedded within Java authorization logic.
Using the Web Object Cache in JSP pages is particularly convenient. JSP code generation can save much of the development effort.
The Web Object Cache consists of two main components:
Cache repository
Cache programming interfaces
This section also provides a brief introduction to the Oracle Application Server Java Object Cache, which is the default cache repository of the Web Object Cache.
The cache repository is the component that is responsible for data storage, data distribution, and cache expiration. There can be multiple repository implementations for a programmable Web cache (such as the Web Object Cache), depending on the tier and platform. For example, the file system might be used for secondary storage in the middle tier, and database tables might be used for primary storage in the database tier.
The Web Object Cache uses the Oracle Application Server Java Object Cache as its default repository. The Java Object Cache is a general-purpose Java caching service and API designed for application use, with objects being accessible by name.
The Java Object Cache is a powerful and flexible programming facility. There are no restrictions on the types of objects that can be cached or the original source of the objects. The management of each object can be easily customized. Each object has a set of attributes such as the following:
How the object is loaded into the cache
Where the object is stored (in memory, on disk, or both)
The lifetime, also known as the time-to-live, of the object
Whom to notify when the object is invalidated
Objects can be invalidated as a group or individually.
For more information about the Java Object Cache, see the Oracle Application Server Containers for J2EE Services Guide.
Note: See "Configuration for Back-End Repository" for information about configuring the Java Object Cache or a file system as the back-end repository for the Web Object Cache. |
The front-end caching interfaces are used through JSP pages and servlets to handle HTTP processing and to direct the semantics relating to the cache policy (rules and specifications determining how the cache works).
The OC4J Web Object Cache programming interfaces can be further divided as follows:
Web Object Cache API
This is the common layer across servlets and JSP pages, dealing with the HTTP semantics and cache policy. This layer communicates with the cache repository.
Web Object Cache tag library
This is a convenient wrapper, using JSP custom tag functionality, for the Web Object Cache API. Use custom tags in a JSP page to control the caching, with the API being called through the underlying tag handler classes.
This chapter describes these programming interfaces and their interaction with the cache repository. Cache tags are described in "Web Object Cache Tag Descriptions". The underlying cache policy API is described in "Web Object Cache API Descriptions". In servlets, you will use the underlying API; in JSP pages, you will typically use the more convenient tags.
The cache policy is a set of specifications determining details of the cache and how it will behave. This includes the following:
Cache scope
Cache block naming rules
Data expiration rules
Cache repository name
You can set cache policy specifications (as described in "Attributes for Policy Specification and Use") through any of the following:
Cache tag attributes (for JSP pages)
Cache policy methods (for servlets)
External cache policy descriptor files (for JSP pages or servlets)
A cache policy object—an instance of the oracle.jsp.jwcache.CachePolicy
class—is created with policy settings based on these inputs. Because the expiration policy is part of the cache policy, each CachePolicy
object includes an attribute that is an instance of the oracle.jsp.jwcache.ExpirationPolicy
class.
Cache data can be of either session scope, where it is available to only the current HTTP session, or application scope, where it is available to all users of the application.
For example, consider an online banking application that caches the account balance. Only the current user is interested in this information, so session
scope is appropriate.
By contrast, consider an online store with a welcome page that issues the same general product recommendations to all users. In this case, it is appropriate for the page to use a cache that has application
scope.
The following sections discuss key areas of functionality of the Web Object Cache:
A cache block is associated with a cache block name, which can be determined either implicitly by the caching policy (generally advisable) or explicitly by your application code. For retrieval, to avoid regenerating the page fragment in question, there is a lookup of the cache block name.
For implicit naming, there are two inputs:
Cache policy
A cache policy API layer performs naming logic.
HTTP request object
The caching logic borrows corresponding semantics from the standard Java servlet API.
For most situations, implicit naming will result in names that are sufficiently informative, because the HTTP request usually includes all the inputs to the Web application (inputs that determine what the application should generate).
Explicit naming might be desirable in some cases, however, such as when a group of users needs to share the same data. In this case, because relevant identification information might not be available directly from the user's HTTP request, an implicit cache name would not be useful. Instead, you can write code to explicitly generate a cache name that identifies the group. Preferably, the name-generation logic should still use only request parameters as input, not other states existing inside the application. This makes the semantics easier to follow and the code easier to debug.
Following is an example of explicit naming. In the cache
tag, note the name
attribute with a JSP expression that calls someMethod()
to set the cache block name:
<ojsp:cache policy="/WEB-INF/policy1.cpd" name="<%= someObj.someMethod() %>" > ...static text... <% // dynamic content ... %> </ojsp:cache>
In the following example, because there is no name
attribute in the cache
tag, the cache block name will be determined implicitly according to the HTTP request and the cache policy:
<ojsp:cache policy="/WEB-INF/policy2.cpd" > ...static text... <% // dynamic content ... %> </ojsp:cache>
See "More About Cache Block Naming and the autoType Attribute" for more information.
Note: Cache blocks can be nested. In this case, the logic of the inner cache block will be executed only when the content of the outer block must be regenerated. |
The OC4J Web Object Cache provides an interface, oracle.jsp.jwcache.CloneableCacheObj
, that you can implement in serializable cache objects that you want to be cloneable. For mutable objects that are cached without being serialized, cloning is useful in providing a complete and hierarchical copy of the cache object. This section explains the usefulness of cloneability, first covering some necessary background information.
There are two categories of repositories that can be used as the back-end of the Web Object Cache:
Secondary storage cache repository such as a file system repository
Memory-oriented cache repository such as the Oracle Application Server Java Object Cache, the default repository of the Web Object Cache
A secondary storage repository requires Java serialization during cache operations. During storage to the cache, objects are serialized into the repository; during retrieval from the cache, they are deserialized into memory. Therefore, as a result of the serialization/deserialization process, a complete and distinct copy of the cache object is automatically created during each cache operation.
This is not the case when you store or retrieve cache objects to or from a memory-oriented repository. With a memory-oriented repository, the identical object in the user application will be stored to the cache, or the identical object in the cache will be retrieved for the user. By default, no copy is made. If there are multiple retrievals, all retrievals share the same object.
In many cases in your applications, you will want to ensure that different retrievals use different copies of a cache object. There are two key reasons for this:
If the identical cache object is shared across multiple retrievals, changes made to the data in one place might unintentionally affect values retrieved and used elsewhere.
If the identical cache object is shared across multiple retrievals, then multiple Java threads might access the same object simultaneously. This would result in thread safety issues if the original object design was not thread-safe. Perhaps, for example, the object was originally intended for page-scope or request-scope usage only, where there could be only one thread for each object. This thread-behavior assumption would be violated.
To avoid these possible problems, use complete and hierarchical copies when you store and retrieve generic Java serializable data to or from a memory-oriented repository. "Complete and hierarchical" means copying not just the direct members referenced by the object, but also any indirect variables that are referenced. For example, assume an object xyz
has a java.util.Vector
instance as a member variable. Cloning a complete and hierarchical copy involves copying not just the Vector
instance itself, but also all mutable objects or elements referenced by the Vector
instance.
If you implement the CloneableCacheObject
interface and its cloneCacheObj()
method in your cache objects, then the Web Object Cache will automatically call cloneCacheObj()
to make a complete and hierarchical copy of each cache object whenever it is stored to or retrieved from a memory-oriented cache repository.
During runtime, when a Web Object Cache cache tag is encountered, the tag handler checks whether a corresponding cache object exists and was created recently enough to reuse. If so, the code in the body of the tag is not executed; instead, the cache object is reused. But if the cache object does not exist or is too old, the tag body code will be executed to generate a new object (page fragment, XML DOM object, or Java serializable object). Then this freshly generated object will be captured, such as through special buffer writing or object passing, and stored into the cache.
If computations in content generation are costly, such as for a complicated database query, and the life span of the cache is appropriate, so that the cached data is reusable, then the Web Object Cache can save significant amounts of time and system resources. Application speed and throughput will be greatly improved.
You can set up cache blocks to expire after a specified duration or at a specified time, or they can be invalidated explicitly by a method call or tag invocation.
Because cache blocks mainly consist of semi-static fragments of information, the Oracle implementation does not require a tightly coherent expiration model. A looser model typically provides acceptable results and requires less synchronization overhead.
There are two categories of expiration for data in Web Object Cache blocks:
Duration (time-to-live): Expiration occurs after data has been in the cache for a specified amount of time.
Fixed time/day: Expiration occurs regularly at a set time, such as at a specified time each day or on a specified day each week.
Expiration details are determined by the settings of attributes in an instance of the oracle.jsp.jwcache.ExpirationPolicy
class. This ExpirationPolicy
object is an attribute of the CachePolicy
object associated with the cache block. See "Expiration Policy Attributes".
In JSP pages, you can set ExpirationPolicy
attributes through attributes of the Web Object Cache cache tags. In servlets, you can use methods of the ExpirationPolicy
object directly. (See "ExpirationPolicy Methods".) Alternatively, you can set ExpirationPolicy
attributes through a cache policy descriptor. (See "Cache Policy Descriptor".)
Instead of depending on expiration to invalidate a cache, you can invalidate it explicitly in one of the following ways:
Use the invalidateCache
tag. See "Web Object Cache invalidateCache Tag".
Use the overloaded invalidateCache()
, invalidateCacheLike()
, or invalidateCacheOtherPathLike()
method of a CachePolicy
instance to explicitly invalidate one or more cache blocks. See "CachePolicy Methods".
This section describes cache policy attributes—specifically, attributes of the CachePolicy
and ExpirationPolicy
classes. You can set these attributes through custom tags in JSP pages, directly through the provided Java API in servlets, or through a cache policy descriptor file.
Cache policies, introduced in "Cache Policy and Scope", consist of the details that determine how cache blocks behave. You can set cache policy attributes in several ways, as described in subsequent sections:
In JSP pages through custom tags
In servlets through method calls
Through a cache policy descriptor file
Specification of cache policy settings results in the creation of a cache policy object, which includes an expiration policy object as one of its attributes. Following is abbreviated code for the CachePolicy
class (in package oracle.jsp.jwcache
), for illustration purposes only, showing the names of the cache policy attributes:
class CachePolicy { boolean ignoreCache; int scope; int autoType; String selectedParameters[]; String selectedCookies[]; Date reusableTimeStamp; long reusableDeltaTime; ExpirationPolicy expirationPolicy; String cacheRepositoryName; boolean reportException; }
Note: The names documented below for integer constants are for servlet usage. Different names can be used for the Web Object Cache tags. See "Web Object Cache cache Tag". |
Table 7-1 describes cache policy object attributes.
Table 7-1 Cache Policy Attribute Descriptions
Attribute | Type | Description |
---|---|---|
ignoreCache |
boolean |
This is for use during development only. When making frequent code changes, set this to Default: |
scope |
int |
Specifies the scope of the cache. Use the integer constant Default: |
autoType |
int |
Specifies whether the cache block is named explicitly or implicitly and how properties of the HTTP request are used in cache block naming (for implicit naming). The name is relevant in determining when the cache is reused for subsequent requests. See "More About Cache Block Naming and the autoType Attribute". Default: implicitly, according to the URI plus all parameters plus selected cookies ( |
selectedParameters[] |
String [] |
These are selected request parameter names used in cache block naming, used in conjunction with Default: |
selectedCookies[] |
String[] |
These are selected cookie names used in cache block naming, used in conjunction with Default: |
reusableTimeStamp |
java.util.Date |
This is an absolute time limit for cache usability, where any cache block created prior to that time will not be reused. Instead, data is regenerated but the cache block is unaltered. See "More About reusableTimeStamp and reusableDeltaTime". Note the following regarding
Default: always reusable |
reusableDeltaTime |
long |
This is a relative time limit for cache usability, where a cache block is not reused if the difference between cache block creation time and current time is greater than Note the following regarding
Default: always reusable |
expirationPolicy |
ExpirationPolicy |
This is an expiration policy object (an instance of Default: the default expiration policy object For information about expiration policy objects, parameters, and defaults, see "Expiration Policy Attributes". |
cacheRepositoryName |
String |
This is the name of the cache repository. Each cache policy can use its own repository. The configurations of cache repositories are defined in the Default: "DefaultCacheRepository" |
reportException |
boolean |
A Default: |
As discussed in "Cache Block Naming: Implicit Versus Explicit", cache blocks can be named either implicitly, sometimes called auto-naming, or explicitly, sometimes called user-naming.
More specifically, there are six ways for cache blocks to be named. Explicit naming is the first way. Specify this with an autoType
setting of TYPE_USERSPECIFIED
(an integer constant).
The other five ways are variations of implicit naming:
Implicit naming with only the request URI being used in the name
Specify this with an autoType
setting of TYPE_URI_ONLY
.
Implicit naming according to the following:
Request URI + query string + selected cookies
Specify this with an autoType
setting of TYPE_URI_QUERYSTR
. Specify the cookies in the selectedCookies[]
attribute.
Implicit naming according to the following:
Request URI + all parameters + selected cookies (default)
Specify this with an autoType
setting of TYPE_URI_ALLPARAM
. Specify the cookies in the selectedCookies[]
attribute.
Implicit naming according to the following:
Request URI + selected parameters + selected cookies
Specify this with an autoType
setting of TYPE_URI_SELECTEDPARAM
. Specify the parameters in the selectedParameters[]
attribute and the cookies in the selectedCookies[]
attribute.
Implicit naming according to the following:
Request URI + all but excluded parameters + selected cookies
Specify this with an autoType
setting of TYPE_URI_EXCLUDEDPARAM
. Specify the cookies in the selectedCookies[]
attribute and the excluded parameters in the selectedParameters[]
attribute.
As an example, assume that you have developed a JSP page, welcome.jsp
, with a personalized greeting for each user. The data with the personalized greeting is the only cache block in the page. Further assume that you have specified "request URI + selected parameters + selected cookies" naming, with user
as the only selected parameter for cache block naming and no selected cookies for naming.
Now assume the page is requested as follows:
http://host:port/a.jsp?user=Amy
In this case, a.jsp?user=Amy
becomes the cache block name.
Now assume that the page is later requested by another user, as follows:
http://host:port/a.jsp?user=Brian
This will not reuse the "Amy" cache, because the value of user
is different. Instead, a new cache block is created with a.jsp?user=Brian
as the name.
Now assume a later request by the first user, as follows:
http://host:port/a.jsp?mypar=3&user=Amy
Because the user is again Amy, this request will reuse the first cache, displaying Amy's customized information without having to regenerate it. The mypar
parameter is irrelevant to the caching mechanism because it was not included in the selectedParameters[]
list of the cache policy object, presumably because the value of mypar
is not relevant in terms of cacheable page output.
Now assume the following subsequent request:
http://host:port/a.jsp?yourpar=4&user=Brian&hello=true&foo=barfly
Because the user is again Brian, this request will reuse the second cache, displaying Brian's customized information without having to regenerate it. The yourpar
, hello
, and foo
parameters are irrelevant to the caching mechanism because they were not included in the selectedParameters[]
list of the cache policy object.
Be aware that the concept of reusable is different than the concept of time-to-live (TTL) and is intended for more advanced use. Time-to-live, which controls the general lifetime of a cache, is described in "Expiration Policy Attributes" below. Usually time-to-live is all that is required to appropriately limit the use of cached data.
The attributes for reusability—reusableTimeStamp
and reusableDeltaTime
—are intended for more specialized use and do not affect the expiration or invalidation of cached data. As an example, consider a situation where different users have different requirements for how up-to-date a Web report is. Assume that most users can accept a report produced anytime within the past day, and that they all want to be looking at the same version so they can compare figures. An appropriate TTL
value, then, would be "one day".
Also presume, however, that there is a small group of privileged users for whom the data is much more time-sensitive. They want to have information that is no more than one hour old.
In this case, although TTL
is set to "one day" for all users, there can be a reusableDeltaTime
setting of "one hour" for the privileged users, which will result in the cache not being used for them if the data is more than one hour old. Remember, though, that reusableTimeStamp
and reusableDeltaTime
do not expire the cache or otherwise affect it. The cached data can still be used for non-privileged users, according to the time-to-live.
It is up to the application logic to set appropriate values of reusableTimeStamp
and reusableDeltaTime
for the privileged user group.
Expiration policies are introduced in "Data Invalidation and Expiration". Expiration policies contain the details that determine when cache blocks expire, at which point their data should no longer be used and the data should be regenerated instead. (Note that for most discussion, you can think of the expiration policies as being part of the cache policies.) ExpirationPolicy
attributes, as with CachePolicy
attributes, can be set in any of the following ways:
In JSP pages through custom tags
In servlets through method calls
Through a cache policy descriptor file
The following abbreviated code for the ExpirationPolicy
class (in package oracle.jsp.jwcache
), provided for illustration purposes only, shows the names of the expiration policy attributes:
class ExpirationPolicy { int expirationType; long TTL; long timeInaDay; int dayInaWeek; int dayInaMonth; boolean writeThrough; }
Table 7-2 describes the expiration policy object attributes.
Note: The names documented below for integer constants are for servlet usage. Different names can be used for the Web Object Cache tags. See "Web Object Cache cache Tag". |
Table 7-2 Expiration Policy Attribute Descriptions
Attribute | Type | Description |
---|---|---|
expirationType |
int |
This is the type of expiration policy and is one of the following, where
Default: time-to-live |
TTL |
long |
This is time-to-live, the amount of time the cache block is good for, expressed in seconds. The value must be a positive number. Default: 300 (5 minutes) |
timeInaDay |
long |
This is the time of day used for daily, weekly, or monthly expiration, expressed in seconds from midnight, where 0 is 00:00:00 (midnight) and 86399 is 23:59:59. Default: 300 (00:05:00); ignored if |
dayInaWeek |
int |
This is the day of the week for weekly expiration, at the specified Default: Wednesday; ignored unless |
dayInaMonth |
int |
This is the date of the month for monthly expiration, such as 10 for the 10th of each month, at the specified Default: 10; ignored unless |
writeThrough |
boolean |
This flag specifies whether the cache repository should treat the cache entry as a write-through cache, writing it immediately into secondary storage such as a file system or database. Set this to With a Note that some cache repositories might not support write-through mode; others might always use write-through mode. Default: |
From JSP pages, you can specify cache policy settings, expiration policy settings, and explicit invalidation through custom tags provided with OC4J. The following sections describe the tags:
Note the following requirements for the Web Object Cache tag library:
The Web Object Cache classes are in the file ojsputil.jar
, which is supplied with OC4J and is located in the "well-known" tag library directory. Verify that this file is installed and in your classpath.
To use the Oracle Application Server Java Object Cache as the back-end repository, the file cache.jar
must be installed and in your classpath. This file also comes with OC4J. In the OC4J 10.1.2 implementation, cache.jar
is listed in the manifest classpath of oc4j.jar
. If the Web Object Cache tag library is loaded by OC4J, then no action on your part is necessary.
The tag library descriptor, jwcache.tld
, must be available to the application, and any JSP page using the library must have an appropriate taglib
directive. In an Oracle Application Server installation, the TLD is in ojsputil.jar
. The uri
value for jwcache.tld
is the following:
http://xmlns.oracle.com/j2ee/jsp/tld/ojsp/jwcache.tld
You can refer to the Oracle Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide for information about taglib
directives, the well-known tag library directory, TLD files, and the meaning of uri
values.
Notes:
|
This section describes the following tags:
cache
This tag is for general character-based caching (HTML or XML fragments).
cacheXMLObj
This tag is for caching XML objects; its parameters are a superset of the cache
tag parameters. Because the Web Object Cache is particularly useful when post-processing XML documents, you will likely use the cacheXMLObj
tag more often than the cache
tag.
useCacheObj
This tag is for general caching of Java serializable objects. Some of the semantics and syntax are patterned after the standard jsp:useBean
tag.
cacheInclude
This tag combines the functionality of the cache
tag with that of the standard jsp:include
tag.
This section also describes conditional execution of code within the cache tags, possible resulting problems, the workaround of dividing cache blocks into individual JSP pages, and, optionally, using the cacheInclude
tag to combine the pages together appropriately.
This section documents the syntax and attributes of the cache
tag, which you can use to set up general caching in a JSP application, in contrast to the caching of XML objects or Java serializable object.
Note: For caching XML objects, use thecacheXMLObj tag instead. For caching Java serializable objects, use the useCacheObj tag. These tags support all the cache tag attributes described here. See "Web Object Cache cacheXMLObj Tag" and "Web Object Cache useCacheObj Tag".
|
<ojsp:cache [ policy = "filename" ] [ ignoreCache = "true" | "false" ] [ invalidateCache = "true" | "false" ] [ scope = "application" | "session" ] [ autoType = "user" | "URI" | "URI_query" | "URI_allParam" | "URI_selectedParam" | "URI_excludedParam" ] [ selectedParam = "space-delimited_string_of_parameter_names" ] [ selectedCookies = "space-delimited_string_of_cookie_names" ] [ reusableTimeStamp = "yyyy.mm.dd hh:mm:ss z" | "yyyy.mm.dd hh:mm:ss" | "yyyy.mm.dd"| "ignored" ] [ reusableDeltaTime = "number" | "ignored" ] [ name = "blockname" ] [ expirationType = "TTL" | "daily" | "weekly" | "monthly" ] [ TTL = "number" ] [ timeInaDay = "number" ] [ dayInaWeek = "Sunday" | "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" ] [ dayInaMonth = "number" ] [ writeThrough = "true" | "false" ] [ printCacheBlockInfo = "true" | "false" ] [ printCachePolicy = "true" | "false" ] [ cacheRepositoryName = "name" ] [ reportException = "true" | "false" ] > ...Code for cache block... </ojsp:cache>
Note: Key default values are as follows:TTL 300 seconds, dayInaMonth 10 (10th of the month), cache repository name DefaultCacheRepository .
|
Most of the parameters of the cache
tag correspond to attributes in the CachePolicy
or ExpirationPolicy
class, described earlier in this chapter (as referenced below).
policy
: Optionally use this to specify a cache policy descriptor, the settings of which would be used in defining the cache policy. You can use a cache policy descriptor instead of using the various individual cache tag attribute settings, or to establish default values that you can optionally override through tag attribute settings.
Specify the descriptor file name according to JSP application-relative syntax. You can refer to the Oracle Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide for information about application-relative syntax.
Here is a simple example of a cache policy descriptor:
<!-- test-policy.cpd --> <cachePolicy scope="application"> <expirationPolicy expirationType="TTL" TTL="25" timeInaDay="00:10:00" writeThrough="true" /> </cachePolicy>
See "Cache Policy Descriptor" for more information.
ignoreCache
: See "Cache Policy Attributes".
invalidateCache
: Enable this flag for the corresponding cache block (any pre-existing cache block with the same name) to first be invalidated. This is particularly useful where implicit cache block naming is used, but can also be used for explicit names by specifying the cache block name in the name
attribute of the cache
tag. The default setting is "false
".
Note: Do not confuse this attribute with the more general-purposeinvalidateCache tag. See "Web Object Cache invalidateCache Tag". The invalidateCache attribute is for more specialized or advanced use to invalidate individual cache blocks.
|
scope
: See "Cache Policy Attributes".
autoType
: See "Cache Policy Attributes". The correspondence between tag attribute settings and class attribute values (integer constants) is as follows:
The user
setting is equivalent to TYPE_USERSPECIFIED
.
URI
is equivalent to TYPE_URI_ONLY
.
URI_query
is equivalent to TYPE_URI_QUERYSTR
.
URI_allParam
is equivalent to TYPE_URI_ALLPARAM
.
URI_selectedParam
is equivalent to TYPE_URI_SELECTEDPARAM
.
URI_excludedParam
is equivalent to TYPE_URI_EXCLUDEDPARAM
.
selectedParam
: See "Cache Policy Attributes".
selectedCookies
: See "Cache Policy Attributes".
reusableTimeStamp
: See "Cache Policy Attributes".
reusableDeltaTime
: See "Cache Policy Attributes".
name
: Where you use explicit cache-block naming, use the name
parameter to specify the block name.
expirationType
: See "Expiration Policy Attributes".
TTL
: See "Expiration Policy Attributes".
timeInaDay
: See "Expiration Policy Attributes".
dayInaWeek
: See "Expiration Policy Attributes".
dayInaMonth
: See "Expiration Policy Attributes".
writeThrough
: See "Expiration Policy Attributes".
printCacheBlockInfo
(for debugging): Enabling this parameter results in printing of the internal cache name, creation time, and expiration time of the cache block, within HTML or XML comment constructs. The default setting is "false
".
printCachePolicy
(for debugging): Enabling this parameter results in printing of the values of all cache policy attributes for this cache block, within HTML or XML comment constructs. The default setting is "false
".
cacheRepositoryName
: See "Cache Policy Attributes".
reportException
: See "Cache Policy Attributes".
The name
attribute is relevant only when autoType
is set to user
.
The selectedParam
attribute is relevant only when autoType
is set to URI_selectedParam
or URI_excludedParam
.
The selectedCookies
attribute is not relevant when autoType
is set to user
or URI
.
The timeInaDay
attribute is not relevant when expirationType
is set to TTL
.
The dayInaWeek
attribute is relevant only when expirationType
is set to weekly
.
The dayInaMonth
attribute is relevant only when expirationType
is set to monthly
.
This example lists and caches a set of items, using the cache
tag.
<%@ taglib uri="http://xmlns.oracle.com/j2ee/jsp/tld/ojsp/jwcache.tld" prefix="ojsp" %> <title>listitem.jsp</title> <% String itemid=request.getParameter("itemid"); if (itemid==null) { out.println("Please select a category from the above drop down box."); return; } %> <% long l1=(new java.util.Date()).getTime(); %> <ojsp:cache autoType="URI_selectedParam" selectedParam="itemid" printCacheBlockInfo="true" printCachePolicy="true" policy="/WEB-INF/test-policy.cpd" > Item List: <b><%= itemid %></b><br> Time: <%= new java.util.Date() %> <br> <jsp:useBean class="java.util.Hashtable" id="table" scope="application" /> <hr> <% Vector list=(Vector) table.get(itemid); if (list==null) { out.println("No such item!"); } else { for (int i=0; i<list.size(); i++) { %> <%= list.elementAt(i) %><br> <% } } %> timestamp:<%= new java.util.Date() %> <br> </ojsp:cache> <% long l2=(new java.util.Date()).getTime(); %> Time for general cache operation:<%= l2-l1 %> <br>
Generally speaking, use the cacheXMLObj
tag instead of the cache
tag if you are caching XML DOM objects.
The cacheXMLObj
tag supports all the cache
tag attributes described in "Web Object Cache cache Tag", as well as the attributes described here.
<ojsp:cacheXMLObj ... [ fromXMLObjName = "objectname" ] [ toXMLObjName = "objectname" ] [ toWriter = "true" | "false" ] > [...Code for cache block...] </ojsp:cacheXMLObj>
Notes:
|
fromXMLObjName
: For explicit passing, specify the name of the XML input object being passed to the cache (from the pageContext
object).
toXMLObjName
: For explicit passing, specify the name of the XML output object being passed from the cache (to the pageContext
object).
toWriter
: Set this to "true
" to write the XML object to a JSP writer to output directly to the user's browser. The default value is "false
".
Note: ThecacheXMLObj tag is one of several custom tags supplied with OC4J that are XML-related, meaning these tags sometimes (or always) take an XML object as input or create one as output. Other such tags include the SQL library dbQuery tag, which can output query results as an XML DOM object, and the XML library transform and styleSheet tags, which can take an XML object as input and use XSLT transformation to create another XML object or a JSP writer as output. These tags are consistent in having a fromXMLObjName attribute and a toXMLObjName attribute for explicit passing of XML data. For general information, see "XML Producers and XML Consumers".
|
This example uses Web Object Cache tags, JESI tags, and tags from the XML and SQL tag libraries. (For JESI tag descriptions, see "Oracle JESI Tag Descriptions". For a description of the XML transform
tag, see "XML Utility Tags". For SQL tag descriptions, see "SQL Tags for Data Access".)
The SQL dbOpen
and SQL dbQuery
tags connect to the database and execute a query. The cacheXMLObj
tag caches the XML DOM object produced by the query. In subsequent executions (for output through different stylesheets, for example), the query does not have to be reexecuted, because the DOM object can be retrieved from the Web Object Cache. The XML transform
tag outputs the query results according to an XML stylesheet, specified through a variable. The JESI fragment
tag encloses HTML output to be cached, which does not require application-level caching. The JESI template
tag disables caching outside the fragment, through the cache="no"
setting.
<jesi:template cache="no"> <% String userStyleLoc="style/rowset.xsl"; %> <h3>Transform DBQuery Tag Example</h3> <h4>Current Time=<%= new java.util.Date() %></h4> <jesi:fragment expiration="60"> <!-- You can cache HTML in OracleAS Web Cache with JESI or you can cache it in Oracle Web Object Cache --> <h4>Cached Time=<%= new java.util.Date() %></h4> <sql:dbOpen connId="conn1" dataSource="<%= dataSrcStr %>" /> <xml:transform href="<%= userStyleLoc %>" > <%-- The XML DOM object is produced by dbQuery And, the DOM object is cached in Oracle Web Object Cache. XSLT is performed on the cached object. --%> <ojsp:cacheXMLObj TTL="60" toWriter="false"> <sql:dbQuery connId="conn1" output="xml" queryId="myquery" > select ENAME, EMPNO from EMP </sql:dbQuery> </ojsp:cacheXMLObj> </xml:transform> <sql:dbCloseQuery queryId="myquery" /> <sql:dbClose connId="con1" /> </jesi:fragment> </jesi:template>
Use the useCacheObj
tag to cache any Java serializable object.
The useCacheObj
tag supports all the cache
tag attributes described in "Web Object Cache cache Tag", as well as the attributes described here.
<ojsp:useCacheObj ... type="classname" id = "instancename" [ cacheScope = "application" | "session" ] > ...Code for cache block... </ojsp:useCacheObj>
Note: Theid and type attributes are not request-time attributes, so cannot be set using JSP runtime expressions.
|
type
(required): Specify the class name of the Java object to cache.
id
(required): Specify the instance name of the Java object to cache.
cacheScope
: This attribute has the same usage as the scope
attribute in the cache
and cacheXMLObj
tags. See "Cache Policy Attributes".
The type
and id
attributes here are used similarly to the type
(or class
) and id
attributes in a jsp:useBean
tag.
<ojsp:useCacheObj id="a2" policy="/WEB-INF/test-policy.cpd" type="examples.RStrArray" > <% // create a temp writeable array WStrArray tmpa2=new WStrArray(3); tmpa2.setStr(2,request.getParameter("testing4")); tmpa2.setStr(1,"def"); tmpa2.setStr(0, (new java.util.Date()).toString() ); // create a readonly copy for the cache a2=new RStrArray(tmpa2); // storing the a2 into pagecontext // so useCacheObj tag can pick it up pageContext.setAttribute("a2",a2); %> </ojsp:useCacheObj>
Be aware that code inside a cache tag (cache
, cacheXMLObj
, or useCacheObj
) is executed conditionally. In particular:
Any code inside a cache tag is executed only when the associated cache block is not reused.
Consider the following example:
<% String str=null; %>
<% ojsp:useCacheObj ... >
<% str = "abc"; //...more Java code...%>
</ojsp:useCacheObj>
<% out.print(str.length()); // May cause null pointer exception
If the cache is available and reused, the code to properly initialize the string str
is not executed.
If you put a method-based variable declaration inside a cache tag, the variable is not available outside the tag.
Consider the following example:
<ojsp:useCacheObj ... >
<% String str = "abc"; //...more Java code...%>
</ojsp:useCacheObj>
<% // String str will not be available here %>
If you are using the cache
tag (not cacheXMLObj
or useCacheObj
), it might be helpful to break your cache blocks into separate JSP pages so that you would be less likely to fall into this type of situation. In this case, each cache block would be represented by its own URI and you could use dynamic-include functionality to combine the pages together as desired.
To make this more convenient, Oracle also provides the cacheInclude
tag, described in the following section, "Web Object Cache cacheInclude Tag".
The cacheInclude
tag combines functionality of the cache
tag (but not the cacheXMLObj
tag or useCacheObj
tag) and the standard jsp:include
tag.
There are a number of advantages in putting cache blocks into separate pages and using cacheInclude
, including general considerations of modularity and clarity as well as the issues discussed in the preceding section, "Conditional Execution of Code Inside the Cache Tags".
Be aware of the following limitations, however:
You cannot use a runtime JSP expression in the cacheInclude
tag.
You must use implicit cache-block naming for the cache block.
There is no flush
parameter, unlike for the jsp:include
tag.
If any of these limitations presents a problem, then use separate cache
and jsp:include
tags.
Also be aware of an important difference between the cacheInclude
tag and the JESI include
tag. (See "JESI include Tag" for information about that tag.) Because the OracleAS Web Cache is in a different caching layer than the Web Object Cache, the including page and included page for a JESI include
tag cannot share the same request object. There is no such limitation with the cacheInclude
tag, however. The including page and included page share the same request object, so beans and attributes of request
scope can be passed between the two pages.
<ojsp:cacheInclude policy = "filename" page = "URI" [ printCacheBlockInfo = "true" | "false" ] [ reportException = "true" | "false" ] > ...Code for cache block... </ojsp:cacheInclude>
Note: For thecacheInclude tag, because policy and page are not request-time attributes, you do not have the option of determining their values through JSP expressions. (Be aware that policy is a request-time attribute for the cache , cacheXMLObj , and useCacheObj tags.)
|
policy
(required): You must use a cache policy descriptor file to specify cache policy settings; individual parameter settings are not supported.
page
(required): Use the page
attribute to specify the URI of the page to dynamically include, as with a standard jsp:include
tag.
printCacheBlockInfo
(for debugging): See "Web Object Cache cache Tag".
reportException
: See "Cache Policy Attributes".
Consider the following cacheInclude
tag usage:
<ojsp:cacheInclude page="anotherPage.jsp" policy="foo.cpd" >
This is equivalent to the following:
<ojsp:cache policy="foo.cpd" > <% pageContext.include("anotherPage.jsp"); %> </ojsp:cache>
It is also equivalent to the following:
<jsp:include page="anotherPage.jsp" flush="true" />
Assume anotherPage.jsp
consists of the following:
<ojsp:cache policy="foo.cpd" >
...anotherPage.jsp contents...
</ojsp:cache>
This section describes how to use the invalidateCache
tag.
To explicitly invalidate a cache block through program logic, you can use the invalidateCache
tag. This section documents the syntax and attributes of this tag.
Notes:
|
<ojsp:invalidateCache [ policy = "filename" ] [ ignoreCache = "true" | "false" ] [ scope = "application" | "session" ] [ autoType = "user" | "URI" | "URI_query" | "URI_allParam" | "URI_selectedParam" | "URI_excludedParam" ] [ selectedParam = "space-delimited_string_of_parameter_names" ] [ selectedCookies = "space-delimited_string_of_cookie_names" ] [ name = "blockname" ] [ invalidateNameLike = "true" | "false" ] [ page = "URI" ] [ autoInvalidateLevel = "application" | "page" | "param" | "cookie" ] [ cacheRepositoryName = "name" ] [ reportException = "true" | "false" ] />
Note: The default value ofautoInvalidateLevel depends on specifics of the page URI. See "Use of page and autoInvalidateLevel".
|
Most parameters of the invalidateCache
tag also exist in the cache
and cacheXMLObj
tags and are used in the same way, as described earlier in this chapter (and as referenced below).
policy
: See "Web Object Cache cache Tag".
ignoreCache
: See "Cache Policy Attributes".
scope
: See "Cache Policy Attributes".
autoType
: See "Cache Policy Attributes". The correspondence between tag attribute settings and class attribute values (integer constants) is as follows:
The user
setting is equivalent to TYPE_USERSPECIFIED
.
URI
is equivalent to TYPE_URI_ONLY
.
URI_query
is equivalent to TYPE_URI_QUERYSTR
.
URI_allParam
is equivalent to TYPE_URI_ALLPARAM
.
URI_selectedParam
is equivalent to TYPE_URI_SELECTEDPARAM
.
URI_excludedParam
is equivalent to TYPE_URI_EXCLUDEDPARAM
.
selectedParam
: See "Cache Policy Attributes".
selectedCookies
: See "Cache Policy Attributes".
name
: Use this with invalidateNameLike
to invalidate one or more cache blocks that were named through explicit cache-block naming, according to the instructions in "Use of name and invalidateNameLike" below.
invalidateNameLike
: Use this with name
to invalidate one or more cache blocks that were named through explicit cache-block naming, according to the instructions in "Use of name and invalidateNameLike" below. The default setting is "false
".
page
: Specify a page-relative or application-relative URI. Use this with autoInvalidateLevel
to invalidate one or more cache blocks that were named through implicit cache-block naming, according to the instructions in "Use of page and autoInvalidateLevel" below.
autoInvalidateLevel
: Use this with page
to invalidate one or more cache blocks that were named through implicit cache-block naming, according to the instructions in "Use of page and autoInvalidateLevel" below.
cacheRepositoryName
: See "Cache Policy Attributes".
reportException
: See "Cache Policy Attributes".
To invalidate one or more cache blocks that were named through explicit cache-block naming, use the name
and invalidateNameLike
attributes together, as follows:
If invalidateNameLike="false"
, then use the name
parameter to specify the name of a single cache block to invalidate.
If invalidateNameLike="true"
, and the underlying cache repository supports wild card characters, then you can use the wildcard "*" character in the name
parameter to invalidate multiple cache blocks whose names fit the criteria. (The Oracle Application Server Java Object Cache currently does not support wild card characters.)
To invalidate one or more cache blocks that were named through implicit cache-block naming, use the page
and autoInvalidateLevel
attributes together.
Use the page
attribute to specify the appropriate URI of the Web page. With implicit naming, cache block names are based on Web page URIs.
Use autoInvalidateLevel
to specify the scope of invalidation—application
scope, page
scope, parameter
scope, or cookie
scope—as follows:
If autoInvalidateLevel="application"
, then all cache blocks associated with the application that the page belongs to will be invalidated.
For example, if there is an application under the /mycontext
context path, and autoInvalidateLevel="application"
, then all cache entries of all pages under http://
host
:
port
/mycontext
will be invalidated.
Here is a corresponding usage example:
<ojsp:invalidateCache page="/" autoInvalidateLevel="application" />
If autoInvalidateLevel="page"
, then all cache block entries associated with the page will be invalidated. Consider the following example:
http://host:port/mycontext/mypage01.jsp?foo=bar
For this request, if autoInvalidate="page"
, then all cache entries of mypage01.jsp
will be invalidated, regardless of what request parameters and cookies they are associated with. This includes cache blocks associated with the following, for example:
http://host:port/mycontext/mypage01.jsp?p1=v1
Here is a corresponding usage example:
<ojsp:invalidateCache page="/mypage01.jsp" autoInvalidateLevel="page" />
If autoInvalidateLevel="param"
, then all cache entries of the page that have the identical selected parameter names and values will be invalidated, regardless of what cookies they are associated with.
For example, consider the following:
<ojsp:invalidateCache policy="/WEB-INF/c1.cpd" page="/mypage01.jsp?foo=bar" autoInvalidateLevel="param" />
In this case, cache blocks associated with the following, for example, will not be invalidated:
http://host:port/mycontext/mypage01.jsp?foo=bar2
However, cache blocks associated with the following will be invalidated, regardless of what cookies they are associated with:
http://host:port/mycontext/mypage01.jsp?foo=bar
Continuing this example, consider the following:
http://host:port/mycontext/mypage01.jsp?foo=bar&p1=v1
Cache blocks associated with this request will be invalidated if c1.cpd
selects the foo
HTTP request parameter only, and the cache blocks are stored under the same cache policy, c1.cpd
. However, the cache objects will not be invalidated if they were not stored under c1.cpd
, or if c1.cpd
also selects the p1
parameter.
If autoInvalidateLevel="cookie"
, then the only cache entries invalidated are those associated with the same page, same selected parameters and values, and same cookies.
Note: If the page URI includes a question mark, then the defaultautoInvalidateLevel is param . If there is no question mark, then the default is page .
|
This section provides a brief example of cache invalidation.
The following page adds an item to a list of items previously cached, then invalidates the cache. The list will presumably be re-cached later with the new item.
<%@ taglib uri="http://xmlns.oracle.com/j2ee/jsp/tld/ojsp/jwcache.tld" prefix="ojsp" %> <title>added.jsp</title> <jsp:useBean class="java.util.Hashtable" id="table" scope="application" /> <% String itemid=request.getParameter("itemid"); String addItem=request.getParameter("addItem"); Vector list=(Vector) table.get(itemid); if (list==null) { list=new Vector(); table.put(itemid,list); } list.addElement(addItem); %> <b><%= addItem %></b> was added into category <b><%= itemid %></b>.<br> <% String viewPage="listitem.jsp?itemid="+itemid; %> <% long l1=(new java.util.Date()).getTime(); %> <ojsp:invalidateCache page="<%= viewPage %>" autoInvalidateLevel="param" policy="/WEB-INF/test-policy.cpd" /> <% long l2=(new java.util.Date()).getTime(); %> Existing cache entry has been invalidated. <br> Invalidation took <%= l2-l1 %> milliseconds. <br> <jsp:include page="<%= viewPage %>" flush="true" /> <br> <a href="seeitems.jsp" >Select items</a> or <a href="additem.html" >Add items</a> <br>
From servlets, you can use CachePolicy
methods to modify cache policy settings or to invalidate a cache block, and ExpirationPolicy
methods to modify expiration settings. This requires creating a cache policy object and retrieving its expiration policy object attribute, which the JSP cache tag handlers do automatically.
The following sections describe the API:
The Web Object Cache classes discussed here are in the oracle.jsp.jwcache
package and are supplied in the file ojsputil.jar
, which comes with OC4J. Verify that this file is installed and in your classpath. Also, to use the Oracle Application Server Java Object Cache as the back-end repository, the file cache.jar
must be installed and in your classpath. This file also comes with OC4J.
For more information about the classes, interfaces, and methods described in this section, see the Javadoc that is supplied with OC4J.
There are two approaches to creating a CachePolicy
object:
Use the static lookupPolicy()
method of the CacheClientUtil
class.
Use one of the public CachePolicy
constructors.
Note: Cache policy objects are not resource objects, such as database connections or cursors, so you can manipulate them without life-cycle or resource management concerns. |
In most situations, the most convenient way to create a CachePolicy
object is through the static lookupPolicy()
method of the CacheClientUtil
class, as in the following example:
CachePolicy cachePolicyObject = oracle.jsp.jwcache.CacheClientUtil.lookupPolicy (servletConfig, request, "/WEB-INF/foo.cpd");
Input a servlet configuration object (a javax.servlet.ServletConfig
instance), a request object (a javax.servlet.http.HttpServletRequest
instance), and the URI path, relative to the application root, of an XML cache policy descriptor file.
Here is a simple example of a cache policy descriptor file:
<!-- test-policy.cpd --> <cachePolicy scope="application"> <expirationPolicy expirationType="TTL" TTL="25" timeInaDay="00:10:00" writeThrough="true" /> </cachePolicy>
See "Cache Policy Descriptor" for more information.
The CachePolicy
class has three public constructors: a simple constructor requiring only a servlet configuration object, a "copy" constructor that copies another CachePolicy
object, and a "copy" constructor with a given servlet configuration object, as follows:
public CachePolicy(javax.servlet.ServletConfig config) public CachePolicy(CachePolicy cPolicy) public CachePolicy(javax.servlet.ServletConfig config, CachePolicy cPolicy)
Several utility methods are available in CachePolicy
objects, as well as getter and setter methods for key attributes.
The following abbreviated code, for illustration purposes only, contains signatures for key methods available in CachePolicy
objects.
See "Cache Policy Attributes" for a discussion of relevant attributes.
class CachePolicy { boolean isRecent(CacheBlock block); void putCache(Object data, HttpServletRequest req, SectionId sectionId); void putCache(Object data, HttpServletRequest req, String specifiedName); void putAutoCacheForOtherPath(Object data, HttpServletRequest req, String otherPath, StringSectionid sectionId); void putAutoCacheForOtherPath(Object data, HttpServletRequest req, String otherPath, Cookie[] newCookies, StringSectionid sectionId); CacheBlock getCache(HttpServletRequest req, SectionId sectionId); CacheBlock getCache(HttpServletRequest req, String specifiedName); CacheBlock getAutoCacheForOtherPath(HttpServletRequest req, String otherPath, StringSectionId sectionId); CacheBlock getAutoCacheForOtherPath(HttpServletRequest req, String otherPath, Cookie[] newCookies, StringSectionId sectionId); void invalidateCache(HttpServletRequest req, SectionId sectionId); void invalidateCache(HttpServletRequest req, String specifiedName); void invalidateCacheLike(HttpServletRequest req, String specifiedName); void invalidateCacheLike(HttpServletRequest req, int autoInvalidateLevel); void invalidateCacheLike(HttpServletRequest req, String specifiedName, int autoInvalidateLevel); void invalidateCacheOtherPathLike(HttpServletRequest req, String otherPath); void invalidateCacheOtherPathLike(HttpServletRequest req, String otherPath, Cookie[] newCookies, int autoInvalidateLevel); Date getCurrentTime(); }
These methods use several common parameters:
req
, a javax.servlet.http.HttpServletRequest
instance
This is the current HTTP request object.
newCookies
, a javax.servlet.http.Cookie[]
array
This is an array of new cookies. If you pass in new cookies, they are used in cache operations that use the otherPath
parameter (such as the putAutoCacheForOtherPath()
method), assuming the cache policy selects some cookies and invalidation is at the cookie level. If you do not pass in new cookies, then cookies of the current HTTP request are used instead.
specifiedName
, a Java string
For explicit cache-block naming, this is the name—either the desired cache block name if you are creating a new cache block, or the existing cache block name if you are retrieving an existing cache block.
sectionId
, an oracle.jsp.jwcache.SectionId
instance, specifically a StringSectionId
or NumberSectionId
instance
For implicit cache-block naming, this is a counter that is used in tracking cache blocks. In JSP pages, it is used, incremented, and maintained by JSP cache tag handlers. It is stored in the JSP pageContext
object.
SectionId
is an interface that is implemented by two classes: StringSectionId
and NumberSectionId
. Where StringSectionId
is specified in a method signature, you must use an instance of that class. Where SectionId
is specified, you can use an instance of either class, but should typically use StringSectionId
. The NumberSectionId
class is primarily intended for use by JSP tag handlers.
In a servlet, you must create a section ID instance manually. "Servlet Page: DemoCacheServlet.java" demonstrates the use of a StringSectionId
instance.
Note: When you construct aStringSectionId instance, the string must begin with an alphabetic (not numeric) character.
|
otherPath
, a Java string
This is the URI of another JSP page that has an associated cache block that you want to store, retrieve, or invalidate.
autoInvalidateLevel
, an integer
For implicit cache-block naming, you can use this to specify a level of invalidation, either application
, page
, parameter
, or cookie
. Use the CachePolicy
integer constant AUTO_INVALIDATE_APP_LEVEL
, AUTO_INVALIDATE_PAGE_LEVEL
, AUTO_INVALIDATE_PARAM_LEVEL
, or AUTO_INVALIDATE_COOKIE_LEVEL
.
The CachePolicy
methods function as follows:
isRecent()
This method checks the timestamp of the specified cache block and determines whether it is recent enough, given the current time and the values of the cache policy reusableTimeStamp
and reusableDeltaTime
attributes.
putCache(data)
Use this method to place an object into the cache repository. The data
parameter is any serializable Java object you want to cache that will not require any further modification or mutation. In JSP pages, the JSP cache
tag handler calls putCache()
to cache a BodyContent
instance. The cacheXMLObj
tag handler calls it to cache an XML DOM object. In a servlet or useCacheObj
tag, the cache target object can be any Java serializable object.
You must also provide an HTTP request object, along with a cache block name (for explicit naming) or a section ID (for implicit naming).
Note: TheputCache() method does nothing if the cache policy ignoreCache attribute is set to "true ".
|
putAutoCacheForOtherPath(...)
Place the specified object into the cache repository according to a specified string-based section ID and a specified page path, optionally using specified cookies as well. You must also input an HttpServletRequest
object. The cache policy must not use explicit naming (in other words, must not have autoType=TYPE_USERSPECIFIED
).
getCache(...)
Use this method to retrieve a cached item from the repository, in the form of a CacheBlock
instance. You can specify the cache block name (for explicit naming) or the section ID (for implicit naming). You must also provide an HTTP request object.
Note: ThegetCache() method does nothing if the cache policy ignoreCache attribute is true .
|
getAutoCacheForOtherPath(...)
Retrieve a cached item from the repository according to a specified string-based section ID and a specified page path, optionally using specified cookies as well. You must also input an HttpServletRequest
object. The cache policy must not use explicit naming, otherwise an exception is thrown. (In other words, you cannot have autoType=TYPE_USERSPECIFIED
.)
invalidateCache(...)
Use this method to invalidate a single cache block. Invalidation is according to the HTTP request object and also according to the specified cache block name (for explicit naming) or section ID (for implicit naming).
invalidateCacheLike(...)
Use this method to invalidate multiple cache blocks. If you use explicit cache-block naming and the cache repository supports wild-card naming, you can input the specifiedName
parameter with "*" wild card characters. The Oracle Application Server Java Object Cache currently does not support wild card characters.
If you use implicit cache-block naming, you must specify the autoInvalidateLevel
parameter to determine, in combination with the HttpServletRequest
object and optionally the specifiedName
parameter, what cache blocks are invalidated. The autoInvalidateLevel
parameter has the same functionality as in a JSP invalidateCache
tag, as explained in "Web Object Cache invalidateCache Tag" (using information from the request object, instead of using information from the page
parameter of the invalidateCache
tag).
invalidateCacheOtherPathLike(...)
Use this method to invalidate cache blocks associated with the URI you provide in the otherPath
parameter. In the signature taking only a request object and the URI, the autoInvalidateLevel
parameter is set automatically according to the URI. It is set to param
level if there is a question mark ("?
") in the URI or to page
level otherwise.
The detailed signature of this method enables you to specifically control the autoInvalidateLevel
setting and the cookies used in invalidation.
getCurrentTime()
Retrieve the current time value, as a java.util.Date
instance, of the underlying cache repository specified in this cache policy.
You can use the following methods to retrieve or alter CachePolicy
object attributes. See "Cache Policy Attributes" for a discussion of these attributes.
boolean getIgnoreCache()
void setIgnoreCache(boolean ignoreCache)
void setIgnoreCache(String ignoreCacheStr)
int getScope()
void setScope(int scope)
For scope
values, use the integer constants SCOPE_APP
and SCOPE_SESSION
.
int getAutoType()
void setAutoType(int autoType)
For autoType
values, use the integer constants TYPE_USERSPECIFIED
, TYPE_URI_ONLY
, TYPE_URI_QUERYSTR
, TYPE_URI_ALLPARAM
, TYPE_URI_SELECTEDPARAM
, and TYPE_URI_EXCLUDEDPARAM
.
String[] getSelectedParam()
void setSelectedParam(String[] selectedParameters)
void setSelectedParam(String selectedParamStr)
String[] getSelectedCookies()
void setSelectedCookies(String[] selectedCookies)
void setSelectedCookies(String selectedCookiesStr)
Date getReusableTimeStamp()
void setReusableTimeStamp(Date reusableTimeStamp)
void setReusableTimeStamp(long reusableTimeStamp)
For reusableTimeStamp
values, the integer constant REUSABLE_ALWAYS
indicates that the cache is always reusable.
long getReusableDeltaTime()
void setReusableDeltaTime(long reusableDeltaTime)
For reusableDeltaTime
values, the integer constant REUSABLE_ALWAYS
indicates that the cache is always reusable.
ExpirationPolicy getExpirationPolicy()
void setExpirationPolicy(ExpirationPolicy expirationPolicy)
String getCacheRepositoryName()
void setCacheRepositoryName(String repoName)
boolean getReportException()
void setReportException(boolean reportException)
void setReportException(String reportExceptionStr)
The following methods are also available, but are primarily intended for use by the Web Object Cache tag handlers:
void setScope(String scopeStr)
For scope
values, there are the string constants SCOPE_APP_STR
and SCOPE_SESSION_STR
.
void setAutoType(String autoTypeStr)
void setReusableTimeStamp(String reusableTimeStampStr)
For reusableTimeStamp
values, the string constant REUSABLE_IGNORED
indicates that the cache is always reusable.
void setReusableDeltaTime(String reusableDeltaTimeStr)
For reusableDeltaTime
values, the string constant REUSABLE_IGNORED
indicates that the cache is always reusable.
Each CachePolicy
object has an ExpirationPolicy
attribute. If you want to set expiration policies for a cache block, you can use the getExpirationPolicy()
method of its CachePolicy
object, as in the following example:
CachePolicy cachePolicyObj = CacheClientUtil.lookupPolicy (config, request, "/WEB-INF/mypolicy.cpd"); ExpirationPolicy expPolicyObj = cachePolicyObj.getExpirationPolicy();
The ExpirationPolicy
class has getter and setter methods for its attributes, as follows. For descriptions of these attributes, see "Expiration Policy Attributes".
int getExpirationType()
void setExpirationType(int expirationType)
void setExpirationType(String expirationTypeStr)
long getTTL()
void setTTL(long ttl)
long getTimeInaDay()
void setTimeInaDay(long timeInaDay)
void setTimeInaDay(String timeInaDayStr)
int getDayInaWeek()
void setDayInaWeek(int dayInaWeek)
void setDayInaWeek(String dayInaWeekStr)
int getDayInaMonth()
void setDayInaMonth(int dayInaMonth)
boolean getWriteThrough()
void setWriteThrough(boolean writeThrough)
void setWriteThrough(String writeThroughStr)
Additionally, the ExpirationPolicy
class has the following utility method:
long getExpirationTime(long createTime)
Given the creation time of a cache block expressed in milliseconds since midnight January 1, 1970, this method calculates and returns the expiration time, also in milliseconds since midnight January 1, 1970. That is, the timestamp when expiration should occur, according to the expiration policy.
The ExpirationPolicy
class also defines the following integer constants for the expirationType
attribute:
TYPE_TTL
TYPE_DAILY
TYPE_WEEKLY
TYPE_MONTHLY
And the following integer constants are defined for the dayInaWeek
attribute:
WEEKLY_SUNDAY
WEEKLY_MONDAY
WEEKLY_TUESDAY
WEEKLY_WEDNESDAY
WEEKLY_THURSDAY
WEEKLY_FRIDAY
WEEKLY_SATURDAY
You can use the getCache()
method of a CachePolicy
object to retrieve the associated CacheBlock
object, as documented in "CachePolicy Methods" and shown in "Servlet Page: DemoCacheServlet.java".
The following abbreviated code, for illustrative purposes only, shows the key methods of the oracle.jsp.jwcache.CacheBlock
class:
class CacheBlock { long getCreationTime(); long getExpirationTime(); Serializable getData(); }
Here are brief descriptions of these methods:
getCreationTime()
: Returns the timestamp indicating when the cache block was created.
getExpirationTime()
: Returns the timestamp indicating the expiration time of the cache block.
getData()
: Returns the cache block data.
Note: Creation time and expiration time are expressed in milliseconds since midnight, January 1, 1970. |
This example presents code for three approaches to an application that caches and presents timestamp output from two cache fragments:
The first approach, tagcode.jsp
, is a simple JSP page that uses the Oracle Web Object Cache tags.
The second approach, servletcode.jsp
, is a more involved JSP page that uses the Web Object Cache API inside a Java scriptlet instead of using the Web Object Cache tags.
The third approach, DemoCacheServlet.java
, uses the Web Object Cache API inside a servlet.
Following the three code samples is a listing of the cache policy descriptor, test-policy.cpd
.
In each approach, the application will cache the two fragments it displays. You can reload repeatedly, but the times displayed in the fragments will not change until the cached fragments expire. The first fragment takes 25 seconds to expire, getting the 25-second time-to-live value from the TTL
setting in the cache policy descriptor (test-policy.cpd
). The second fragment takes 15 seconds to expire, overriding the cache policy descriptor time-to-live value with a value set directly in the page code.
Output for the sample applications looks something like the following:
fragment#1 (expires in 25 seconds based on TTL value test-policy) Sun May 27 15:20:46 PDT 2001 fragment#2 (expires in 15 seconds because TTL overrides test-policy value) Sun May 27 15:20:46 PDT 2001
<%@ taglib uri="http://xmlns.oracle.com/j2ee/jsp/tld/ojsp/jwcache.tld" prefix="ojsp" %> <title>tagcode.jsp</title> <pre> tagcode.jsp <ojsp:cache policy="/WEB-INF/test-policy.cpd" > fragment#1 (expires in 25 seconds based on TTL value test-policy) <%= new java.util.Date() %> </ojsp:cache> <ojsp:cache policy="/WEB-INF/test-policy.cpd" TTL="15" > fragment#2 (expires in 15 seconds because TTL overrides test-policy value) <%= new java.util.Date() %> </ojsp:cache> </pre>
Code notes are the same as for the servlet version in the next section, "Servlet Page: DemoCacheServlet.java".
<%@ page import="oracle.jsp.jwcache.*,java.io.*" %> <title>servletcode.jsp</title> <pre> servletcode.jsp <% CachePolicy cachePolicyObj = CacheClientUtil.lookupPolicy(config,request, "/WEB-INF/test-policy.cpd" ); // Note A StringSectionId sectionId=new StringSectionId("s1"); // Note B CacheBlock cacheBlockObj=null; cacheBlockObj = cachePolicyObj.getCache(request,sectionId); // Note C if (!cachePolicyObj.isRecent(cacheBlockObj)) { // Note D CharArrayWriter newOut=new CharArrayWriter(); PrintWriter pw=new PrintWriter(newOut); // actual logic within a cache block pw.println ("fragment#1 (expires in 25 seconds based on TTL value test-policy)"); pw.println(new java.util.Date()); // which generates content into the "out" object if (cacheBlockObj == null) { // Note E cachePolicyObj.putCache(newOut.toCharArray(),request,sectionId); // Note F } out.write(newOut.toCharArray()); // writing out newly created data back to the original writer } else { out.write((char[])cacheBlockObj.getData()); // writing the existing cached data to the writer } sectionId=new StringSectionId("s2"); long timeToLive = 15; // now set TTL to 15 on this block ExpirationPolicy expirationPolicy = cachePolicyObj.getExpirationPolicy(); expirationPolicy.setTTL(timeToLive); cachePolicyObj.setExpirationPolicy(expirationPolicy); cacheBlockObj = cachePolicyObj.getCache(request,sectionId); if (!cachePolicyObj.isRecent(cacheBlockObj)) { CharArrayWriter newOut=new CharArrayWriter(); PrintWriter pw=new PrintWriter(newOut); // actual logic within a cache block pw.println ("fragment#2 (expires in 15 seconds because TTL overrides test-policy value)"); pw.println(new java.util.Date()); // which generates content into the "out" object if (cacheBlockObj == null) { cachePolicyObj.putCache(newOut.toCharArray(),request,sectionId); } out.write(newOut.toCharArray()); // writing out newly created data back to the original writer } else { out.write((char[])cacheBlockObj.getData()); // writing the existing cached data to the writer } %> </pre>
Code notes are explained at the end of the code.
package demoPkg; import javax.servlet.*; import javax.servlet.http.*; import java.io.IOException; import java.io.PrintWriter; import java.io.CharArrayWriter; import oracle.jsp.jwcache.CachePolicy; import oracle.jsp.jwcache.ExpirationPolicy; import oracle.jsp.jwcache.StringSectionId; import oracle.jsp.jwcache.CacheBlock; import oracle.jsp.jwcache.CacheClientUtil; public class DemoCacheServlet extends HttpServlet{ public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // standard writer object from servlet engine PrintWriter out=response.getWriter(); ServletConfig config=getServletConfig(); try { CachePolicy cachePolicyObj = CacheClientUtil.lookupPolicy(config,request, "/WEB-INF/test-policy.cpd" ); // Note A StringSectionId sectionId=new StringSectionId("s1"); // Note B CacheBlock cacheBlockObj=null; cacheBlockObj = cachePolicyObj.getCache(request,sectionId); // Note C if (!cachePolicyObj.isRecent(cacheBlockObj)) { // Note D CharArrayWriter newOut=new CharArrayWriter(); PrintWriter pw=new PrintWriter(newOut); // actual logic within a cache block pw.println("fragment#1"); pw.println(new java.util.Date()); // which generates content into the "out" object if (cacheBlockObj == null) { // Note E cachePolicyObj.putCache(newOut.toCharArray(),request,sectionId); // Note F } out.write(newOut.toCharArray()); // writing out newly created data back to the original writer } else { out.write((char[])cacheBlockObj.getData()); // writing the existing cached data to the writer } sectionId=new StringSectionId("s2"); long timeToLive = 15; // now set TTL to 15 on this block ExpirationPolicy expirationPolicy = cachePolicyObj.getExpirationPolicy(); expirationPolicy.setTTL(timeToLive); cachePolicyObj.setExpirationPolicy(expirationPolicy); cacheBlockObj = cachePolicyObj.getCache(request,sectionId); if (!cachePolicyObj.isRecent(cacheBlockObj)) { CharArrayWriter newOut=new CharArrayWriter(); PrintWriter pw=new PrintWriter(newOut); // actual logic within a cache block pw.println("fragment#2"); pw.println(new java.util.Date()); // which generates content into the "out" object if (cacheBlockObj == null) { cachePolicyObj.putCache(newOut.toCharArray(),request,sectionId); } out.write(newOut.toCharArray()); // writing out newly created data back to the original writer } else { out.write((char[])cacheBlockObj.getData()); // writing the existing cached data to the writer } } catch (Throwable th) { // your exception handling code here th.printStackTrace(out); } } }
The following notes describe some of the key functionality of the preceding example:
The cache policy object is created in the lookupPolicy()
call (Note A), with attribute settings according to the cache policy descriptor test-policy.cpd
.
The section ID is created for each cache block (Note B), as required for implicit cache-block naming. See "CachePolicy Methods" for information about section IDs.
The cache block is retrieved from the repository through the getCache()
method of the cache policy object (Note C) and placed into the repository through the putCache()
method, according to the section ID in each case.
The isRecent()
call determines if the cache block is recent enough to use (Note D). If so, the cached data is retrieved through the getData()
method of the cache block. (See "CacheBlock Methods".) If not, a special PrintWriter
object is created to buffer the output and save it back to the cache repository. If the cache block object is not found (is null, Note E), then the putCache()
method of the cache policy object is called to create a new cache block (Note F).
This cache policy descriptor is used by all three approaches to the sample application: tagcode.jsp
, servletcode.jsp
, and DemoCacheServlet.java
:
<!-- test-policy.cpd --> <cachePolicy scope="application"> <expirationPolicy expirationType="TTL" TTL="25" timeInaDay="00:10:00" writeThrough="true" /> </cachePolicy>
You can optionally use an XML-style cache policy descriptor to specify attribute settings for the CachePolicy
and ExpirationPolicy
objects. In any JSP pages or servlets that you use, you would then specify the cache policy descriptor through the policy
attribute of a cache
, cacheXMLObj
, useCacheObj
, cacheInclude
, or invalidateCache
tag.
The following sections provide the cache policy descriptor DTD, a sample cache policy descriptor, and information about loading and refreshing the cache policy descriptor:
This section provides a listing of the Web Object Cache cache policy descriptor DTD, cachepolicy.dtd
.
<!-- cachepolicy.dtd --> <!-- This DTD is used to validate any (Oracle programmable web) cache policy descriptors (for example, "/WEB-INF/foo.cpd"). --> <!-- The cachePolicy element is the root element of cache policy descriptors. configuration descriptor. --> <!ELEMENT cachePolicy ( selectedParam*, selectedCookie*, reusableTimeStamp?, reusableDeltaTime?, cacheRepositoryName?, expirationPolicy? ) > <!ATTLIST cachePolicy ignoreCache (true | false) "false" > <!ATTLIST cachePolicy scope (application | session) "application" > <!ATTLIST cachePolicy autoType (user | URI | URI_query | URI_allParam | URI_selectedParam | URI_excludedParam ) "URI_allParam" > <!ATTLIST cachePolicy reportException (true | false) "true" > <!ELEMENT selectedParam (#PCDATA) > <!ELEMENT selectedCookie (#PCDATA) > <!ELEMENT reusableTimeStamp (#PCDATA) > <!ELEMENT reusableDeltaTime (#PCDATA) > <!ELEMENT cacheRepositoryName (#PCDATA) > <!ELEMENT expirationPolicy EMPTY > <!ATTLIST expirationPolicy expirationType (TTL | daily | weekly | monthly) "TTL" > <!ATTLIST expirationPolicy TTL CDATA "300" > <!ATTLIST expirationPolicy timeInaDay CDATA #IMPLIED > <!ATTLIST expirationPolicy dayInaWeek (Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday) "Wednesday" > <!ATTLIST expirationPolicy dayInaMonth CDATA "10" > <!ATTLIST expirationPolicy writeThrough (true | false) "true" >
This section provides an example of a simple cache policy descriptor that sets the TTL
and timeInaDay
attributes.
<!-- test-policy.cpd --> <cachePolicy scope="application"> <expirationPolicy expirationType="TTL" TTL="25" timeInaDay="00:10:00" writeThrough="true" /> </cachePolicy>
To create a CachePolicy
object from an XML cache policy descriptor file, there must be a call to the static lookupPolicy()
method of the CacheClientUtil
class. For JSP pages, this is handled automatically. For servlets, you must include the lookupPolicy()
call in your code. See "Servlet Page: DemoCacheServlet.java".
If the caching policy has not been previously loaded, the lookupPolicy()
invocation results in the XML descriptor being parsed and used in constructing a new CachePolicy
object and an ExpirationPolicy
attribute of this object. See "Cache Policy Object Creation" for information about the lookupPolicy()
method.
The CachePolicy
object is stored indirectly under the ServletContext
object associated with your application. When the same caching policy is requested again, the stored policy object will be returned without the descriptor being reread or re-parsed. For performance reasons, because the cache policy descriptor files are seldom changed, as well as for security reasons, OC4J does not provide descriptor auto-reloading functionality. The resulting cache policy object is stored in the middle-tier JVM for faster access.
The CachePolicy
object will be valid until the servlet context is destroyed or someone calls the static refreshPolicy()
method of the CacheClientUtil
class. This method has the same calling sequence as the lookupPolicy()
method. For example:
oracle.jsp.jwcache.CacheClientUtil.refreshPolicy (servletConfig, request, "/WEB-INF/foo.cpd");
When you alter and refresh the caching policy, active cache blocks are not affected.
Use an XML-style cache repository descriptor to specify what to use as the back-end cache repository for the Web Object Cache and how to configure it. The following sections list the DTD for cache repository descriptors, as well as a sample cache repository descriptor:
Sample Cache Repository Descriptor
Note: By default, the Web Object Cache uses the Oracle Application Server Java Object Cache as its cache repository. |
This section provides a listing of the Web Object Cache cache repository descriptor DTD, wcache.dtd
.
<!-- Copyright 2000 Oracle Corporation wcache.dtd --> <!-- This DTD is used to validate "/WEB-INF/wcache.xml", which is used to hold web cache repositories configuration information for Oracle programmable web caching components. --> <!-- The wcache-config element is the root element of web cache repositories configuration descriptor. --> <!ELEMENT wcache-config (cache-repository*)> <!ELEMENT cache-repository (cache-repository-name,cache-repository-class,init-param*)> <!ELEMENT cache-repository-name (#PCDATA)> <!ELEMENT cache-repository-class (#PCDATA)> <!ELEMENT init-param (param-name,param-value)> <!ELEMENT param-name (#PCDATA)> <!ELEMENT param-value (#PCDATA)>
This section lists the cache repository descriptor provided with OC4J.
Note: The DTD does not includereporoot , which is a specific-use parameter that only a file system cache implementation requires.
|
<wcache-config> <cache-repository> <cache-repository-name>DefaultCacheRepository</cache-repository-name> <cache-repository-class> oracle.jsp.jwcache.repository.impl.OCSRepoImpl </cache-repository-class> </cache-repository> <cache-repository> <cache-repository-name>SimpleFSRepo</cache-repository-name> <cache-repository-class> oracle.jsp.jwcache.repository.impl.SimpleFSRepositoryImpl </cache-repository-class> <init-param> <param-name>reporoot</param-name> <param-value>/tmp/reporoot</param-value> </init-param> </cache-repository> </wcache-config>
This section describes how to configure the Oracle Application Server Java Object Cache or a file system as the back-end repository for the OC4J Web Object Cache.
The OC4J server.xml
file must have a <javacache-config>
element to specify the Java Object Cache configuration file. This is a subelement of the <application-server>
element. By default, the entry is as follows:
<application-server ... > ... <javacache-config path="../../../javacache/admin/javacache.xml" /> ... </application-server>
As shown, and assuming the default configuration file directory location (where server.xml
is located), the default is for OC4J instances to share the same Java Object Cache configuration file, javacache.xml
, in the ORACLE_HOME
/javacache/admin
directory.
Here is a sample Java Object Cache configuration file:
<?xml version="1.0" encoding="UTF-8"?> <cache-configuration xmlns="http://www.oracle.com/oracle/ias/cache/configuration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > <logging> <location>javacache.log</location> <level>ERROR</level> </logging> <communication> <isDistributed>true</isDistributed> <coordinator discovery-port="7000"/> </communication> <persistence> <location>diskcache</location> <disksize>32</disksize> </persistence> <max-objects>1000</max-objects> <max-size>48</max-size> <clean-interval>30</clean-interval> </cache-configuration>
For more information about the Java Object Cache, its configuration, and the javacache.xml
file, see the Oracle Application Server Containers for J2EE Services Guide. For more information about the server.xml
file, refer to the Oracle Application Server Containers for J2EE User's Guide.
To use a file system as the back-end repository, edit the cache repository descriptor, wcache.xml
, to set reporoot
to specify a root directory for the file system cache. This file is located in the /WEB-INF
directory where the OC4J samples are installed. See "Cache Repository Descriptor" for general information and for an example of a cache repository descriptor that sets a reporoot
value.
For example, for a UNIX system:
<init-param> <param-name>reporoot</param-name> <param-value>/mydir/repositoryroot</param-value> </init-param>
Alternatively, for a Windows system:
<init-param> <param-name>reporoot</param-name> <param-value>c:\mydir\repositoryroot</param-value> </init-param>