Jakarta Struts

Subproject Name: JakartaStruts

Official Web Page: http://jakarta.apache.org/struts

Metaproject Name: JakartaProject

Sponsor: ApacheSoftwareFoundation

Wiki: http://nagoya.apache.org/wiki/apachewiki.cgi?StrutsProjectPages

Struts is a ModelViewController FrameWork for simplifying WebBasedDevelopment? and a specific subproject of the Jakarta project (http://jakarta.apache.org/).. It brings JavaServerPages and JavaServlet development a bit closer to what WebObjects offers.

(There are other Jakarta frameworks - e.g., Avalon (a "server framework", Jetspeed (a "Web portal" framework), Log4J (a logging framework), Lucene (a search engine framework), Turbine (another Web framework), Velocity (a Web framework and seemingly more).)

Struts includes the following primary areas of functionality:


June 30, 2003: Struts 1.1 released.


I used to bitch about Struts because I didn't like how you had the one master file for your application. I knew (from theory and experience) that it would get very messy to maintain as your app scales beyond a few pages. (This is that "centralized screen flow mappings", BTW).

Then I got a project using Struts, and XDoclet (http://xdoclet.sourceforge.net/). Instantly, the "centralized" screen flow became decentralized, to the developer view of the world. This made a huge difference to the usability of Struts. If you're out there and using Struts, I strongly urge you to check out XDoclet.

Now, if they could only hurry up and get that automatic validation and transformation of data type support that's in the nightly build out to release... -- RobertWatkins


Another experience of struts. We had to get a site up and running that had hundreds of pages of dynamic content (dynamic in this instance doesn't mean much - a few things in the page templates changed based on who you were, certain things you did on the site, etc). The company had a Web designer (pure HTML) already, and some Java developers who'd learned in-house, and as a result had only ever written monolithic servlets (I mean really monolithic, no layers or reuse at all). When I joined I had to propose how the site development should be done.

What I wanted to achieve was that the Web designer retained control of the design, and that we should be able to track changes in the static versions of the site he produced for marketing. I also wanted to enforce view-model separation, to give the developers some better habits. There is actually a good tool for this (xmlc) but I rejected that because Struts structured the MVC side of things better, and using xmlc it wasn't clear we'd be able to reuse other people's custom tags. What I wanted was something to make Struts more like xmlc.

So I wrote it myself. I wrote a JakartaAnt task to support converting an HTML file into a set of JavaServerPages. Its parser looks for elements with 'id' attributes and for each of these I generate a separate JSP, then finally generate a single JSP to tie them together (using the Struts 'template' tags). Config files let me change arbitrarily which files get included in which template. This lets the Java developers write small, custom JSPs for pages where code generation doesn't fulfil our needs (mainly pages which display lists of things). The task rewrites all URLs in the pages to point at where their equivalent JSPs will be, and rewrites all forms to use the Struts form tags. (the rules used in this process are quite complicated, I can explain more if asked but its unnecessary to make the point).

I would like to at some point (when the company allows) release this as open source; I haven't seen anyone else do this with Struts (even though there are a number of other Struts code generators, none of them work this way AFAIK). I can thoroughly recommend it as an approach. To give you some idea of the effect, the current site has 67k lines of html but only 5k lines of custom JSP (which is waaay more than we needed really). All of the HTML is written by the designer using WYSIWIG tools. As well as the effort saved in this version of the site, we have just reskinned the site for a different customer, in about a week. The Struts code, for the most part, has not changed at all, since we had clean model-view separation; the Java developers only had to write a few new custom JSPs. -- BrianEwins


In 2Q02 I evaluated Struts for potential inclusion in my company's product, and rejected it in favor of an internally-developed JSP model 2 architecture framework. Struts has a number of really great things going for it, including increasing momentum and nice internationalization hooks.

But it presents a SystemOfNames and AllocationOfResponsibility that departs decidedly from the ModelModelViewController paradigm promulgated by the Smalltalk community, and that increases reliance on the nebulous notion of "beans". Stateless and fine-grained, Actions are less useful in the application layer of a FourLayerArchitecture than stateful, long-lived, large-grained ApplicationModels underlying one or more Views. By encapsulating the state of a user's interaction (selections, edits, etc.) in instance variables, surviving between user interface events, and implementing behavior for responding to all events coming from its supported views, an ApplicationModel provides good factoring (high internal cohesion, low external coupling) and well-encapsulated context for deciding how to respond to a user interface event. Reuse of behavior is easily achieved by inheritance between ApplicationModel classes and delegation between ApplicationModel instances.

Struts also presents a burden and source of coupling with its external configuration. JSPs and ActionMappings? are coupled by a URL scheme you're burdened with inventing when, by contrast, a constant URL with two standard request parameters (identifying a view and an HTML element) suffices to uniquely identify a user interface event. EnterpriseApplications with hundreds of use cases could require maintenance of hundreds of ActionMappings? in the external configuration file (not to mention hundreds of Action classes) unless abstraction and parameterization of Actions is expected under the intentions of Struts' designers. Using larger-grained classes (and event dispatching from standard URL parameters instead of custom URL path segments) results in much less source to maintain in the application layer.

Perhaps in future versions Struts will complement its other valuable characteristics with a less expensive event dispatching approach, and a SystemOfNames truer to ModelModelViewController concepts proven over the last two decades in the Smalltalk community. Until then it may not be the SimplestThingThatCouldPossiblyWork.

-- RandyStafford

Firstly, let me challenge your assumptions:

Here's a few points about how I view Struts (and why I like it): This leads to the tradeoff of requiring validation in two places, but this isn't unique to Struts (it's the same tradeoff when deciding to use JavaScript-based validation, for example). It's a matter of the amount of strain you want to place on any particular portion of your system. In a distributed system, where your business model is implemented remotely (through web services or EJBs, or whatnot), the Struts model might make some sense - validate in the Web tier and avoid the network round-trip. Similarly, many object models will validate business rules before hitting the RDBMS thus potentially also avoiding a round-trip. Some would say all of this is b.s. and all validation should just be in the database anyway, so buy a faster interconnect between your Web tier and your database. :-) YMMV.

I'm with all that. "Input buffers" or "holding areas" to buffer/hold values and objects during validation are important - and SplitValidation? is real and appropriate. I like to do syntactic validation as close to the glass as possible (in JavaScript) and semantic validation in the domain model. Incidentally that was one of the nice things about GemStone - you didn't have to explicitly create and merge an "editing copy" of a domain object graph to apply edits and invoke semantic validation (as you have to do with TopLink). Instead GemStone implicitly created the editing copy for you at the disk page level upon first write to an object, and you could abort the edits by simply throwing a validation exception out of your EJB to rollback the JTS transaction. It was neat.

  Setup Action(s) -> Render JSP -> UI Think Time -> Process Action(s)
Struts fits a vary narrow role: screen flow, UI data binding, and Web-tier validation. It isn't over achieving, and fits that role well, IMHO. -- StuCharlton


ApplicationModel wasn't a "control", i.e. event handler, so much as it was a "binding" or a "mapping" between layers.

I have to disagree. Action buttons on user interfaces were typically bound to ApplicationModel methods that implemented the system's response to presses of those buttons. In other words, ApplicationModels "controlled" interaction and/or "handled events", in addition to their other responsibility of adapting DomainModels to views. -- RandyStafford


See http://jakarta.apache.org/velocity/ymtd/ymtd.html for an interesting discussion comparing JakartaVelocity with JSP. My experience with velocity and turbine is that it is far more productive than struts or plain JSP. Check it out. -- ChanningWalton


See http://www.johngresh.com/doc/researchInterests/ood/collectionSwitch/paper/collectionSwitchPaper.pdf for an interesting discussion of an alternative controller servlet that can be used in web applications that opt out of the Struts framework. The Collection Switch design pattern provides for a controller class that actually scales (i.e. NEVER grows). -- Alex


CategoryFramework


EditText of this page (last edited December 11, 2006) or FindPage with title or text search