Isolate server includes' runtime context
Tutorial Details:
Isolate server includes' runtime context
Isolate server includes' runtime context
By: By Borislav Iordanov
Create black-box, reusable UI components from JSP pages and Java servlets
odularization and composition are perhaps the two most important features we have come to rely on in every modern programming environment. Server-side Java Web development technologies offer several means to decompose an application into reusable units. But encapsulating and reusing frontend logic remains one of the most challenging aspects of Web application design. Custom tags constitute one way of encapsulating presentation logic and reusing it within JavaServer Pages (JSP) pages. However, they have several notable disadvantages such as requiring a fair amount of Java programming expertise as well as recompilation and redeployment upon change. Usage of the standard server-side include mechanisms is more common. Includes are more accessible to Web authors and often appear as the more practical solution even to experienced Java developers. Still, the reuse usually achieved through includes rarely goes beyond the simple, macro-like textual level.
In this article, I present a simple technique that enables treating JSP pages and servlets as self-contained, reusable presentation modules. While it opens new and interesting possibilities for decoupling large Web applications, it does not appear to be widely adopted. Based on the dynamic include mechanism of the Java Servlet and JSP specifications, the technique can be viewed as a pattern in the context of Web programming or as an implementation of the general calling frame pattern found in nearly all modern programming languages. I introduce a small API and tag library you can use in your own Web applications. For simplicity, I will use the general term dynamic resource to refer to both JSP pages and servlets.
Note: You can download the source code that accompanies this article from Resources .
Background and problem
Recall that there are two basic means of including one JSP page from another: the <@include file="..."> directive and the standard action. The include directive performs a translation time include of the specified file's textual content. It can be considered simply as a type of macro facility. The include action, on the other hand, invokes the specified server-side resource at runtime. From a programming perspective, it is a form of a procedure call. For more on the differences between static and dynamic includes, please see Resources .
Yet, to truly treat a JSP page or servlet as a standalone piece of logic, we would like to view it as a user interface (UI) component that can be configured and invoked to render itself. The invocation part is already handled by the dynamic include mechanism. Configuration is the trickier part. Because the dynamic include is implemented as a separate server-side request, you can always append a query string to the Uniform Resource Identifier (URI) and pass request parameters as you would do in a normal URL link. The standard include dispatching mechanism scopes the request parameters; the original request parameters are available with include-specific ones taking precedence in the case of a name conflict. However, there are a few limitations:
No servlet API allows you to programmatically manage the parameters passed to the include, besides appending a query string to the URI path
You can't hide the original request parameters
Request parameter types can only be regular strings
The first problem is admittedly a minor point in cases where the presentation is exclusively generated through JSP pages. The second becomes an issue in larger applications where resources are included from different contexts and their behavior depends on the presence (or absence) of a very specific set of request parameters. The last problem is the most problematic. It imposes a serious restriction on the kind of information one can pass to the included resource.
Because of the third limitation in the above list, information between the various dynamic resources composing a request's final output is usually passed around in the form of request-scoped attributes. It is then accessed within a JSP page through standard JSP actions or JSTL (JSP Standard Tag Library) EL (expression language) expressions. (Please see Resources if you are unfamiliar with the JSTL and its expression language.) But storing request attributes pollutes the global request namespace and frequently leads to subtle bugs. It imposes a heavy burden on both an included resource author and an including servlet author, as they both must be aware of all possible contexts in which the inclusion is performed and carefully manage the naming of attributes. For instance, if the included resource sets some request attributes, perhaps to include in turn another resource, how can you be sure it is not overriding a global attribute? Or, when it checks for presence of an attribute to decide on some action, how can you be sure that the attribute in question is present, but for entirely different purposes and/or with a completely different type? The list of potential problems goes on. In brief, it is very difficult to work with the dynamic resource as a black-box independent of the current global runtime context.
Solution: Add calling frames to dynamic includes
To solve this problem, I apply an old trick and create a calling frame for the data passed to an invoked process and destroy it once that process completes execution. Given the standard runtime semantics of dynamic includes, which stipulate that the inclusion be performed in the same thread and with its own request instance, this approach is only natural. When performing an include of some JSP page or servlet, you pass to it your own request object with its own attributes map. The latter acts as a local calling frame similar to a stack frame in a conventional procedure call. After the inclusion is done, your custom request object can be released together with its set of local attributes.
With this setup, the request instance of a dynamic resource has its own attribute namespace, and it is completely safe for authors to assume that upon return from the inclusion, the request object's original state will remain untouched. Thus, a dynamic resource becomes a well-encapsulated functional unit that can be safely reused from various places as long as the caller complies with its "interface." One does not have to manage a global namespace for the whole request processing.
You can implement this strategy by writing a simple request replacement class and a few supporting custom JSP tags to use instead of the standard jsp:include action.
Implementation
The basic Servlet API for performing dynamic includes is the RequestDispatcher class. An instance can be obtained through a call to the current request instance's getRequestDispatcher() method:
RequestDispatcher dispatcher = request.getDispatcher(resource_uri);
where resource_uri is the relative URI path to the desired resource. The actual include is done by calling:
dispatcher.include(request, response);
Notice that a request object is passed to the include() method. This is the request instance available to the included resource; it is also your opportunity to plug in a custom request.
Your strategy is to implement your own version of the standard ServletRequest interface that wraps the current request object and maintains its own set of attributes. The wrapper class will delegate all method calls, except the ones dealing with setting and getting attributes, to the current request instance. A standard convenience implementation called class javax.servlet.ServletRequestWrapper , which does most of the work for you, already exists. You just extend it and override the methods of interest, namely the attributes map manipulation methods. Listing 1 shows this code.
Listing 1
public class IncludeServletRequestWrapper extends ServletRequestWrapper
{
private boolean hide_scope = true;
private HashMap attributes = new HashMap();
public IncludeServletRequestWrapper(ServletRequest request)
{
super(request);
}
public IncludeServletRequestWrapper(ServletRequest request, boolean hideScope)
{
super(request);
this.hide_scope = hideScope;
}
/**
* Specify whether the enclosed request scope should be available. In other
* words, specify whether attributes of the wrapped request should
* be searched.
*
* @param hideScope true if attributes of the
* wrapped request should remain hidden and false otherwise.
*/
public void setHideScope(boolean hideScope) {this.hide_scope = hideScope;}
/**
* Return true if the scope (set of attributes) of
* the enclosed request are hidden and false otherwise.
*/
public boolean getHideScope() { return this.hide_scope; }
/**
* Remove all local to this wrapper request attributes.
*/
public void clear()
{
attributes.clear();
}
/**
* Retrieve an attribute of this request. If the attribute is not found
* in this wrapper and hideScope is false, then the parent
* request object is searched.
*
* @param name The name of the attribute.
* @return The attribute's value if found and null otherwise.
*/
public Object getAttribute(String name)
{
Object result = attributes.get(name);
if (result == null && !hide_scope)
result = super.getAttribute(name);
return result;
}
/**
* Remove an attribute from the local request scope.
*
* @param name The attribute's name.
*/
public void removeAttribute(String name)
{
attributes.remove(name);
}
/**
* Set an attribute in the local request scope.
*
* @param name The name of the attribute.
* @param value The value of the attribute. If null , the call will
* effectively remove any existing attribute with the name.
*/
public void setAttribute(String name, Object value)
{
attributes.put(name, value);
}
/**
* Return the names of all available request attributes.
*/
public Enum
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Isolate server includes' runtime context
View Tutorial: Isolate server includes' runtime context
Related
Tutorials:
Make room for JavaSpaces, Part 2 - JavaWorld January 2000
Make room for JavaSpaces, Part 2 - JavaWorld January 2000 |
JNDI overview,
Part 3: Advanced JNDI - JavaWorld March
2000
JNDI overview,
Part 3: Advanced JNDI - JavaWorld March
2000 |
Encapsulate reusable functionality in JSP
This tutorial shows you how you can encapsulate the resuable functionality in JSP pages. |
Programming restrictions on EJB - JavaWorld August 2000
Programming restrictions on EJB - JavaWorld August 2000 |
Get the app out - JavaWorld January 2001
Get the app out - JavaWorld January 2001 |
J2EE or J2SE?
JNDI works with both
J2EE or J2SE?
JNDI works with both |
Master J2ME for live data
delivery
Master J2ME for live data
delivery |
Score big with
JSR 77, the J2EE Management Specification
Score big with
JSR 77, the J2EE Management Specification |
Rumble in the
jungle: J2EE versus .Net, Part
1
Rumble in the
jungle: J2EE versus .Net, Part
1 |
Business process
automation
made easy with
Java, Part 1
Business process
automation
made easy with
Java, Part 1 |
All that JAAS
All that JAAS |
Update distributed applications
Update distributed applications |
Finally, getting hands in !
Finally, getting hands in ! |
Isolate server includes' runtime context
Isolate server includes' runtime context |
Good article
Good article |
Second-generation aspect-oriented
programming
Second-generation aspect-oriented
programming |
Reuse Tiles and Simplify UI
JavaServer Pages (JSP) technology supports application object reuse through includes, which allow other files (including other JSPs) to be sourced into a JSP file either at compile time or dynamically at application runtime. This is great for abstracting |
Free JSP, Free EJB and Free Servlets Hosting Servers
Free JSP, Free EJB and Free Servlets Hosting Servers
Free JSP, Free EJB and Free Servlets Hosting Servers
Web roseindia.net
Other Free Hosting Services
MyCGIserver - Free Hosting server provides the following support with the free account:
JSP |
Free JSP, Free EJB and Free Servlets Hosting Servers
Free JSP, Free EJB and Free Servlets Hosting Servers
Web roseindia.net
Free JSP, Free EJB and Free Servlets Hosting Servers
MyCGIserver - Free Hosting server provides the following support with the free account:
JSP 1.1, Servlets, Apache Cocoon, |
UltraLightClient Community Site
Community-driven Wiki site for UltraLightClient Code Snippets and Contributions
If you want to contribute, please go to Register as Committer. There is no support for the content on this site by Canoo. Committers agree that the code can be used free of c |
|
|
|