Oracle9i Servlet Engine Developer's Guide
Release 1 (9.0.1)

Part Number A90213-02
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback

Go to previous page Go to next page

6
Calling EJBs

This chapter tells you how to call Enterprise JavaBeans (EJBs) from servlets running in the OSE/OJVM servlet container.

This chapter covers the following topics:

Overview

When you call a server-side EJB from a client application, you must use a network protocol that involves an ORB, such as RMI over IIOP. However, calling out from the servlet to an external object that is in the same session as the servlet can be much simpler and faster than calling from a client. When the servlet and the other object are running in the same server session, the connection between them does not involve network traffic, only in-memory resource-sharing. Also, no ORB is involved, making the calling code in the servlet code simpler. All you need to do is specify the name of the object to look up.

The remainder of this chapter documents an example that demonstrates calling an EJB from a servlet in the same Oracle Java Virtual Machine session.

EJB Example

In this example, the EJB accesses the Oracle database to retrieve the employee ID number for an employee whose last name was passed to the EJB from the servlet. So the example comprises four elements:

The example is kept simple, so that you can easily see how the four elements interact.

In order to compile and run the example, the Oracle9i server must be installed and running, and the HR example schema must be installed in the database. (The HR schema is preconfigured.)


Note:

The HR schema is not available in the Oracle8i Release 3 distribution. But this example would work for Oracle8i (Release 3) if you change the SQL statement in the EJB code to access the SCOTT.EMP table, and change the Makefile or batch file to access the SCOTT schema, rather than the HR schema. 


There are two main pieces of code that make up the example:

In addition to these, there are the EJB Home and Remote Interface specifications:

Finally, there are several support files required for any application that uses EJBs:

Servlet

The servlet is called from a client, such as Web browser. The client must pass the employee last name to the servlet in a query string. See "Accessing the Servlet" for an example of the kind of URL that you could use to invoke the servlet.

The servlet code is listed in this section. The servlet performs the following steps:

  1. Imports the required Java packages, including the EJB home and remote interfaces.

  2. Declares Java variables for the last name, and for the ID number that is returned by the bean.

  3. Gets the last name from the query string.

  4. Gets a new Initial Context for calling the EJB.

  5. Looks up the EJB home interface, using the name of the bean as published in the JNDI namespace ("/test/IDBean", see "Compiling and Deploying the Example").

  6. Creates a reference to the remote interface.

  7. Calls the EJB getID(String) method to retrieve the employee's ID number, passing it the last name obtained from the query string.

  8. Prints the ID number to the HTTP response output stream.

The listing for the code, IDServlet.java, is shown here:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
import IDCommon.ID;
import IDCommon.IDHome;
import javax.naming.Context;
import javax.naming.InitialContext;

public class IDServlet extends HttpServlet
{ 
  public void doGet (HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException
  {
    String EmpID = null;
    String LastName = null;
    PrintWriter out = new PrintWriter(resp.getOutputStream());

    LastName = req.getQueryString();

    try {
      InitialContext ic = new InitialContext();
      IDHome ID_home = (IDHome)ic.lookup ("/test/IDBean");
      ID id = ID_home.create ();
      EmpID = id.getID(LastName);
      out.println (LastName + "'s employee ID is " + EmpID);
    } catch (Exception e) {
      EmpID = "Error";
    }
    out.flush(); out.close();
  }


  public void init(ServletConfig cfg) throws ServletException {
    super.init(cfg);
  }
  

  public void destroy() {
    super.destroy();
  }

  public String getServletInfo() {
      return "Servlet calling EJB example";
  }
}

EJB

The Enterprise JavaBean that is called by the servlet takes the employee's last name that is passed from the servlet, and looks up the ID number in the database. The EJB performs the following steps:

  1. Imports the required packages. Note that the SQL and the Oracle JDBC packages must be imported for the JDBC code in the example to work (or even compile).

  2. The bean implements a method getID(String LastName) to get the ID number from the database server.

  3. The bean method declares a JDBC connection conn, a JDBC result set rset, and a String EmpID for the ID. (The ID number could have been retrieved into an int, but the String is used as a "quick and dirty" way of returning a SQL error if the JDBC connection or query fails.)

  4. The first two Java statements in the try{} block open an Oracle server-side internal JDBC connection.

  5. The if{} block sets up a prepared JDBC statement. Note the '?' placeholder for the last name in the WHERE clause of the SQL statement.

  6. pstmt.setString(1, LastName) sets the value of the argument into the SQL statement.

  7. The query is executed, and the next value for the query is obtained. Note that if there is more than one person with the same last name in the table, only the first person's ID is retrieved.

  8. The getString() method on the result set object gets the ID value.

  9. If the JDBC-related statements fail, the catch{} block is executed. The text string for the SQL exception is placed in the return value EmpID. Oracle does not recommend this technique as a standard way for applications to handle JDBC errors. It is done here to keep the example simple. See the Oracle9i JDBC Developer's Guide and Reference for better ways to handle errors of this kind.

