Perspectives on Struts
By far, Struts is the most popular web framework in the Java world. I've
noticed that it is now popular enough that recruiters and IT managers are
mentioning it by name. In fact, one recruiter said that he was looking for
someone with 5 years of professional experience with Struts… I just had
to laugh.
Struts has it own list of good points, but I have a couple of issues with
it. What I would like is to dive into the internals to see if I can't fix
some of them. So, don't mind me, but I'm going to ramble on about what I'm
not fond of…
A View for a Change
Once upon a time, Russell Beattie started complaining about JSPs. And
in my view, he is completely right, they are ugly and awful and there is
little MVC about it. I personally don't think that we should be
programming web pages, and yet, that is what we do with JSPs.
Dave Johnson attempted to defend JSPs, but his best defense is that
JSP is "an accepted Java standard" and everybody knows it. Since most other
web template languages are just as bad at allowing (and often insisting on)
code in the web pages, he's right. I guess I could prefer using Java as a
script language instead of learning a new one, but JSPs amount to three
separate languages rolled into one page… and this doesn't take into
consideration HTML, Javascript, CSS, etc.
Granted, many of our JSP pages don't include lots of smatterings of `<% …
%>` code, but wouldn't it be nice if the beans instantiated with
<jsp:useBean>
could be access from the EL?
But really I want my pages to be easily designed by my graphics designer
using his favorite web editor of choice. And once they have been integrated
with the web app, I want the graphic designer to be able to re-edit them.
Granted, many web editor programs have plugins that can handle JSPs, but
the result is still a mess. I've mentioned all of this before, but
personally, I don't want my designer to worrying about looping constructs.
No, the JSTL doesn't help as it is just syntactic sugar. A programming
statement with angle brackets around it is still a programming statement.
If I could limit things and just use the <c:forEach>
and
<logic:notEmpty>
/ <logic:present>
, I might be happy.
However, I'm thinking of the possibility of ripping out JSPs from Struts
and using a better template engine, like StringTemplate or
XMLC… even Freemarker is a better choice. And that is my main
problem with Struts… It is nigh impossible to change the template engine
given the current Struts architecture.
But what about <html:errors>
?
Are you kidding me? What advantage does it give you that a normal template
engine doesn't? Formatting this "tag" requires you to add silly HTML-light
code into your properties file, like errors.header=<font color="red">
Ick. I think I'd rather have all of the code right there, as in the
following StringTemplate code example:
$if(errors)$
<div class="errormsg"><b>Error</b> $errors$</div>
$endif$
What what about Internationalization?
You have two choices, you either code each web page in a different locale
and have the controller choose which to use, or your use resource bundles.
The fact that Struts gives you access to a resource bundle doesn't mean it
isn't possible in any other template engine. They are just data messages
than can be accessed like anything else.
It Hurts to Type
—
In the typical Struts model, you would create a web page containing a form
and then create a matching ActionForm. Every variable in your form would
have an equivalent variable in the ActionForm class, plus a setter and
getter for each. All of that work just to syntactically validate the
fields. And what is more, is this class is too application specific (even
form-specific) to be reused.
It seems to me that you could grab the request parameters into a hash
(isn't this what a DynaBean really is?), validate the data, and create a
component that did the error buffering and error notification. Granted this
validation wouldn't be reused any more often, but at least it is a lot less
typing.
It is nice that this problem has been solved with DynaForms. And if you use
this syntax validator stuff from the Validator plugin, you can get rid of
the file altogether. Of course, then you have to deal with even more
xml-configuration-file-proliferation, but that is another problem.
Note: When I mentioned this to someone, they felt like the biggest
advantage of using JSPs and FormBeans is the automatic type conversion that
can happened. All parameter data on the web is a string, but if you declare
a variable to be an int or long, it will get converted for you.
But this really isn't a good idea. Think about, let's suppose you have a
field that can be blank or have a number, and the user enters "34t" …
because there is a "t" in what they type, the conversion utilities set your
variable to "0" … which is a perfectly valid number from your standpoint,
but hardly what the user had in mind.
Model Beans
Creating JavaBeans for your model isn't Struts' idea (or its fault either).
For a long time, we've had this notion that each table in our database
should be interacted through an object, and I have mentioned [my feelings
on this subject]6 before.
Sometimes this is an appropriate model, but often it is a complete waste of
effort at best and a performance bottleneck at worst. But the energy
currently being worked into object-to-relational-database tools like
Hibernate, JDO, Torque and many others attest to our love of
objects even when dealing directly with a database may be better and more
efficient.
New Conclusion
Ok, so after ragging on Struts for its problems, I interviewed with a
company looking for a "JSP Programmer". After demonstrating the initial
pages of their prototype, I asked them was framework they were using.
"We're using JSPs," they said.
And they were. JSP, Model 1.
They had a JSP file with a few hundred lines of Java code and then 40 lines
of HTML interspersed with it. Holy hell, it is hard to bitch about Struts
when you think about what life would be like without it.
Update
Dave Johnson (on Blogging Roller) started thinking
about continuations between web pages and thought if would be a grand
idea to take the control flow module from Cocoon and add it to
Struts (see this overview).
After a brief prototype, he announced that Don Brown took over the project
and made it part of the Struts Applications project (see
StrutsFlow).
The concept of web-based continuations is something akin to procedurally
ask for a value, ask for another value, etc. Something like this:
sendPage("page1.blah");
var user = request.get("user");
sendPage("page2.blah");
var address = request.get("address");
// …
sendPage("pagen.blah");</pre>
In this case, it maintains the fact that we have a series of pages being
sent to the user and data from each of these pages are returned
procedurally. Makes doing those bloody wizards a bit easier (see
this introduction to the subject using Cocoon).
The fact that he was able to hack this into the Struts source gives me hope
about coming up with a similar hack of replacing JSPs with a better
template engine. Unless someone else wants to do it for me.
Tell others about this article: