Programmer's Guide



Chapter 30   Using Servlet Business Objects

This chapter describes the servlet business object, a triggered business object that responds to requests for specific URLs. The chapter is organized as follows:

This chapter assumes that you understand the HTTP protocol, and are familiar with the contents of the HTTP request and response headers. For more information, see the JDK 2.0 documentation or the Servlet home page provided by JavaSoft.

About servlets   Top of page

Servlets are standard JDK objects that run on the server, allowing you extend the server's functionality. Servlets are associated with one or more URLs. The servlet executes when a client (such as a browser) requests one of these URLs (through an HTTP statement such as PUT, POST, GET, and DELETE). The HTTP request gets passed to the servlet as the first parameter to the service event.

The Servlet API is defined by Sun as part of the standard Java extension package javax.servlet. SilverStream HTTP listeners conform with this standard API. As a result HTTP listeners are implemented in a somewhat different way than other SilverStream business objects. Whereas most other event methods take one parameter, which is a subclass of AgoBusinessObjectEvent, the Servlet API defines five events for servlets. The primary event, service, is defined to take two interfaces as parameters, a ServletRequest and a ServletResponse.

The objects that are passed to the servlet implement these interfaces, and are also subclasses of AgoBusinessObjectEvent. This allows you access to all of the facilities available in other business object events, such as AgaDatas, AgiDatabase objects, AgiServer objects, and so on.

About the servlet business object   Top of page

A servlet business object (or HTTP listener) is a type of SilverStream business object that implements the AgiHTTPListener interface and the javax.servlet.Servlet interface. When a SilverStream application requests an URL, you can program the servlet's response.

When the SilverStream Server receives a request for an URL that has a servlet associated with it, the server broadcasts the event to the servlet and passes it an event object that includes all of the relevant information for the servlet.

NOTE   Only a single servlet can be associated with a URL.

Creating a servlet object   Top of page

You use the SilverStream Business Object Designer to create a business object and to specify a Servlet trigger. SilverStream adds the implements AgiHttpListener clause to the object's class definition and registers the object as an HTTP listener.

    For more information see the Business Object Designer chapter in the online Tools Guide.

You can also create a Java class in an external editor that implements AgiHttpListener, then import the source or class file using the SilverCmd ImportSource and ImportClass commands.

    For information see the SilverCmd Reference in the online Tools Guide.

How servlets work   Top of page

