Skip Headers
Oracle® Application Server Application Developer's Guide
10g Release 2 (10.1.2)
Part No. B14000-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

8 Supporting Wireless Clients

The wireless feature in OracleAS enables wireless clients to access your applications. Because wireless clients use protocols different from HTTP and markup languages other than HTML, you have to make some modifications to the sample application to support wireless clients.

Contents of this chapter:

8.1 Changes You Need To Make To Your Application

If your application uses the MVC design, you only need to make a few changes to your application to support wireless clients:

8.2 Presentation Data for Wireless Clients

Because wireless clients do not use a standardized markup language, you have to write presentation data for the clients in XML based on a generic DTD specification. The wireless feature in OracleAS transforms the XML to the specific markup language that the wireless client can process.

Like HTML, applications can generate XML from JSP files or static files. In the sample application, the presentation data comes from JSP files because it contains dynamic data.

The generic XML for wireless clients is based on the SimpleResult DTD.


See Also:

Oracle Application Server Wireless Developer's Guide for details on the DTD and how to use its elements.

8.2.1 Screens for the Wireless Application

Figure 8-1 to Figure 8-3 show the sample application on an OpenWave simulator. The application on a wireless client looks similar to the application on a desktop browser.

Figure 8-1 Screens for the Wireless Application (1 of 3)

Description of wireless_screens_1.gif follows
Description of the illustration wireless_screens_1.gif

On Screen 1, the wireless client lists the applications that it can run. This is essentially a list of the files in:

$OMSDK_HOME/oc4j_omsdk/omsdk/j2ee/applications/pmsdk/apps/

$OMSDK_HOME is the home directory for OracleAS Wireless SDK.

Screen 2 shows the sample application's starting point, which is the empbft.xml file. The file displays a text input field where the user can enter an employee ID.

Screen 3 shows the results of the query. The wireless client has a scroll bar that enables the user to scroll down the page to view all the information. At this screen, the user can press the Menu button to add or remove benefits.

Figure 8-2 Screens for the Wireless Application (2 of 3)

Description of wireless_screens_2.gif follows
Description of the illustration wireless_screens_2.gif

Screen 4 shows the menu, which offers selections such as add benefits, remove benefits, and query other employee.

Screen 5 shows a list of benefits that the user can add. The user selects one benefit to add and clicks OK to submit the request. Note that on wireless clients, the user can select only one item to add or remove at a time.

Screen 6 tells the user that the add benefit operation was completed successfully. This screen also has a Menu option.

Figure 8-3 Screens for the Wireless Application (3 of 3)

Description of wireless_screens_3.gif follows
Description of the illustration wireless_screens_3.gif

Screen 7 shows the menu. It has four options: add more benefits, remove more benefits, query same employee, and query other employee.

Screen 8 shows the list of benefits after the user has added a benefit.

Screen 9 is similar to Screen 3, except that it is scrolled down to show the list of benefits for the user.

8.2.2 Differences Between the Wireless and the Browser Application

In the browser version of the application, users can select multiple benefits to add or remove. On wireless devices, however, users can select only one item at a time. To assist users in adding/removing multiple items, the application provides options called "Add More Benefits" and "Remove More Benefits" to enable users to select another benefit to add or remove (screen 7). These options are not necessary, and thus not available, for the browser version of the application.

These options are made available from successWireless.jsp, which is displayed after the application adds or removes a benefit successfully (screen 6). This screen displays a success message. When users click Menu on this screen, they see the "Add More Benefits" and "Remove More Benefits" options.

// from successWireless.jsp
<SimpleText>
   <SimpleTextItem>Operation completed successfully.</SimpleTextItem>
   <Action label="Add More Benefits" type="SOFT1" task="GO"
target="/empbft/controller?action=addBenefitToEmployee&amp;clientType=wireless&amp;empID=<%=empId%>"></Action>

   <Action label="Remove More Benefits" type="SOFT1" task="GO"
target="/empbft/controller?action=removeBenefitFromEmployee&amp;clientType=wireless&amp;empID=<%=empId%>"></Action>

   <Action label="Query Same Employee" type="SOFT1" task="GO"
target="/empbft/controller?action=queryEmployee&amp;clientType=wireless&amp;empID=<%=empId%>"></Action>

   <Action label="Query Other Employee" type="SOFT1" task="GO"
target="/empbft/controller?action=queryEmployee&amp;clientType=wireless"></Action>
</SimpleText>

When the user selects the "Add More Benefits" or "Remove More Benefits" option, the request is similar to the request to add or remove a benefit. The request contains an action parameter, an empID parameter, and a clientType parameter. The application requeries the database and displays an updated list of benefits (Screen 8).

8.3 Deciding Where to Put the Presentation Data for Wireless Clients

You can write the XML presentation data for wireless clients in the same JSP file as the one that generates the HTML, or in a different JSP file. Regardless of where you put the presentation data, you still need to determine if a request came from a wireless or desktop client.

8.3.1 Determining the Origin of a Request

You can determine the origin of a request by inserting a parameter in the request to identify wireless clients. You can include the parameter and its value using a hidden input form element.

The sample application uses a parameter name of clientType and parameter value of wireless to identify wireless clients. Each wireless client request contains this parameter. For example, in empbft.xml, which is the first file in the application that wireless clients see:

// empbft.xml
<?xml version = "1.0" encoding = "ISO-8859-1"?>
<SimpleResult>
  <SimpleContainer>
    <SimpleForm title="Query Employee" target="/empbft/controller">
       <SimpleFormItem name="empID" format="*N">Enter Emp ID: </SimpleFormItem>
       <SimpleFormItem name="action" type="hidden" value="queryEmployee" />
       <SimpleFormItem name="clientType" type="hidden" value="wireless" />
    </SimpleForm>
  </SimpleContainer>
</SimpleResult>

You can then check for the clientType parameter in servlets or JSPs in the same way that you check for other parameters.

In servlets:

String client = req.getParameter(SessionHelper.CLIENT_TYPE_PARAMETER);
boolean wireless = 
          client != null && client.equals(SessionHelper.CLIENT_TYPE_WIRELESS);

In JSPs:

<%
  String client = request.getParameter(SessionHelper.CLIENT_TYPE_PARAMETER);
  boolean wireless =
            client != null && client.equals(SessionHelper.CLIENT_TYPE_WIRELESS);
%>

8.3.2 Combining Presentation Data in the Same JSP File

If you use this method, determine the origin of the request (whether it came from a wireless or desktop client) in the JSP file itself. You can then generate HTML or XML depending on the origin. For example:

// import classes for both wireless and browsers
<%@ page import="java.util.*" %>
<%@ page import="empbft.component.employee.ejb.*" %>
<%@ page import="empbft.component.employee.helper.*" %>
<%@ page import="empbft.util.*" %>

