tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Talin <>
Subject RE: some cool hacking projects...
Date Thu, 14 Oct 1999 22:30:04 GMT
> How does this compare with the jsp:forward or jsp:include actions?

They are both quite different.

jsp:forward redirects the entire page to a new template page.

jsp:include is a static inclusion. The included text becomes part of the
same java class as the overall page.

Components are different. Each component is compiled into a seperate
Java class, using a method which is identical to JSP pages. (And in
fact, in our system, JSP pages are simply components with no arguments
that live in a different directory.) So if a component, such as a search
box or a stock ticker, is used on 10 different pages, there is only one
copy of the Java code to generate the search box HTML residing in

When a component finishes generating content, control returns to the
calling page, which continues where it left off. A single page may call
many components, which in tern may call sub-components, etc.

The result of this is that the total amount of HTML in our application
has been reduced by about 1/3.

In addition, the choice of which component is executed can be made at
the time the page is generated. The name of the component is simply a
string, which can either be a string literal, or a calculated
expression. This allows, for example, pages which are customizable by
end-users, as seen in portal sites such as In our case, it
allows us to assemble different feature sets for our different affiliate

Unlike regular JSP pages, components can be passed arguments when they
are called. For example, we have a component which displays a set of
file tabs, allowing the user to select between various "modes". Which
tab is currently selected is passed as an argument to the component,
which uses this image to display the appropriate file-tab image.

Components arguments are passed as an array of strings to the
component's "apply" function. Unfortunately, we can't simply pass
arbitrary types to the component because we want all web pages to be
polymorphic. Instead, we opted for each template page (whether top-level
page or component) to take a string argument list. We could probably
have changed this to allow templates to take an array of objects,
however since cast operations are slow in Java we decided that strings
were probably better in this case.

The component system has been a really huge win for us - at the current
time, most of our HTML pages are just a few lines of component calls,
with a little bit of formatting glue (like tables) between them. All of
the real "meat" of the page is within components.

Of course, we've made a significant departure from the JSP model in
order to do this. For one thing, the Java classes that components are
compiled into are not descended from "Servlet", but have their own base
class. The reason for this is the need to pass arguments into the
component. Another reason is that we buffer the output of the page
generation before committing it to the socket, so that a component can
add headers or do redirects, which can't be done if we've already sent
some content to the client.

Also, one of the potential problems with components is the handling of
embedded forms within components. For example, if a component appears on
10 different web pages, does this means that all ten pages need to
contain the logic to handle POSTS from that component? The solution is
to divide the handling of the HTTP request function into two phases, one
to process the input parameters and one to generate the page. The first
phase uses a "handler=ID" parameter in the query string to route the
incoming request to the correct handler class (although there are some
security issues here - it should not be possible to execute arbitrary
code on the server by twiddling the handler parameter). Once the request
params have been handled, and a template has been selected, then the
page generation phase can begin. In general, only in the first phase are
database updates performed and other state changes such as cookie

Another cool thing we've built here is appearance management. Basically,
each HTTP request that comes in is associated with an "Appearance"
object, which is selected based on the URL path, on cookie data, on
request parameters, session parameters, or in some other place. The
appearance object contains a set of java properties which can be used to
do runtime substitutions of pages styles. For example, an appearance
object can have a property called "page.backgroundColor". There is also
a "Platform" object which is associated with each different browser
type. These objects are initialized in a lazy fashion, that is the
object is created the first time anybody uses it, then cached in a hash
table for easy access on subsequent requests. The appearance and
platform properties are stored in a set of ordinary Java properties text
files. Once the objects have been created, the template system can take
insert an appearance- or platform-specific text at any point, for
example <%=page.appearance.getProperty("backgroundColor")%>

With appearance management, we can take the same basic content and
"brand" it for different affiliate partners, so that the page looks
substantially different. Yet this does it in a way that is relatively
easy to author, and maintains a high level or performance.

The component system and the appearance management system interact in
various interesting ways, such as storing the name of a component as an
appearance proprerty, or storing decorative "wrappers" in the appearance
object which wrap around the output of a component, putting it into a
bordered box. This way we can have, for example, a search box which
doesn't need to know whether it's in a blue box with a thin orange
border, or a black box with a thick white border.

One thing that we are planning to implement in the near future is an
authorization system that will use a capability model to allow access to
restricted pages based on client-side certificates, smart cards and
other authentication tokens.

View raw message