Oracle8i Application Developer's Guide - XML Release 3 (8.1.7) Part Number A86030-01 |
Library | Service | Contents | Index

Customizing Content with XML: Dynamic News Application, 12 of 16

## 1 Get End-User Preferences

Logic for processing preferences is distributed throughout the application, which stores the data both in the database and in client-side cookies. The application reads preference data from a cookie whenever possible to improve performance. If it can't get the data from a cookie (for example, because the end-user is visiting the site for the first time, or the end-user's browser does not accept cookies), the application reads preference data from the database.

### From a Client-Side Cookie

The two methods below show how the application processes preference data stored in a cookie. Both methods come from xmlnews.common.UserPreference. Here's a sample cookie:

    DynamicServlet=3$0$0#4$2$1***242

The cookie uses dollar signs to separate preference values, pound signs to separate categories, and three asterisks as a token to separate user ID and preference data. The sample cookie above shows that user 242 wants items from categories 3 and 4. In category 3, the user wants items of all types in all subcategories (a value of 0 selects all items). In category 4, the user wants items from subcategory 2 only, and within that subcategory, only items of type 1.

The sample app processes such cookies in two steps:

1. First, getNewsCookie gets the "DynamicServlet" cookie from the browser that issued the HTTP request.

2. Then loadPreferenceFromCookie parses it to get a String that contains that user's ID and preferences.

       public Cookie getNewsCookie(HttpServletRequest request)

                         throws Exception {
                 Cookie c[] = request.getCookies();
                 Cookie l_returnCookie = null;
                         for (int i = 0; (c!= null) && (i < c.length); i++) {
                         if (c[i].getName().equals("DynamicServlet")) {
                             l_returnCookie = c[i];
                             }
                           }
                           return l_returnCookie;
                         }
           public Vector loadPreferenceFromCookie(Cookie p_cookie) throws Exception {
                 Vector l_prefId = new Vector(2);
                 String l_Preferences = p_cookie.getValue();
                 StringTokenizer l_stToken = new StringTokenizer(l_Preferences, "***");
                 String l_userId = "";
                 while (l_stToken.hasMoreTokens()) {
                    // First Token is User Preference.
                    l_Preferences = l_stToken.nextToken();
                    // Second Token is User ID.
                    l_userId = l_stToken.nextToken();
                 }
                 l_prefId.addElement(l_Preferences);
                 l_prefId.addElement(l_userId);
                 return l_prefId;
              }

### Querying the Database

If it can't read preferences from a cookie, the application queries the database. The class `xmlnews.common.GenUtility` implements methods that connect to the database and fetch news categories, sub-categories, and types.

The semi-dynamic servlet and the dynamic servlet both call these methods and the methods `loadInitalPreference` and `constructUserPreference` . These are both implemented in xmlnews/common/UserPreference.java.

Method `loadInitalPreference` calls `getSubCategories`, then loops through the result set, combining category values with separator characters to build a preference string.

    public String loadInitialPreference(Vector p_category, Vector p_subcategory,
            Vector p_types, Connection p_con)
    throws Exception {
    GenUtility m_general = new GenUtility();
    ...
    for (int i = 0; i < p_category.size(); i++) {
            String l_cat[] = (String []) p_category.elementAt(i);
            l_category = l_cat[0];
            Vector l_subcategory = m_general.getSubCategories(p_con,l_cat[0]);

            for(int l_j = 0, l_k = 0; l_j < l_subcategory.size(); l_j++, l_k++)
     {
    ...
    // Append the next preferences to the constructed string
       l_userPref = l_userPref+"#"+l_category+"$"+l_subCat+"$"+l_typeStr;
              }
       }
    ...
        return l_userPref;
       }

    public static Vector getSubCategories(Connection p_conn, String p_categoryId)
        throws Exception {
        Vector l_subCats = new Vector();

    PreparedStatement l_pstmt = p_conn.prepareStatement(
       "Select id, name from sub_categories where category_id = ? ");
        l_pstmt.setString(1, p_categoryId);
        ResultSet l_rset = l_pstmt.executeQuery();

    while (l_rset.next()) {
         String[] l_subCat = new String[2];
         l_subCat[0] = new String(l_rset.getString(1));
         l_subCat[1] = new String(l_rset.getString(2));
         l_subCats.addElement(l_subCat);
         }
    l_pstmt.close();
    return l_subCats;
    }

For example, the following code comes from `xmlnews.dynamic.DynamicServlet.service`.

It calls these methods to read end-user preferences from the database, then uses the preferences to build an HTML page.

    public void service(HttpServletRequest p_request,
          HttpServletResponse p_  response)
          throws ServletException {

       // The following are declared elsewhere as class variables
       // and initialized in the servlet's init method.
       // GenUtility m_general = null;

       // m_general = new GenUtility();
       // UserPreference m_userPreference = null;
       // m_userPreference = new UserPreference();
       ...

       // If the database connection has been closed, reopen it.
          if (m_connection == null || m_connection.isClosed())
              m_connection = m_general.dbConnection();
       ...
          String l_preference = m_userPreference.loadInitialPreference(
          m_general.getCategories(m_connection),
          null, m_general.getTypes(m_connection),
                                   m_connection);

    m_userPreference = m_userPreference.constructUserPreference
       ( l_preference,m_status);

       // Display the Dynamic Page
          this.sendDynamicPage(l_browserType, p_response,
          l_userName, m_userPreference,
          m_servletPath + "?REQUEST_TYPE=SET_ADVANCED_USER_PREFS",
          m_servletPath + "?REQUEST_TYPE=LOGIN_REQUEST",
          m_servletPath + "?REQUEST_TYPE=LOG_OUT_REQUEST",
          m_servletPath);
        ...
     }

| Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
Library | Service | Contents | Index