  10. Finally, the ID number is returned as a string to the EJB caller--the servlet.

EJB Code

The code for IDBean.java is shown here:

package IDServer;

import javax.ejb.SessionBean;
import javax.ejb.CreateException;
import javax.ejb.SessionContext;
import java.rmi.RemoteException;
import java.sql.*;
import oracle.jdbc.*;

public class IDBean implements SessionBean
{
  public String getID (String LastName) throws RemoteException {
    Connection conn = null;
    ResultSet rset = null;
    String EmpID = null;
    try {
      OracleDriver ora = new OracleDriver();
      conn = ora.defaultConnection();
      if (conn != null) {
        PreparedStatement pstmt = conn.prepareStatement
          ("select employee_id from hr.employees where last_name = ?");
        pstmt.setString(1, LastName);
        rset = pstmt.executeQuery();
        if (rset.next()) {
          EmpID = rset.getString(1);
        else
          EmpID = "Unknown";
        }
      }
    } catch (java.sql.SQLException e) {
      EmpID = e.getMessage();
    }
    return EmpID;
  }

  // Methods of the SessionBean

  public void ejbCreate () throws RemoteException, CreateException {}
  public void ejbRemove() {}
  public void setSessionContext (SessionContext ctx) {}
  public void ejbActivate () {}
  public void ejbPassivate () {}

}

EJB Interfaces

The EJB home interface (IDCommon/IDHome.java) specification is:

package IDCommon;

import javax.ejb.EJBHome;
import javax.ejb.CreateException;
import java.rmi.RemoteException;

public interface IDHome extends EJBHome
{
  public ID create () throws RemoteException, CreateException;
}

The remote interface (IDCommon/ID.java) is:

package IDCommon;

import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface ID extends EJBObject  
{
  public String getID (String LastName) throws RemoteException;
}

EJB Descriptors

The EJB descriptor for this example is:

<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems Inc.//DTD Enterprise JavaBeans 1.1
//EN" "ejb-jar.dtd">
<ejb-jar>                     
 <enterprise-beans>            
   <session>                   
   <ejb-name>IDBean</ejb-name>
   <home>IDCommon.IDHome</home>
   <remote>IDCommon.ID</remote>
   <ejb-class>IDServer.IDBean</ejb-class>
   <session-type>Stateful</session-type>
   <transaction-type>Container</transaction-type>
  </session> 
 </enterprise-beans>
 <assembly-descriptor>
   <security-role>
     <role-name>OraclePublicRole</role-name>
   </security-role>
   <method-permission>
     <role-name>OraclePublicRole</role-name>
     <method>
       <ejb-name>IDBean</ejb-name>
       <method-name>*</method-name>
     </method>
   </method-permission>
   <container-transaction>
     <method>
      <ejb-name>IDBean</ejb-name>
      <method-name>*</method-name>
     </method>
     <trans-attribute>Required</trans-attribute>
   </container-transaction>
 </assembly-descriptor>
</ejb-jar>

The Oracle-specific descriptor is:

<?xml version="1.0"?>
<!DOCTYPE oracle-ejb-jar PUBLIC "-//Sun Microsystems Inc.//DTD Enterprise JavaBe
ans 1.1//EN" "oracle-ejb-jar.dtd">
<oracle-ejb-jar>
 <oracle-descriptor>
   <ejb-name>IDBean</ejb-name>
   <mappings>
     <ejb-mapping>
       <ejb-name>IDBean</ejb-name>
       <jndi-name>test/IDBean</jndi-name>
     </ejb-mapping>
     <security-role-mapping>
        <security-role>
          <role-name>OraclePublicRole</role-name>
        </security-role>
        <oracle-role>PUBLIC</oracle-role>
     </security-role-mapping>
     <transaction-manager>
       <default-enlist>True</default-enlist>
     </transaction-manager>
   </mappings>
 </oracle-descriptor>
</oracle-ejb-jar>

Compiling and Deploying the Example

Follow these steps to compile and deploy the example:

  1. Use a JDK 1.2-compliant Java compiler to compile

    • ID.java

    • IDHome.java

    • IDBean.java

    • IDServlet.java

  2. Use loadjava to load the IDServlet.class file into the Oracle server.

  3. Publish the servlet to the JNDI namespace. For the URL specified below, we assume that the servlet has been published to the named_servlets directory in the HR servlet context (/HRRoot/contexts/HRContext). See Chapter 3, "OSE Configuration and Examples" for more information about loadjava and publishservlet.

  4. Deploy the EJB to the server using the deployejb command. Here is a possible deployejb command for this example:

    % deployejb -republish -addclasspath .:<your_classpath> -temp temp \
    -user HR -password hr
    -service sess_iiop://<host_name>:<your_port_number>:<your_Oracle_SID>
    -descriptor ID.xml -oracledescriptor IDMap.xml server.jar

There is a Makefile, and Windows NT batch files, that show how to compile this demo, in the demo samples directory of your Oracle installation.

Accessing the Servlet

You can access the servlet from a Web browser, for example Netscape Navigator or Internet Explorer. To invoke the servlet, specify a URL of the general form:

http://<your_host_name>:<port_number>/
<context_virtual_path>/<servlet_virtual_path>?<employee_last_name>

(But all on one line.) Here is a specific URL that was used in testing this example:

http://dlsun1497:8060/ose/testID?Kumar

Where dlsun1497 is the author's workstation (inside the Oracle firewall, sorry), 8060 is the port number that the HTTP service listens on, /ose is the virtual path for the HRContext servlet context (see Chapter 3, "OSE Configuration and Examples"), and /IDtest is the virtual path that IDServlet was published under in step 3 above.

If you do not specify a query string in the URL, the Web client prints:

null's employee ID is Unknown

If you specify an employee name that does not exist in the HR.EMPLOYEES table, you get:

xyz's employee ID is Unknown

(You can see why returning the error in the String is not a very good idea for a real application.)


Go to previous page Go to next page
Oracle
Copyright © 1996-2001, Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback