Chapter 23 Creating Java Servlets


Writing servlets for Jaguar

You can implement servlets for Jaguar as you would for any other server that follows the Java servlet specification. Servlets for Jaguar can be coded to the standard Java servlet API and use classes in the javax.servlet and javax.servlet.http packages. This section lists coding information specific to Jaguar and describes Jaguar's extensions to the standard servlet API.

Connection caching

Servlets can use these classes to retrieve cached connections:

These classes are documented in Chapter 1, "Java Classes and Interfaces" of the Jaguar CTS API Reference.

Component invocations

Servlets in Jaguar can instantiate component instances using the same technique used within EJB or Java/CORBA components. Use the EJB technique when portability to other J2EE servers is required.

Using the EJB technique To invoke component methods, use the lookup method in class javax.naming.InitialContext to resolve the Bean's home interface, then create a reference to the remote interface. For example:

import javax.ejb.*;
import javax.naming.*;

QueryBean _queryBean;
String _queryBeanName =
"java:comp/env/ejb/querybean" ;
Context ctx = getInitialContext();
try {
Object h = ctx.lookup(_queryBeanName);
QueryBeanHome qbHome = (QueryBeanHome)
javax.rmi.PortableRemoteObject.narrow(h, QueryBeanHome.class);
_queryBean = qbHome.create();
}
catch (NamingException ne)
{
System.out.println("Error: Naming exception: "
+ ne.getExplanation() + ne.toString());
throw new Exception(
"Lookup failed for EJB " + _queryBeanName);
}

For more information on the EJB client interfaces, see Chapter 9, "Creating Enterprise JavaBean Clients". For servlets installed in a Web application, you can define an EJB reference in the Web application properties to alias the name used in your source code. The EJB reference allows the Web applicatoin to be deployed on another J2EE server without changing your servlet code. See "EJB references" for more information.

Using the Java/CORBA technique To invoke component methods, create an ORB instance to obtain a proxy for the components, then invoke methods on the proxy object reference. For components on the same server, call the string_to_object method with the IOR string specified as Package/Component. For example, the fragment below obtains a proxy object for a component called Payroll that is installed in the Finance package:

java.util.Properties props = new java.util.Properties();
props.put("org.omg.CORBA.ORBClass",
"com.sybase.CORBA.ORB");
ORB orb = ORB.init((java.lang.String[])null, props);
Payroll payroll =
PayrollHelper.narrow(orb.string_to_object(
"Finance/Payroll"));

By default, servlets run without a user name and password. A servlet client, authenticated by the Jaguar server, runs with the client's user name and password. If an unauthenticated servlet client invokes a component method, the component is instantiated without a user name and password. If roles limit access to a component or method and the servlet has no user name, a method invocation attempt fails. To specify a user name, use this syntax:

PayrollHelper.narrow(orb.string_to_object(
"iiop://0:0:<user_name>:<password>/Finance/Payroll"));

Where iiop://0:0 is equivalent to iiop://this_host:this_port .

Threading

If possible, servlets should be coded to be thread-safe, such that the service method can be called concurrently from multiple threads. This threading model is the default for servlets running in Jaguar. In most cases, it offers the best performance. If your servlet cannot support this threading model, you must do one of the following to ensure that the servlet executes safely in Jaguar:

Logging

Servlets can log error messages or other text to the Jaguar servlet log file, using the standard servlet log methods in the ServletContext class (or the equivalent methods in the GenericServlet class). Jaguar records servlet log messages in the httpservlet.log file, located in the Jaguar bin subdirectory. If you define additional servers, the name of the servlet log file is prepended with the server name. For example, if you create a server named Test_server, then servlet messsages for that server are directed to the Test_serverhttpservlet.log file.

Error pages

You can customize error and exception reports that are sent to Web application clients by creating error pages. When the servlet engine detects an error or catches an exception thrown by a servlet, it searches for a corresponding error page to handle the response. This example illustrates how to declare an error page in the deployment descriptor:

<error-page>
<error-code>404</error-code>
<location>/etc/404.html</location>
</error-page>

The location is the path relative to the Web application's context root. For example, /etc/404.html corresponds to this file in your Jaguar installation directory, where web-app is the name of the Web application:

Repository/WebApplication/web-app/etc/404.html

For information about how to use Jaguar Manager to set up an error page, see "Error pages".

Request dispatching

A RequestDispatcher instance allows one servlet to invoke another and either forward a request, or include the target servlet's response with its own. The RequestDispatcher interface provides methods to accomplish both. To obtain an object that implements the RequestDispatcher interface, use one of these ServletContext methods:

To forward a request, the initial servlet calls the forward method of the RequestDispatcher interface. The target servlet returns the response. This method can be called only if no output has been committed to the client. Before the forward method returns, the response must be committed and closed by the servlet container.

To include a target servlet's response with its own, the initial servlet calls the include method of the RequestDispatcher interface. The target servlet has full access to the request object but can write only to the ServletOutputStream or Writer of the response object and it cannot modify the response headers. The target servlet can commit a response by either writing past the end of the response buffer, or explicitly calling the flush method of the ServletResponse interface.

URL interpretation

The ServletContext and ServletRequest objects both contain methods to retrieve a RequestDispatcher instance. ServletContext methods require an absolute URL. ServletRequest methods can interpret a relative URL. Both URL types must follow these guidelines:

A ServletContext.getRequestDispatcher URL must begin with a forward slash ('/'). If a ServletRequest.getRequestDispatcher URL begins with a forward slash, the servlet engine interprets it as an absolute URL. Otherwise, the servlet engine appends the relative URL to the current request's URI path. For example, if the current request is /catalog/garden.html and the relative URL is sports.html, then the new URL is /catalog/sports.html.

Implementation

Jaguar's servlet engine passes all servlet invocation requests through a RequestDispatcherobject instance. When the servlet engine receives a request from a client, it calls the RequestDispatcher.service method. This method loads, initializes, and handles instance pooling of single-threaded servlets. It also invokes the servlet and handles errors.

Static content

A RequestDispatcher instance would typically be used for servlets and JSPs, but it can also be used for static content. If the servlet engine forwards a request to a static content RequestDispatcher, the RequestDispatcher must set the response status, the response headers, and the response data. If a static content RequestDispatcher is called to set the data for the current request, it only needs to return the content of the static page.

Response buffering

The Java servlet API supports response buffering that allows the servlet to control how the servlet container buffers responses, and when to send a response to a client. The ServletResponse interface provides these methods that allow a servlet to access buffering information:

See the Java Servlet Specification, v2.2 for detailed information about using response buffering.

Encoding responses and double-byte characters

When you compile a Java servlet, the characters are encoded according to the locale of your machine unless you specify encoding in the javac compile command. When a client sends a request from a browser, the parameters are always ISO 8859-1 encoded.

To provide a client's browser with the encoding information it needs to translate the content of a response correctly, declare the encoding in the response header. If you specify the content type without the encoding information, for instance:

response.setContentType("text.html");

the client's browser assumes that the content is ISO 8859-1 encoded. If the content has been encoded using some other standard, the client's browser does not translate the data correctly. This example specifies the double-byte character set big5, the encoding name of traditional Chinese characters:

response.setContentType("text/html;charset=big5");

To encode the response content, compile the servlet with this encoding option:

javac -encode iso-8859-1 <java source file>

or convert static strings within the servlet code, for instance:

String origMsg = "<double-byte character string>";
String newMsg = new String(origMsg.getBytes(), "iso-8859-1");

 


Copyright © 2000 Sybase, Inc. All rights reserved.