Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers 10g Release 3 (10.1.3.0) Part Number B25947-02 |
|
|
View PDF |
This chapter describes how to add caching support to existing application pages.
This chapter explains the following:
For most Web-based applications, a large percentage of requests are made for identical or similar content. These repeated requests for both dynamic and static contents place a significant strain on application infrastructure.
Caching stores all or parts of a web page in memory for use in future responses. It significantly reduces response time to client requests by reusing cached content for future requests without executing the code that created it.
Oracle ADF Faces Cache provides a simple way for you to cache portions of a response generated by a request. You simply wrap the fragment content you want to cache with a beginning <afc:cache>
and ending </afc:cache>
tag. By caching both dynamic and static content, you can increase throughput and shorten response times.
You can add the <afc:cache>
tag to cache the following fragment types:
Page fragment—You make the <afc:cache>
tag a direct child of the <f:view>
tag, and enclose the page's content within it.
Fragment within a page—You enclose only the fragment portion within the <afc:cache>
tag. Caching fragments is useful when sections of a page must be created for each request.
Included fragment that exists in its own subpage—You make the <afc:cache>
tag a direct child of the <f:subview>
tag, and enclose the fragment's content within it.
You can use the ADF Faces Cache library with any application developed with JavaServer Faces (JSF).
Consider using the <afc:cache>
tag for the following types of content:
Resource Intensive
If rendering a particular JSF or ADF component requires resource-intensive operations like making database or network queries, caching can help to reduce the rendering cost by retrieving content from the cache as opposed to regenerating it.
Shareable
The cache can serve the same object to multiple users or sessions.
The degree of sharing can be application wide or limited by certain properties, such as a bean property, user cookie, or request header.
Changes infrequently
Infrequently changing content is ideal to cache, because the cache can serve the content for a long period of time. The ADF Faces Cache expiration and invalidation mechanisms help to invalidate content in the cache. Use expiration when you can accurately predict when the source of the content will change; use invalidation for content that changes from a request.
Because frequently changing content requires constant cache updates, this content is not ideal to cache.
Several of the pages in the SRDemo application use the Cache
component to cache fragments. By analyzing how caching support was added to SRCreate.jspx
and SRFaq.jspx
, you can better understand how to cache fragments in your applications.
Figure 23-1 shows the SRCreate.jspx
page. It contains these cacheable fragments:
The first fragment contains content at the start of the page, including the text and link to the Frequently Asked Questions, the prompt to enter a basic description of your problem, and the objectSeparator
component.
This content is generic to all users.
The second fragment contains the tabs, including the New Service Request tab.
This content varies by the user. The content is valid across all sessions for the same user.
The third fragment contains the Logout and Help menu item at the top of the page.
This content is generic to all users.
Because these fragments are shareable by a given user across sessions or across all users, they are good caching candidates.
Example 23-1 shows the code for the first fragment, the start of the page content.
Example 23-1 Start Page Content Fragment
<!--Page Content Start--> <afc:cache duration="864000"> <af:objectSpacer width="10" height="10"/> <af:panelHorizontal> <f:facet name="separator"> <af:objectSpacer width="4" height="10"/> </f:facet> <af:outputText value="#{res['srcreate.faqText']}"/> <af:commandLink text=" #{res['srcreate.faqLink']}" action="dialog:FAQ" useWindow="true" immediate="true" partialSubmit="true"/> </af:panelHorizontal> <af:objectSpacer width="10" height="10"/> <af:outputFormatted value="#{res['srcreate.explainText']}"/> <af:objectSeparator/> </afc:cache>
The attributes for the <afc:cache>
tag specify the following:
The duration
attributes specifies 86,400 seconds before the fragment expires. When a fragment expires and client requests it, it is removed from the cache and then refreshed with new content.
Example 23-2 shows the code for the second fragment, the tabs across the top of the page.
Example 23-2 Menu Tabs Fragment
<f:facet name="menu1"> <afc:cache duration="864000" varyBy="request.Session" <af:menuTabs var="menuTab" value="#{menuModel.model}"> <f:facet name="nodeStamp"> <af:commandMenuItem text="#{menuTab.label}" action="#{menuTab.getOutcome}" rendered="#{menuTab.shown and menuTab.type=='default'}" disabled="#{menuTab.readOnly}"/> </f:facet> </af:menuTabs> </afc:cache> </f:facet>
The attributes for the <afc:cache>
tag specify the following:
The duration
attribute specifies 86,400 seconds before the fragment expires.
The varyBy
attribute specifies which version of the fragment to display based on the session scope. This attribute specifies to cache a version of the fragment for the entire session. The content is valid across one session regardless of the user.
Example 23-3 shows the code for the last fragment, which displays the Logout and Help menu items as a global menu fragment.
Example 23-3 Logout and Help Menu Fragment
<f:facet name="menuGlobal"> <f:subview id="globalMenufragment"> <afc:cache duration="86400"> <jsp:include page="/app/globalMenu.jspx"> </afc:cache> </f:subview> </f:facet>
Figure 23-2 shows the SRFaq.jspx
page. Its content is shareable among all users.
Example 23-4 shows the code for this page fragment.
Example 23-4 FAQ Fragment
<f:view>
<afc:cache duration="86400"
searchKeys="FAQ"
...FAQ Page Content...
</afc:cache>
</f:view>
The attributes for the <afc:cache>
tag specify the following:
The duration
attribute specifies 86,400 seconds before the fragment expires.
The searchKeys
attribute assigns this page fragment a search string of FAQ
. You can invalidate this fragment using this search key.
You use search keys to organize web pages and fragments into different groups. You can assign all the pages in a particular group with the same search key. For example, you can assign the search key new_request
to all the pages that have something to do with creating a new service requests. To invalidate a group of objects, you submit an invalidation request that specifies the search key associated with that particular group. For example, if the invalidation request specifies the search key new_request
, all the pages assigned the new_request
search key will be invalidated. In the SRDemo application, the SRFaq.jspx
page is the only page assigned a search key.
When objects are marked as invalid and a client requests them, they are removed and then refreshed with new content.
To use the Cache
component, you add the ADF Faces Cache library to an application's project and apply the library to the specific JSP page.
To add the ADF Faces Cache library:
In the Application Navigator, select the project that you want to use the Cache
component.
From the context menu, choose Project Properties.
The Project Properties dialog opens.
Select the Libraries node.
On the Libraries page, click Add Library.
Locate the ADF Faces Cache library in the selection tree and click OK.
On the Libraries page, click OK.
For each JSP document or page, you plan to apply the <afc:cache>
tag, add the following library syntax to the <jsp:root>
tag:
xmlns:afc="http://xmlns.oracle.com/adf/faces/webcache"
You can now insert the Cache
component from the Component Palette or use Code Insight to insert the <afc:cache>
tag.
When you run an application containing the <afc:cache>
tag, the content is not cached until there is an initial browser request for it. After the content is cached, the content is served from the cache. You can see when content is inserted into the cache and how many cache hits and misses result from fragment requests using a combination of the following tools:
ADF Faces Cache leverages the Java Logging API (java.util.logging.Logger) to log events and error messages. These messages show the sequence of how objects are inserted and served from the cache.
Depending on the logging configuration specified in the j2ee-logging.xml
file, logging information can display in the Log Window of JDeveloper and write to the log.xml
file. The j2ee-logging.xml
file specifies the directory path information for log.xml
.
Example 23-5 shows log excerpts in which fragment SRCreate.jspx
is initially requested and found not to be in the cache (cache miss
) and inserted into the cache (insert
). SRCreate.jspx
is requested again, and served from the cache (cache hit
).
The AFC Statistics servlet, shown in Figure 23-3, displays the following cache statistics. These statistics can help to provide an overall picture of cache throughput:
Number of objects in cache–The number of objects stored in the cache.
Number of cache hits–The number of requests served by objects in the cache.
Number of cache misses–The number of cacheable requests that were not served by the cache. This number represents initial requests and requests for invalidated or expired objects that have been refreshed.
Number of invalidation requests–The number of invalidation requests serviced by the cache.
Number of documents invalidated–The total number of objects invalidated by the cache.
The Number of invalidation requests and the Number of documents invalidated may not be the same. This difference can occur because one search key may apply to more than one object.
The Click here to Reset Stats link, shown in Figure 23-3, resets these statistics, except for Number of objects in cache.
To enable the servlet:
Create the following entry in the web.xml
file in the /WEB-INF
directory of the application:
<servlet> <servlet-name>AFCStatsServlet</servlet-name> <servlet-class>oracle.webcache.adf.servlet.AFCStatsServlet</servlet-class> </servlet>
Point your browser to the following URL:
http://application_host:application_port/application-context-root/servlet/AFCStatsServlet
See Also:
Topic "Viewing Cache Performance Statistics" in the JDeveloper online help for further information about the AFC Statistics servletThe visual diagnostics feature enables you to visually display whether fragments are cache hits or cache misses. This feature demarcates fragment output with the HTML <SPAN>
tag, using a class appropriate for its cache hit or cache miss status. By setting a distinct class style, you can visually determine whether fragments are stored in the cache.
While the SRDemo application does not use the visual diagnostics feature, you may find it useful for testing your applications.
See Also:
Topic "Using Visual Diagnostics" in the JDeveloper online help for further informationWhen you use AFC Statistics servlet, you may encounter the following problems:
HTTP 404 Page Not Found
error code
If you receive this error when accessing the servlet, it is most likely the result of a configuration issue.
To resolve this problem, ensure the following lines are present in the web.xml
file:
<servlet> <servlet-name>AFCStatsServlet</servlet-name> <servlet-class>oracle.webcache.adf.servlet.AFCStatsServlet</servlet-class> </servlet>
Cache instance is not running
error
This error occurs because the servlet has not started to monitor the cache. The servlet only starts to monitor the cache after the first object has been inserted into the cache and the cache instance is created.