Oracle9i Servlet Engine Developer's Guide Release 1 (9.0.1) Part Number A90213-02 |
|
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:
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.
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.)
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:
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:
/test/IDBean
", see "Compiling and Deploying the Example").
getID(String)
method to retrieve the employee's ID number, passing it the last name obtained from the query string.
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"; } }
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:
getID(String LastName)
to get the ID number from the database server.
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.)
try{}
block open an Oracle server-side internal JDBC connection.
if{}
block sets up a prepared JDBC statement. Note the '?' placeholder for the last name in the WHERE clause of the SQL statement.
pstmt.setString(1, LastName)
sets the value of the argument into the SQL statement.
getString()
method on the result set object gets the ID value.
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.
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 () {} }
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; }
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>
Follow these steps to compile and deploy the example:
loadjava
to load the IDServlet.class
file into the Oracle server.
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
.
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.
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.)
|
Copyright © 1996-2001, Oracle Corporation. All Rights Reserved. |
|