// check the client type that sent the request
<%
  String client = request.getParameter(SessionHelper.CLIENT_TYPE_PARAMETER);
  boolean wireless = ( (client != null) && 
                 client.equals(SessionHelper.CLIENT_TYPE_WIRELESS) );
  if (wireless)
  {
%>
    <?xml version = "1.0" encoding = "ISO-8859-1"?>
    <%@ page contentType="text/vnd.oracle.mobilexml; charset=ISO-8859-1" %>
    <SimpleResult>
      <SimpleContainer>
        <SimpleForm title="Query Employee" target="/empbft/controller">
           <SimpleFormItem name="empID" format="*N">Enter Emp ID:
                                                       </SimpleFormItem>
           <SimpleFormItem name="action" type="hidden" value="queryEmployee" />
           <SimpleFormItem name="clientType" type="hidden" value="wireless" />
        </SimpleForm>
      </SimpleContainer>
    </SimpleResult>
<%
  } else {
%>
    <%@ page contentType="text/html;charset=ISO-8859-1"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <link rel="stylesheet" href="css/blaf.css" type="text/css">
    <title>Query Employee</title>
    </head>
    <body>
    <h2>Employee Benefit Application</h2>
<%
  String empId = request.getParameter(SessionHelper.EMP_ID_PARAMETER);
  if (empId == null)
  {
%>
<h4>Query Employee</h4>
<form method=get action="/empbft/controller">
<input type=hidden name=action value=queryEmployee>
<table>
  <tr>
    <td>Employee ID:</td>
    <td><input type=text name=empID size=4></td>
    <td><input type=submit value="Query Employee"></td>
  </tr>
</table>
<h4>Actions</h4>
<a href="/empbft/">Home</a><br>
</form>
<%
  } else {
    int id = Integer.parseInt(empId);
    EmployeeManager mgr = SessionHelper.getEmployeeManager(request);
    EmployeeModel emp = mgr.getEmployeeDetails(id);
%>
<h4>Employee Details</h4>
<table>
<tr><td>Employee ID: </td><td colspan=3><b><%=id%></b></td></tr>
<tr><td>First Name: </td><td><b><%=emp.getFirstName()%></b></td><td>Last Name: </td><td><b><%=emp.getLastName()%></b></td></tr>
<tr><td>Email: </td><td><b><%=emp.getEmail()%></b></td><td>Phone Number: </td><td><b><%=emp.getPhoneNumber()%></b></td></tr>
<tr><td>Hire Date: </td><td><b><%=emp.getHireDate().toString()%></b></td><td>Job: </td><td><b><%=emp.getJobId()%></b></td></tr>
</table>
<h4>Elected Benefits</h4>
<table>
  <%
    Collection benefits = emp.getBenefits();
    if (benefits == null || benefits.size() == 0) {
  %>
      <tr><td>None</td></tr>
  <%
    } else {
      Iterator it = benefits.iterator();
      while (it.hasNext()) {
        BenefitItem item = (BenefitItem)it.next();
  %>
        <tr><td><%=item.getName()%></td></tr>
  <%
      } // end of while
    } // end of if
  %>
</table>
<h4>Actions</h4>
<table>
<tr><td><a href="/empbft/controller?empID=<%=id%>&amp;action=addBenefitToEmployee">Add benefits to the employee</a></td></tr>
<tr><td><a href="/empbft/controller?empID=<%=id%>&amp;action=removeBenefitFromEmployee">Remove benefits from the employee</a></td></tr>
<tr><td><a href="/empbft/controller?action=queryEmployee">Query other employee</a></td></tr>
<tr><td><a href="/empbft/">Home</a><br></td></tr>
</table>
<%
    } // end of else (empId != null)
%>
</body>
</html>
<%
} // end of else (wireless)
%>

8.3.3 Separating Presentation Data into Separate Files

If you are using different files, edit the subclasses of ActionHandler to check the origin of the request, and forward the request to the proper JSP file. For example:

public void performAction(HttpServletRequest req, HttpServletResponse res)
    throws ServletException
{
   String client = req.getParameter(SessionHelper.CLIENT_TYPE_PARAMETER);
   boolean wireless = 
           client != null && client.equals(SessionHelper.CLIENT_TYPE_WIRELESS);
   String empIdString = req.getParameter(SessionHelper.EMP_ID_PARAMETER);
   boolean validEmpId = true;
   if (empIdString != null) {
      int empId = Integer.parseInt(empIdString);
      validEmpId = (empId >= 100 && empId <= 206) ? true : false;
   }

   // Forward to appropriate page
   if (wireless) {
      if (validEmpId) {
         forward(req, res, "/queryEmployeeWireless.jsp");
      } else {
         forward(req, res, "/errorWireless.jsp");
      }
   } else {
      if (validEmpId) {
         forward(req, res, "/queryEmployee.jsp");
      } else {
         forward(req, res, "/error.jsp");
      }
   }
}

The value of CLIENT_TYPE_PARAMETER is defined in SessionHelper to be clientType. This is the name of the parameter.

The value of CLIENT_TYPE_WIRELESS is defined in SessionHelper to be wireless. This is the value of the parameter.

This parameter and the value of the parameter are defined in empbft.xml. This file corresponds to the ID page for wireless. It enables users to enter a number in a text input field.

