This section describes how to use older components (Java and C++ AppLogics) with newer components (servlets and EJBs). The following four combinations are supported:
Calling EJBs from Java AppLogics
Since there is no special context shared between servlets and EJBs, you call an EJB from an AppLogic in exactly the same way you would from a servlet.
This example shows an AppLogic accessing an EJB called ShoppingCart. The AppLogic creates a handle to the cart by casting the user's session ID as a cart after importing the cart's remote interface. The cart is stored in the user's session.
import cart.ShoppingCart;
...
// Get the user's session and shopping cart
//first create the session
ISession2 sess = createSession(GXSESSION.GXSESSION_DISTRIB,
0, //no timeout
"callEjb" //app name
null, //system-gen'd ID
null);
//create an IValList to store the shopping cart in the session
IValList ival = sess.getSessionData();
ShoppingCart cart = (ShoppingCart)ival.getVal("shoppingCart");
// If the user has no cart, create a new one
if (cart == null) {
cart = new ShoppingCart();
ival.setVal("shoppingCart", cart);
}
You can access EJBs by using the Java Naming Directory Interface (JNDI) to establish a handle, or proxy, to the EJB. You can then refer to the EJB as a regular object; any overhead is managed by the bean's container.
This example shows the use of JNDI to look up a proxy for a shopping cart:
String jndiNm = "Bookstore/cart/ShoppingCart";
javax.naming.Context initCtx;
Object home;
try {
initCtx = new javax.naming.InitialContext(env);
} catch (Exception ex) {
return null;
}
try {
java.util.Properties props = null;
home = initCtx.lookup(jndiNm);
}
catch(javax.naming.NameNotFoundException e)
{
return null;
}
catch(javax.naming.NamingException e)
{
return null;
}
try {
IShoppingCart cart = ((IShoppingCartHome) home).create();
...
} catch (...) {...}
Calling Servlets from Java AppLogics
You can call a servlet from a Java AppLogic, for example if you want your AppLogic to call a JSP, using GXContext.NewRequest( ) or GXContext.NewRequestAsync( ). For more details and specific examples of NewRequest( ), see the documentation for the GXContext class in the NAS Foundation Class Reference.
To call a servlet from an AppLogic using the same process call the servlet's serlvet engine (an AppLogic called ServletRunner), do something like this:
class SomeApplogic extends Applogic {
int execute() {
valIn.setValString("appName","nsOnlineBank");
valIn.setValString("servletName","Login");
com.netscape.server.servlet.servletrunner.ServletRunner sr =
new com.netscape.server.servlet.servletrunner.ServletRunner();
sr.valIn = valIn;
sr.valOut = valOut;
sr.context = context;
sr.stream = this.stream;
sr.ticket = this.ticket;
sr.request = this.request;
sr.COMSet(COMGet());
sr.COMAddRef();
sr.execute();
...
}
}
To call a servlet from an AppLogic in a new process, i.e. using NewRequest( ), do something like this:
class SomeApplogic extends Applogic {
int execute() {
valIn.setValString("appName","nsFortune");
valIn.setValString("servletName","fortune");
valIn.setValString("SCRIPT_NAME","nsOnlineBank/Login"
retValue = GXContext.NewRequest(m_Context,
"ApplogicServlet_nsFortune_fortune",
valIn,valOut,host,port,0);
...
}
}
You can call a JSP in much the same way, as in the following example:
public class SomeApplogic extends Applogic {
int execute() {
valIn.setValString("appName","System");
valIn.setValString("servletName","JSPRunner");
valIn.setValString("JSP","nsOnlineBank/jsp/abc.jsp");
valIn.setValString("SCRIPT_NAME","nsOnlineBank/Login"
retValue =
GXContext.NewRequest(m_Context,
"Applogic Servlet_System_JSPrunner",
valIn,valOut,host,port,0);
...
}
}
To call a servlet using a GUID, do something like this:
public class SomeApplogic extends Applogic {
int execute() {
valIn.setValString("appName","nsFortune");
valIn.setValString("servletName","fortune");
newRequest("{6F3547D0-FDCB-1687-B323-080020A16896}",
valIn,valOut,0);
}
}
Calling Java AppLogics from Servlets
You can call AppLogics from servlets using GXContext.NewRequest( ) or GXContext.NewRequestAsync( ). For more details and specific examples, see the documentation for the GXContext class in the NAS Foundation Class Reference.
In order to call an AppLogic using NewRequest( ), you must first cast the server's context to an IContext object, and then set up the input and output IValList objects for the AppLogic.
This example shows how to obtain an IContext object, set up parameters for the AppLogic, and finally call the AppLogic using NewRequest( ):
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.kivasoft.applogic.*;
import com.kivasoft.types.*;
import com.netscape.server.servlet.extension.*;7
public class callAnAppLogic extends HttpServlet {
public void service(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
// first set up ic as a handle to an IContext
ServletContext sctx = getServletContext();
com.netscape.server.IServerContext isc;
isc = (com.netscape.server.IServerContext) sctx;
com.kivasoft.IContext ic = isc.getContext();
//set up IValLists and GUID
IValList vi = GX.CreateValList(); // valIn
valIn.setValString("randomParameter", "Cirdan the Shipwright");
IValList vo = GX.CreateValList(); // valOut
String al = req.getParameter("AppLogicToCall");
// expect AppLogicToCall in request
//finally, call the AppLogic
GXContext.NewRequest(ic, al, vi, vo, 0);
}
}
Accessing the Servlet's AppLogic
Each servlet is contained in an AppLogic. You can access the AppLogic instance controlling your servlet using the method getAppLogic() in the NAS feature interface HttpServletRequest2.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.kivasoft.applogic.*;
import com.kivasoft.types.*;
import com.netscape.server.servlet.extension.*;7
public class callAnAppLogic extends HttpServlet {
public void service(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
HttpServletRequest2 req2 = (HttpServletRequest2)req;
AppLogic al = req2.getAppLogic();
//al is now a handle to the superclass
...
}
}
Calling C++ AppLogics from Servlets
The method GXContext.NewRequest( ) as described in Calling Java AppLogics from Servlets calls an AppLogic by GUID and provides handles to objects as input and output parameters. This method works for calling C++ AppLogics as well as Java AppLogics, since the AppLogic is called by the specified name or GUID and not by a handle specific to Java. See the example shown in that section.
Sessions in Partially Migrated Applications
The HttpSession2 interface is an additional session interface that gives you direct access to the session object. Using this interface, you can share sessions (and therefore data) between applogics and servlets.
In servlets, a session is an instance of HttpSession. But in AppLogics, session data is an IValList object. An AppLogic stores integers, strings, and blobs (byte arrays) in a session, whereas a servlet stores serializable objects in a session. As a result, there is no immediate mapping between what an AppLogic stores and and what a servlet stores in a session (except for strings).
The HttpSession2 interface solves the issue of sharing session data. HttpSession2 provides methods for storing and retrieving integers, strings, blobs, and user login datamethods that parallel what an AppLogic developer uses. In this way, HttpSession2 enables sessions to work back and forth across AppLogics and servlets.
HttpSession2 provides loginSession( ) and logoutSession( ) for servlets to share the AppLogic session API. These two methods are typically used with isAuthorized( ), as is done for AppLogics. Servlets are also registered with an access control list, so that a secure session established in an AppLogic can be used in a servlet, and vice versa.
You also use loginSession( ) to authenticate a session. For more information, see Writing Secure Applications in the Programmer's Guide (Java).
Making the Session Visible
Note that, because sessions are controlled with cookies, a session created in an AppLogic is not visible in a servlet by default. This is because cookies are domain- and URI-dependent, and the URI for a servlet is different from that of an AppLogic. To work around this problem, call setSessionVisibility() before you call saveSession() when you create a session in an AppLogic.
It is important to do this before calling saveSession(), since saving the session also creates the session cookie.
For example, in an AppLogic:
domain=".mydomain.com";
path="/"; //make entire domain visible
isSecure=true;
if ( setSessionVisiblity(domain, path, isSecure) == GXE.SUCCESS )
{ // session is now visible to entire domain }
For more information about sessions, see Creating and Managing User Sessions in the Programmer's Guide (Java).
Converting ITemplateData to ResultSet
NAS 2.1 provided an interface called ITemplateData to represent a hierarchical source of data used for HTML template processing. In NAS 2.1, ITemplateData provides methods for iterating through rows in a set of memory-based hierarchical data and retrieving column values. This functionality is not supported in NAS 4.0, although group names are supported (and required).
In NAS 4.0, ITemplateData functionality is replaced with JDBC ResultSet objects. You can convert ITemplateData objects to ResultSets using the method convertITemplateDataToResultSet() from the BaseUtils class. For specific usage information, see the documentation for the BaseUtils class in the NAS Foundation Class Reference.
This example shows an ITemplateData conversion to a ResultSet in an AppLogic. Note that you must provide a data group name as a parameter to the conversion method.
ITemplateData itd = GX.CreateTemplateDataBasic("myTemplateData");
...//populate myTemplateData
...
ResultSet rs = convertITemplateDataToResultSet("dataGroup1", itd);