As mentioned previously, DynamoHttpServletRequest
provides methods for setting the various fields of the request, making these changed values visible to subsequent elements in the pipeline. The request is available as a Nucleus component at /OriginatingRequest
.
In addition to property setters, DynamoHttpServletRequest
provides methods for adding attributes to the request, which lets you annotate the request with additional information. The DynamoHttpServletRequest
also provides a way to attach attribute factories to the request, which allows you delay the computation of attributes until they are first needed.
Finally, DynamoHttpServletRequest
provides a way to attach permanent attributes to the request. These are attributes that stay around from request to request. These permanent attributes allow you to reuse objects, which is the key to getting high throughput out of the servlet pipeline.
These features are described in the following topics:
Request Property Setters
DynamoHttpServletRequest
offers the following setX
methods that allow you to change the properties of a request:
setAuthType
setContentLength
setContentType
setInputStream
setMethod
setPathInfo
setPathTranslated
setProtocol
setQueryString
setRemoteAddr
setRemoteHost
setRemoteUser
setRequestURI
setScheme
setServerName
setServerPort
setServletPath
These methods are derived from the base class, atg.servlet.MutableHttpServletRequest
.
In addition, DynamoHttpServletRequest
offers its own setX
methods, such as:
setBaseDirectory
setRequestLocale
setMimeType
setSession
If you set a property with one of these setX
methods, subsequent calls to the corresponding getX
method return the value that you set. These new values are also visible to servlets farther down in the pipeline.
OriginatingRequest Component
In addition, the current request is available in Nucleus as /OriginatingRequest
. The HTTP headers of the request are available as properties of this Nucleus component. This lets you get the value of the HTTP REFERER header like this, for example:
<dsp:valueof bean="/OriginatingRequest.referer"/>
Request Attributes
You can also add arbitrary keyword/value mappings to the request. These mappings are called attributes. They are added to the request by calling setAttribute
. After an attribute has been added, it can be retrieved by calling getAttribute
. These attributes are visible to your own servlets and servlets farther down the pipeline.
Attributes are often used to annotate a request with information derived from the request. For example, an attribute might hold the values of the cookies that came with the request, represented as a Dictionary
of cookie name/cookie value pairs. The entire Dictionary
is added as an attribute using a well-known attribute name, and subsequent servlets in the pipeline can access the Dictionary
of cookies by retrieving that attribute by name.
After a request has been completed, all attributes are cleared from the request before the next request begins.
Attribute Factories
One of the techniques that can be used to improve performance is to avoid calculating values unless they are needed. The previous section described how a Dictionary
of cookies might be useful as an attribute. But if only 10 percent of the requests actually use that Dictionary
, 90 percent of the requests waste cycles calculating that Dictionary
.
The DynamoHttpServletRequest
lets you register an attribute factory for an attribute. This attribute factory is able to compute the value of the attribute when it is needed. When getAttribute
is called on a request, the request determines if the value of the attribute has already been set. If not, the request checks to see if an attribute factory has been registered for that attribute. If so, the attribute factory is called to generate the value of the attribute. The generated value is then registered as an attribute and is available for subsequent calls to getAttribute
.
So for the cookies case, register an attribute factory with the request. The attribute factory can create the Dictionary
of cookies the first time the cookies attribute is accessed.
The attribute factory must be of type atg.servlet.AttributeFactory
, which defines a single method createAttributeValue
. An attribute factory is registered by calling setAttributeFactory
.
Like attributes, all attribute factories are cleared from the request after a request has been completed.
Permanent Attributes
Perhaps the most important technique for achieving high performance is reuse of objects. In Java, every object creation is expensive, and every object creation also has a delayed cost in garbage collection, so reusing objects is a guaranteed way to improve performance.
The DynamoHttpServletRequest
provides a way for you to register permanent attributes. Unlike normal attributes, permanent attributes are not cleared between requests, meaning that these permanent attributes are available for reuse by multiple requests.
For the cookie example, the Dictionary
used to hold the cookies might be stored as a Hashtable
that is a permanent attribute of the request. Instead of creating a Hashtable
for each request, the permanent Hashtable
attribute can be extracted from the request, cleared, and reused.
Adding permanent attributes to the request uses a slightly different process from adding normal attributes. Instead of having separate get
and set
methods, permanent attributes are only accessed by a getPermanentAttribute
method. The getPermanentAttribute
must be passed an AttributeFactory
. This AttributeFactory
serves two purposes: it acts as the key for the attribute, and it is used to create the attribute if it has not already been created.
The following shows how you might use a permanent attribute to store the Hashtable
for the cookies:
// Member variables class CookiesFactory implements AttributeFactory { public Object createAttributeValue () { return new Hashtable (); } } AttributeFactory cookiesKey = new CookiesFactory (); ... public void service (DynamoHttpServletRequest request, DynamoHttpServletResponse response) throws ServletException, IOException { Hashtable cookies = (Hashtable) request.getPermanentAttribute (cookiesKey); cookies.clear (); ... }
The first part of the example shows how to define an AttributeFactory
inner class that both creates the Hashtable
when needed, and also acts as the key. In the method where you need to extract the Hashtable
, you call getPermanentAttribute
, passing it the AttributeFactory
. The first time you call this on the request, it fails to find a value associated with that key, and calls on the AttributeFactory
key to create the value. Subsequent calls on that same request find and return the value that was previously registered with that key. This value remains part of the request even after the request is complete and a new request begins.
Each request object gets its own copy of your permanent attribute, so if your server is running 40 request-handling threads, you might see the permanent attribute get created 40 times, once for each request object. But after all request objects have a copy of the attribute, no more object creations are necessary.