// empbft.xml
<?xml version = "1.0" encoding = "ISO-8859-1"?>
<SimpleResult>
  <SimpleContainer>
    <SimpleForm title="Query Employee" target="/empbft/controller">
       <SimpleFormItem name="empID" format="*N">Enter Emp ID: </SimpleFormItem>
       <SimpleFormItem name="action" type="hidden" value="queryEmployee" />
       <SimpleFormItem name="clientType" type="hidden" value="wireless" />
    </SimpleForm>
  </SimpleContainer>
</SimpleResult>

8.4 Header Information in JSP Files for Wireless Clients

You have to make some changes in the header of your JSP files for wireless clients:

8.4.1 Setting the XML Type

The first line of the JSP file should specify that the file is an XML file:

<?xml version = "1.0" encoding = "ISO-8859-1"?>

8.4.2 Setting the Content Type

In the JSP files for wireless clients, you need the following line at the top of the files to set the content type of the response and the character set.

<%@ page contentType="text/vnd.oracle.mobilexml; charset=ISO-8859-1" %>

You need to do this because the default value for contentType for JSPs is text/html, and this is not what you want for wireless clients.

The transformer uses the text/vnd.oracle.mobilexml value when transforming the page into data that the wireless client can understand.

8.5 Operation Details

To OracleAS, requests from wireless clients look the same as requests from desktop browsers except that the user agent field contains the name of the wireless device. However, the way in which wireless requests get to OracleAS is different: Wireless requests first go through gateways (such as WAP, Voice, or SMS), which convert the requests to the HTTP protocol. The gateways then route the requests to OracleAS Wireless.

OracleAS Wireless processes the requests by invoking an adapter to retrieve XML from the mobile application. The XML is based on a schema defined by OracleAS.

OracleAS Wireless then invokes a transformer, which takes the XML and transforms it to a markup language appropriate for the wireless client. OracleAS sends the resulting data to the gateway, which may encode the data (to make the data more compact) before sending it to the client.

8.5.1 Query Operation

Figure 8-4 shows the flow of the query operation with wireless and browser clients. This figure is a more complex form of Figure 6-1.

Figure 8-4 contains two sequences of events. One sequence is for requests that come from browsers; steps in this sequence are noted in the figure with a "B". The other sequence is for requests that come from wireless clients; steps in this sequence are noted with a "W".

The steps for browser requests are covered in "Query Employee Operation". This section covers the wireless steps.

W1: The server sends the request to the Controller with the action parameter set to queryEmployee and the empID parameter set to the employee ID entered by the user.

W2: QueryEmployee.java checks the clientType parameter to determine if the request came from a wireless client or a browser. This parameter is set only in the XML files that the application sends to wireless clients; requests from browsers do not have this parameter. QueryEmployee.java also checks if the employee ID is valid.

W3: QueryEmployee.java forwards the request to queryEmployeeWireless.jsp.

W4: queryEmployeeWireless.jsp is similar to queryEmployee.jsp. It retrieves and displays employee data. Note that the retrieval method is the same in both files. The only difference is in the tags used (HTML for browsers, XML for wireless clients).

8.5.2 queryEmployeeWireless.jsp

queryEmployeeWireless.jsp looks like the following:

// queryEmployeeWireless.jsp
<?xml version = "1.0" encoding = "ISO-8859-1"?> 
<%@ page contentType="text/vnd.oracle.mobilexml; charset=ISO-8859-1" %> 
<%@ page import="java.util.*" %>
<%@ page import="empbft.component.employee.ejb.*" %>
<%@ page import="empbft.component.employee.helper.*" %>
<%@ page import="empbft.util.*" %>
<SimpleResult>
   <SimpleContainer>
<%
  String empId = request.getParameter(SessionHelper.EMP_ID_PARAMETER);
  if (empId == null)
  {
%>
     <SimpleForm title="Query Employee" target="/empbft/controller">
       <SimpleFormItem name="empID" format="*N">Enter Emp ID: </SimpleFormItem>
       <SimpleFormItem name="action" type="hidden" value="queryEmployee" />
       <SimpleFormItem name="clientType" type="hidden" value="wireless" />
     </SimpleForm>
<%
  } else {
    int id = Integer.parseInt(empId);
    EmployeeManager mgr = SessionHelper.getEmployeeManager(request);
    EmployeeModel emp = mgr.getEmployeeDetails(id);
%>
     <SimpleText>
       <SimpleTextItem>Emp ID: <%=empId%></SimpleTextItem>
       <SimpleTextItem>First Name: <%=emp.getFirstName()%></SimpleTextItem>
       <SimpleTextItem>Last Name: <%=emp.getLastName()%></SimpleTextItem>
       <SimpleTextItem>Email: <%=emp.getEmail()%></SimpleTextItem>
       <SimpleTextItem>Phone: <%=emp.getPhoneNumber()%></SimpleTextItem>
       <SimpleTextItem>Hire: <%=emp.getHireDate()%></SimpleTextItem>
       <SimpleTextItem>Job: <%=emp.getJobId()%></SimpleTextItem>
       <SimpleTextItem>Elected Benefits: </SimpleTextItem>
<%
    Collection benefits = emp.getBenefits();
    if (benefits == null || benefits.size() == 0) {
%>
       <SimpleTextItem>None</SimpleTextItem>
<%
    } else {
      Iterator it = benefits.iterator();
      while (it.hasNext()) {
        BenefitItem item = (BenefitItem)it.next();
%>
       <SimpleTextItem><%=item.getName()%></SimpleTextItem>
<%
      } // end of while
    } // end of if
%>
     <Action label="Add Benefits" type="SOFT1" task="GO"
           target="/empbft/controller?action=addBenefitToEmployee&amp;
                    clientType=wireless&amp;empID=<%=empId%>"></Action>
     <Action label="Remove Benefits" type="SOFT1" task="GO"
             target="/empbft/controller?action=removeBenefitFromEmployee&amp;
             clientType=wireless&amp;empID=<%=empId%>"></Action>
     <Action label="Query Other Employee" type="SOFT1" task="GO"
                  target="/empbft/controller?action=queryEmployee&amp;
                  clientType=wireless"></Action>
     </SimpleText>
<%
    } // end of else (empId != null)
%>
   </SimpleContainer>
</SimpleResult>


The Action tag defines popup menus (Figure 8-1, Screen 4). The user presses the Menu button to access the popup menu.

8.5.3 Add and Remove Benefits Operations

The add and remove benefits operations for wireless clients are similar to the corresponding operations for browsers. The changes in the application needed to support these operations for wireless clients include:

  • Modifying AddBenefitToEmployee.java and RemoveBenefitFromEmployee.java to check if the request came from a wireless client. The checks use the same format as in the query operation.

  • Creating addBenefitToEmployeeWireless.jsp and removeBenefitFromEmployeeWireless.jsp to define the XML for presentation.

  • Creating errorWireless.jsp to display an error message.

  • Creating successWireless.jsp, which the application displays when a user successfully adds or removes a benefit. In addition to displaying a success message, the file also defines a popup menu that enables the user to add or remove additional benefits without having to go to the main menu. This feature is not applicable to browsers. "Differences Between the Wireless and the Browser Application" describes this feature in detail.

8.6 Accessing the Application

While you are developing wireless applications, you may not have access to an environment where you can run your applications from actual wireless clients. In such cases, you can test your applications using simulators. However, before you deploy your applications in a production environment, it is highly recommended that you find or set up an environment where you can test your applications with actual wireless clients.

8.6.1 Using a Simulator

To access the application from a wireless client simulator:

  1. Enter the following URL in the simulator:

    http://<host>:<port>/omsdk/rm
    

/omsdk/rm points to the wireless application. It displays a screen with two choices:

  • Go To ...

    This selection displays a screen with a text field that enables you to enter a URL to visit.

  • Samples

    This selection displays a screen (Figure 8-1, Screen 1) that lists all the applications in a certain directory.

  1. Select Samples.

  2. Invoke your application from the list of applications.

8.6.2 Using an Actual Wireless Client

To access the application from an actual Web-enabled wireless client such as a cell phone or PDA, check that the application can be accessed publicly (that is, it is not behind a firewall). Requests from wireless clients go through gateways, which can communicate only with machines that are accessible publicly.

Your application should then appear on the list of applications when you enter the URL and follow the steps listed in "Using a Simulator".