tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Talin <ta...@brodia.com>
Subject Model-View-Controller archecture for JSPs
Date Fri, 25 Feb 2000 00:43:30 GMT
This is a suggestion.

We've been using a "Model-View-Controller" paradigm with our JSP pages, and
it's one of the best decisions we ever made.

Some background: Model-View-Controller (MVC) was first introduced with the
SmallTalk user interface on the Alto. The idea is that a GUI can be broken
down into three types of components: The Model which stores the state, the
View which controls the presentation of the state, and the Controller which
allows the editing of the state.

However, in most modern GUIs the View and Controller elements are combined
into a single object, often called a "widget". For example, a slider class
will be both a view (showing the value) and a controller (allowing dragging
of the knob). For GUIs, this combination is generally OK, since there is a
generally a 1:1 correspondance between controllers and views.

A similar situation exists with most web-based applications - the code to
handle input is often intermixed with the code to generate the view, in this
case the HTML output. This is particularly true in the case of JSP pages.
But it is not so clear that combining the view and controller are as good of
an idea here. The JSP examples on the Sun website are a good example of why
combining the view and the controller is in fact NOT a good idea - the code
is strange and hard to understand. Adding a web form into a page also
requires that you embed the logic for handling that form onto the target
page. If several different forms can post to the same page, or the same form
can post to various different pages then you end up having to embed the
logic for handling the query parameters in many different places, and it
quickly becomes confusing. An example of this is a preferences component in
a sidebar which appears on several different pages. The preferences
component has an "update preferences" button which sends a POST to whichever
page is currently being viewed. The same page is redisplayed with the new
preferences. Seperating the view from the controller allows the logic for
changing preferences to be centralized in a single location.

I've been looking around the web, and I've noticed a couple of attempts to
seperate the handling of input from the generation of pages, but in many
cases this seperation is done in a way that is either incomplete, hard to
use, or doesn't work with JSP pages. Of course, I haven't seen everything
that's out there...

Anyway, the system that I have is very simple: There is a RequestHandler
class which is used to handle the incoming HTTP request. This is similar but
not identical to the Tomcat concept of interceptors. To create a new
handler, you need to subclass the RequestHandler class and then register
that class with the handler manager. (The registration is handled by listing
each handler in the configuration file). Each handler has a unique ID
string, which is used as a hash table key to get access to that handler.

Handlers are invoked using the query parameter "handler=". In our servlet,
if we see a "handler" parameter, we grab the value of that param and look it
up in the hash table, which results in the handler object. The handler is
then passed the request and response objects (and some other context info).
Handlers can do redirects and forwards if needed. (Note: Originally I was
just going to have the handler parameter be just the name of the class, but
this turns out to be a bad security hole.)

Note that unlike interceptors, only one handler can be run per request.
However, that's generally OK, since the user can only hit one submit button
at a time. Also unlike interceptors, the handler that gets run is different
for different forms. (You could easily implement the handler system using
interceptors, however.)

Calling a handler from a FORM is simple: For example, in the preferences
panel, all you would have to do is say:

	<form method="POST" action="<%= getThisURI() %>?handler=prefs"> ...
etc.

This means that the preferences component can easily be included in any
page. Just add one line of JSP code to include the component and you're
done.

What we've learned is that the handler system is easy to use and contributes
to an overall cleanliness and organization of JSP pages - in fact, we pretty
much use handlers for all processing of input, even if it's a case that's so
simple that the handler system isn't needed.

One thing that the system lacks is the ability to add handlers while the
server is running, the same way that JSP pages can be edited and added.
However, this hasn't been a big problem for us.

Anyway, I'm sure many of you have thought about this already, although not
in perhaps the same terms. I mean, it seems so simple and obvious...at the
same time, I've seen a lot of code examples out there which suffer badly
because they haven't adopted a model like this.

Mime
View raw message