Servlets are associated with an URL (or multiple URLs) which you can define at design time or runtime. When a SilverStream application performs an operation on that URL (requests it (HTTP GET), updates it (HTTP PUT or POST), or removes it (HTTP DELETE), the SilverStream Server finds the associated servlet (HTTP listener), instantiates it (if it is an event-lifetime object), and fires the service event. The service event is passed two parameters, one representing the request (and providing access to the server environment), and another representing the response. You code the event by filling in the response.

Servlet methods   Top of page

The SilverStream Server calls the standard servlet methods listed in this table.

Servlet Event

Description

  init() 

Fires when the SilverStream Server instantiates the servlet.

For both server-lifetime and event-lifetime objects, the server instantiates the servlet when application objects first make calls to the servlet's associated URLs.

Receives a javax.servlet.ServletConfig event object.

  service() 

Fires for each URL request.

Receives a javax.servlet.ServletRequest and a javax.servlet.ServletResponse object.

  destroy() 

Fires before the servlet gets garbage collected.

For server-lifetime objects, the servlet is available for garbage collection when the server is shut down or the servlet is re-saved, so that the new one is instantiated and the old one is available for garbage collection.

For event-lifetime objects, the servlet is available for garbage collection once it finishes processing.

  getServletInfo() 

Fires when called by another object.

Returns a String with information about the servlet, such as author and copyright.

  setServletConfig() 

Fires when called by another object.

Returns a javax.servlet.ServletConfig object.

You can query the config object for information about parameters, names, and the servlet context.

Servlet processing summary   Top of page

This is a summary of how servlets are handled by the SilverStream Server.

  1. A SilverStream client (typically a browser) requests a URL that has a servlet associated with it.

    When you create the servlet business object you can specify whether it runs for the lifetime of the event or the lifetime of the server. For event-lifetime servlets, the server instantiates the servlet and fires the init event. For server-lifetime servlets, the server fires the init event at server startup or when the object was first saved. The init event contains the servlet configuration object.

  2. The server fires the service event for each request on that URL.

    The service event includes two parameters: the javax.servlet.ServletRequest and the javax.servlet.ServletResponse.

    The ServletRequest provides access to the entire HTTP request. The ServletResponse lets your write the entire HTTP reply.

    The ServletRequest and ServletResponse parameters are the standard javax.servlet parameters. The service event is an instance of the SilverStream event object AgoHTTPRequestEvent. The AgoHTTPRequestEvent has all of the common business object event information, such as AgaDatas.

    NOTE   The SilverStream helper methods usually cast the object appropriately, but sometimes you must cast it.

  3. After the servlet performs whatever you program it to do, it returns the javax.servlet.ServletResponse.

    You program the contents of the ServletResponse.

Associating URLs with servlets   Top of page

There are two ways to associate a URL with a servlet:

Specifying URLs using the Business Object Designer   Top of page

The Business Object Designer allows you to specify the URLs as one of the steps to creating the listener object. The Wizard provides this panel to supply the URLs.

If you do not specify the URL when you create the object using the Wizard, you can specify or change the URL using the Property Inspector shown here.

Choose the URLs button. SilverStream displays the same dialog box as the Wizard.

When you specify the URLs at design time, SilverStream saves them with the metadata for the object.

Specifying URLs programmatically   Top of page

To dynamically associate an URL with a servlet you get an AgiDatabase object from any event object by calling

  evt.getDatabase() 

Once you have the AgiDatabase, you can call the createServletResource() method to associate a URL with a servlet. The createServletResource() method has this declaration.

  String createServletResource(String url,String businessObjectName) throws AgoUnrecoverableSystemException, IOException 

where:

URLs that you create dynamically are not saved across sessions and are not available in the design environment.

Programming servlets   Top of page

Servlets provide a configuration object that is passed on the init event. The configuration object provides methods that you can use to obtain information about it. You should save the configuration object as a member variable so that it is available on other events.

This code shows how to save the configuration object as a member variable called javax.servlet.ServletConfig m_servletConfig in the init event.

  // Variable definition in General code section 
private javax.servlet.ServletConfig m_servletConfig;

// Code for init evt
public void init(javax.servlet.ServletConfig config) throws javax.servlet.ServletException
{
   m_servletConfig = config;
}

The configuration object provides three methods used to set initialization parameters for the servlet:

SilverStream sets no values for these initialization parameters.

ServletContext methods

The ServletContext has methods that you can use to obtain information about servlets, such as getMIMEType()and getServletNames().

The ServletContext also has methods that you can use to obtain information. SilverStream implements the methods as described in the following table.

Servlet method

Description

  getMIMEType() 

Returns the MIME-Type or Content-Type of an object based on its name passed in as a parameter.

  getServlet() 

Returns this servlet.

  getServletNames() 

Returns an Enumeration of servlets in the database.

  getServlets() 

Returns null. It is a deprecated method.

  log() 

Writes errors to the SilverStream log files.

  getRealPath() 

Translates a path passed in as a parameter. No translations are required in the SilverStream environment so this method just returns the parameter passed in.

  getServerInfo() 

Returns the name of the SilverStream Server as it appears in the HTTP header. For example, SilverStream Server Version 3.0.

  getAttribute() 

Returns null.

About request headers   Top of page

You can use the ServletRequest parameter to obtain information that the client (the browser) has passed to the server, including the names of the parameters that the client is passing to the server, the parameter's values, any query information, and cookies. You can obtain any part of the header through the appropriate method call on the javax.servlet.ServletRequest object that is passed on the service event. For example, you can obtain the request header Content-type by calling the getContentType() method in the service event:

  String ct=evt.getContentType(); 

About response headers   Top of page

You can use the ServletResponse parameter to set the information that the server returns to the client including any of the header fields (like the date), any errors that occurred on the server as the servlet processed the request, and any cookies that you want to return to the client.

SilverStream supplies a default reply with some of the header information already filled in for you. You can add additional information to the default, or change the default reply completely. SilverStream provides a limited set of header fields that it sets by default. They include:

You can override these defaults by calling the appropriate javax.servlet.Response method in the service event. For example, to set the date in the response header, you would call the setDateHeader() method.

You are responsible for constructing a valid HTTP response to return. See the HTTP specifications (RFC 2616) for details.

SilverStream servlet extensions   Top of page

SilverStream extends the standard javax.servlet.http.HttpServletRequest interface with additional functionality to support HTML forms that use the INPUT TYPE =file tag (AgiHttpServletRequest) and for fields in a multi-part/form-data POST (AgoHTTPRequestEvent).

About AgiHTTPServletRequest

The AgiHTTPServletRequest includes two methods to deal with file uploads from HTML pages: getFileContent() and getFileContentType(). Using these methods requires that the HTML form uses the tag INPUT TYPE=file to let end users submit the contents of a file in HTML.Unlike the getParameter() method provided in the standard servlet interface, which returns a String, these methods allow you to access the attachment itself. AgiHTTPServletRequest also includes a method, delegateToPage(), to delegate processing to an AgpPage.

This table is a summary of AgiHTTPServletRequest methods.

Method

Description

  delegateToPage() 

Fills in the response by delegating processing to the service method of the specified page.

  getDatabaseURL() 

Returns the URL of the database, as in "http://myserv/myDB".

  getFileContent() 

Returns the file content from an HTML form-field of type <INPUT TYPE=FILE>.

  getFileContentType() 

Returns the file content type (MIME-Type) from an HTML form-field of type <INPUT TYPE=FILE>.

  getParameterAsObject() 

Returns the value of the named HTTP parameter as an Object. The object will either be a String or a string array (String[]) for multi-valued fields. This method provides optimized access avoiding the need to create a String array when there is a single value.

  invokeBusinessObject() 

Invokes a business object.

About AgoHTTPRequestEvent

The AgoHTTPRequestEvent includes methods that allow you to access the content and content type of HTML form-fields: getFileContent() and getFileContentType(). This object also provides access, through AgoBusinessObjectEvent, to SilverStream standard business object methods, such as getAgaData(), getDatabase(), getUser(), and others.

This table is a summary of AgoHTTPRequestEvent methods.

Method

Description

  getExtensionFromURL() 

Gets the extension from a String form of an URL.

  getContentTypeFromExtension() 

Gets the content type in String form from an extension in String form.

  decodeURLEncodedForm() 

Takes a string encoded as an application/x-www-form-url-encoded MIME type and parses it into a Hashtable of query terms.

  getFileContent() 

Returns the file content from an HTML form-field of type <INPUT TYPE=FILE>.

  getFileContentType() 

Returns the file content type (MimeType) from an HTML form-field of type <INPUT TYPE=FILE>.

Servlet coding example   Top of page

     For more information about this code and other examples of using servlets, go to Triggered Business Objects>Servlets in the Application Techniques section of the help system.

The following code represents the service() method in a servlet called bosrvletArticle. This method gets the data set that is associated with the business object. It creates a query for records from the requested URL and sends the query. From the records that it retrieves (typically one record), it displays the contents of the articleData column.

  public void service(javax.servlet.ServletRequest req, javax.servlet.ServletResponse res) throws javax.servlet.ServletException, java.io.IOException 
{
AgoHttpRequestEvent request = (AgoHttpRequestEvent)req;
AgoHttpReplyEvent response = (AgoHttpReplyEvent)res;

try
{
String url = request.getPathInfo();
if (!url.equals(""))
{
url = url.substring(1);
// Get the AgaData object specified by "dataArticles".
// This is the data set associated with the
// servlet business object.
AgaData dataArticles = request.getAgaData("dataArticles");
// Create a query for data from the articles table
// for records whose url column has the same URL value as
// the request.
String sQuery = "articles.url='articles/" + url + "'";
// Send the query by calling dataArticles.query().
// The query result is stored in dataArticles.
dataArticles.query(sQuery);
byte[] articleData;
String sArticleData = "";
// To display the result, go to the first record of
// the retrieved data.
if (dataArticles.gotoFirst())
{
// Get the value of the "articledata" property and
// convert it to a String. "articledata" is the
// property name you have given the
// articles.articledata column.
sArticleData =
(String)dataArticles.getProperty("articledata");
System.out.println("====> bytedata retrieved!");
}
else
{
sArticleData = "" +
"No page was found for URL: " + url +
"";
}
// Get the String as bytes and write the servlet
// response using the output stream.
OutputStream out = response.getOutputStream();
out.write(sArticleData.getBytes());
// Set the MIME type for the response.
response.setContentType("text/html");
response.setStatus(response.SC_OK);
}
return;
}
catch (Exception e)
{
// Call sendError on the ReplyEvent
response.sendError
(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
e.toString());
return;
}
}






Copyright © 2000, SilverStream Software, Inc. All rights reserved.