Skip Headers

Oracle9i Application Server Application Developer's Guide
Release 2 (9.0.2)

Part Number A95101-01
Go To Documentation Library
Go To Product List
Solution Area
Go To Table Of Contents
Go To Index

Go to previous page Go to next page

Adding Web Cache to the Application

You can use the web cache feature of Oracle9iAS to improve performance, availability, and scalability of your applications without modifying them. You just have to specify which pages in your applications you want to cache using the Oracle Web Cache Manager tool.

This guide does not cover how web cache works. For an overview and details of web cache, see the Oracle9iAS Web Cache Administration and Deployment Guide.

8.1 Choosing Which Pages to Cache

Pages that you should cache include the following:

You use the Oracle Web Cache Manager to manage cached pages. This applies to static and dynamic elements. To cache a page, you specify the page's URL in the Oracle Web Cache Manager. You can use regular expressions to match multiple URLs and to ensure your pattern matches exactly.

The next section shows how the Employee Benefit application caches a combination of static pages and dynamic pages.

8.2 Analyzing the Application

The only static element in the Employee Benefit application is a style sheet (blaf.css).

The ID page (Figure 2-1), which prompts the user to enter an employee ID, is a static page in the sense that it does not change from user to user, but it is generated dynamically. This is a good page to cache.

The most requested pages in the application are the pages that display employee information. Caching these pages would improve application performance. These pages are dynamically generated, however; the application needs to invalidate them when they are no longer valid.

There are no graphics to cache in this application.

8.2.1 Specifying the Pages to Cache

Figure 8-1 shows the Oracle Web Cache Manager with the Cacheability Rules page selected. The first three lines are specific to the Employee Benefit application.

The ID page and the pages that display employee information have similar URLs. The URL for the ID page is:


The employee information pages have URLs that look something like this:


Both URLs have action=queryEmployee. The following regular expression covers both URLs:


To cache the style sheet, specify its URL in the Oracle Web Cache Manager. The ^ and $ are special characters used in regular expressions to indicate the beginning and the end of a line. This ensures that the pattern matches exactly.


The second rule, which matches ^/empbft/$, specifies an optional convenience page that provides a link to the ID page of the application. This page is static. If you have a page external to the application that links to the application, then you do not need this page and URL.

Figure 8-1 Oracle Web Cache Manager

Text description of cachemgr.jpg follows.

Text description of the illustration cachemgr.jpg

8.2.2 Invalidating Pages

You need to invalidate dynamic pages in the cache when they are no longer valid. To invalidate cached pages, send an XML file with the URL of the pages that you want to invalidate to web cache.

The Employee Benefit application caches the employee information page, which should be invalidated as soon as the data in the database is updated. One way to do this is to send an invalidation message to web cache at the end of the add and remove benefit operations. This method, however, does not invalidate the pages when other applications update the underlying tables in the database that the Employee Benefit application uses.

A better way is to have the database send the invalidation message when the data in the tables changes. To do this, set up triggers on the tables to fire when data in the tables gets updated. The triggers can call a procedure to send the invalidation message to web cache.

The procedure that the triggers invoke looks like the following:

-- Usage:
--    SQL> set serveroutput on (When debugging to see dbms_output.put_line's)
--    SQL> exec invalidate_emp('doliu-sun',4001,122);
create or replace procedure invalidate_emp (
                            machine in varchar2,
                            port    in integer,
                            emp     in integer) is
  d integer;
  c  utl_tcp.connection;  -- TCP/IP connection to the Web server
  DQUOTE constant varchar2(1) := chr(34);
  CR     constant varchar2(1) := chr(13);
  AMP    constant varchar2(1) := chr(38);
  uri varchar2(100) := '/empbft/controller?action=queryEmployee' || AMP ||
                       'amp;empID=' || emp;
  content_length integer;
  -- Note: The 177 + Length of uri to invalidate = Content-Length
  content_length := LENGTH(uri) + 177;
  dbms_output.put_line('Content-Length:' || content_length);
  -- open connection
  c := utl_tcp.open_connection(machine, port);
  -- Send the HTP Protocol Header
  -- send HTTP POST for Oracle Web Cache
  d := utl_tcp.write_line(c, 'POST /x-oracle-cache-invalidate HTTP/1.0');
  -- Note: The Authorization passes the User:Password as a base64 encoded
  --       string. ie. invalidator:admin =>  
  d := utl_tcp.write_line(c, 'Authorization: BASIC aW52YWxpZGF0b3I6YWRtaW4=');
  d := utl_tcp.write_line(c, 'Content-Length: ' || content_length);
  dbms_output.put_line('Content-Length: ' || content_length);
  -- send TWO CR's per HTTP Protocol  (Note: One from above)
  -- (Note: If testing with telnet count cr as 2 characters)
  d := utl_tcp.write_line(c, CR );
  -- send Calypso xml Invalidation File
  d := utl_tcp.write_line(c, '<?xml version=' || DQUOTE || '1.0' || DQUOTE ||
  d := utl_tcp.write_line(c, '<!DOCTYPE INVALIDATION SYSTEM ' || DQUOTE ||
                             'internal:///invalidation.dtd' || DQUOTE || '>');
  d := utl_tcp.write_line(c, '<INVALIDATION>');
  -- May need to uncomment this for testing dif. expressions.
  -- d := utl_tcp.write_line(c, '<URL EXP=' || DQUOTE || '/cache.htm' || DQUOTE
  --                 || ' PREFIX=' || DQUOTE || 'NO' || DQUOTE || '>');
  d := utl_tcp.write_line(c, '<URL EXP=' || DQUOTE || uri || DQUOTE ||
                             ' PREFIX=' || DQUOTE || 'NO' || DQUOTE || '>');
  d := utl_tcp.write_line(c, '<VALIDITY LEVEL=' || DQUOTE || '0' || DQUOTE ||
                             ' />');
  d := utl_tcp.write_line(c, '</URL>');
  d := utl_tcp.write_line(c, '</INVALIDATION>');
    -- Capture some of the expected return output when debugging
    dbms_output.put_line(substr(utl_tcp.get_line(c, TRUE),1,80)); -- read result
    dbms_output.put_line(substr(utl_tcp.get_line(c, TRUE),81,160));
    dbms_output.put_line(substr(utl_tcp.get_line(c, TRUE),161,240));
    dbms_output.put_line(substr(utl_tcp.get_line(c, TRUE),241,320));
    dbms_output.put_line(substr(utl_tcp.get_line(c, TRUE),321,400));
    dbms_output.put_line(substr(utl_tcp.get_line(c, TRUE),401,480));
    WHEN utl_tcp.end_of_input THEN
      NULL; -- end of input

The invalidate message that the procedure sends to web cache is an XML file. The file looks like the following:

<?xml version="1.0"?>
<!DOCTYPE INVALIDATION SYSTEM "internal:///invalidation.dtd">

The uri is replaced with something like:


Web cache listens on a specific port. The procedure calls utl_tcp.open_connection to open a connection to web cache and sends an HTTP header:

POST /x-oracle-cache-invalidate HTTP/1.0
Authorization: BASIC aW52YWxpZGF0b3I6YWRtaW4=
Content-Length: contentLength

Note that the procedure has to calculate the content length. It starts with 177, which is the length of the XML file, to which it adds the length of the uri.

The Authorization specifies the username and password for web cache.

8.2.3 Setting up Triggers on the Underlying Tables

The underlying tables in the database have the following triggers. These triggers run the invalidate procedure.

The first trigger is fired when a row is deleted from the employee_benefit_items table.

AFTER DELETE on employee_benefit_items
invalidate_emp('doliu-sun', 4001, :old.EMPLOYEE_ID);

The second trigger is fired when a row is inserted or updated in the employee_benefit_items table.

AFTER INSERT OR UPDATE on employee_benefit_items
invalidate_emp('doliu-sun', 4001, :new.EMPLOYEE_ID);

Go to previous page Go to next page
Copyright © 2002 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Go To Product List
Solution Area
Go To Table Of Contents
Go To Index