husted 2002/12/29 14:15:35 Modified: doc/userGuide building_controller.xml Log: Content change contributed by Tim O'Brien (PR #15167). Revision Changes Path 1.53 +110 -77 jakarta-struts/doc/userGuide/building_controller.xml Index: building_controller.xml =================================================================== RCS file: /home/cvs/jakarta-struts/doc/userGuide/building_controller.xml,v retrieving revision 1.52 retrieving revision 1.53 diff -u -r1.52 -r1.53 --- building_controller.xml 29 Dec 2002 18:06:59 -0000 1.52 +++ building_controller.xml 29 Dec 2002 22:15:35 -0000 1.53 @@ -16,6 +16,7 @@ <author>Eddie Bush</author> <author>Yann Cebron</author> <author>David Graham</author> + <author>Tim O'Brien</author> </properties> <body> @@ -677,7 +678,7 @@ ActionForm form, ServletRequest request, ServletResponse response) -throw Exception; +throws Exception; public ActionForward execute(ActionMapping mapping, ActionForm form, @@ -687,14 +688,19 @@ </code></pre> <p> - Most projects would only use the "HttpServletRequest" version. + Since the majority of Struts projects are focused on building web + applications, most projects will only use the "HttpServletRequest" + version. + A non-HTTP execute() method has been provided for applications that are + not specifically geared towards the HTTP protocol. </p> <p> The goal of an <code>Action</code> class is to process a request, via its <code>execute</code> method, and return an <code>ActionForward</code> - object that identifies where control should be forwarded (e.g. a JSP) to - provide the appropriate response. + object that identifies where control should be forwarded (e.g. a JSP, + Tile definition, Velocity template, or another Action) to provide the + appropriate response. In the <i>MVC/Model 2</i> design pattern, a typical <code>Action</code> class will often implement logic like the following in its <code>execute</code> method: @@ -749,78 +755,6 @@ </ul> <p> - The design issues to remember when coding <code>Action</code> classes - include the following: - </p> - - <ul> - - <li> - The controller servlet creates only one instance of your - <code>Action</code> class, and uses it for all requests. - Thus, you need to code your <code>Action</code> class so that it - operates correctly in a multi-threaded environment, just as you must - code a servlet's <code>service</code> method safely. - </li> - - <li> - The most important principle that aids in thread-safe coding is to - use only local variables, not instance variables, in your - <code>Action</code> class. - Local variables are created on a stack that is assigned (by your JVM) - to each request thread, so there is no need to worry about sharing - them. - </li> - - <li> - The beans that represent the Model of your system may throw exceptions - due to problems accessing databases or other resources. - You should trap all such exceptions in the logic of your - <code>execute</code> method, and record them in the application's log - (along with the corresponding stack trace) by calling:<br /> - <code>servlet.log("Error message text", exception);</code> - </li> - - <li> - As a general rule, allocating scarce resources and keeping them across - requests from the same user (in the user's session) can cause - scalability problems. - You should strive to release such resources (such as database - connections) prior to forwarding control to the appropriate View - component -- even if a bean method you have called throws an - exception. - </li> - - </ul> - - <p> - In addition, you will want to guard against <code>Action</code> classes - that are too large. - The easiest way for this to happen is to embed your functional logic in - the <code>Action</code> class itself, rather than coding it in separate - business logic beans. - Besides making the <code>Action</code> class itself hard to understand and - maintain, this approach also makes it harder to re-use the business logic - code, because it is embedded inside a component (the <code>Action</code> - class) that is tied to being executed in a web application environment. - </p> - - <p> - An <code>Action</code> can be factored into several local methods, so - long as all properties needed are passed in the method signatures. - The JVM handles such properties using the stack, and so they are - thread-safe. - </p> - - <p> - The example application included with Struts stretches this design - principle somewhat, because the business logic itself is embedded in the - <code>Action</code> classes. This should be considered something of a - bug in the design of the sample application, rather than an intrinsic - feature of the Struts architecture, or an approach to be emulated. - </p> - - <p> In Struts 1.0, Actions called a <code>perform</code> method instead of the now-preferred <code>execute</code> method. These methods use the same parameters and differ only in which exceptions @@ -839,9 +773,108 @@ and wraps any <code>Exception</code> thrown as a <code>ServletException</code>. </p> + + </section> + + <section name="4.4.1 Action Class Design Guidelines" href="action_design_guide"> + + <p> + Remember the following design guidelines when coding <code>Action</code> + classes: + </p> + + <ul> -</section> + <li> + <b>Write code for a multi-threaded environment</b> - + The controller servlet creates <b>only one instance of your + <code>Action</code> class</b>, and uses this one instance to service + all requests. + Thus, you need to write thread-safe <code>Action</code> classes. + Follow the same guidelines you would use to write thread-safe + Servlets. + Here are two general guidelines that will help you write scalable, + thread-safe Action classes: + + <ul> + + <li> + <b>Only Use Local Variables</b> - The most important principle + that aids in thread-safe coding is to use only local variables, + <b>not instance variables</b>, in your <code>Action</code> class. + Local variables are created on a stack that is assigned (by your + JVM) to each request thread, so there is no need to worry about + sharing them. + An <code>Action</code> can be factored into several local methods, + so long as all variables needed are passed as method parameters. + This assures thread safety, as the JVM handles such variables + internally using the call stack which is associated with a single + Thread. + </li> + + <li> + <b>Conserve Resources</b> - As a general rule, allocating scarce + resources and keeping them across requests from the same user + (in the user's session) can cause scalability problems. + For example, if your application uses JDBC and you allocate a + separate JDBC connection for every user, you are probably going + to run in some scalability issues when your site suddenly shows + up on Slashdot. + You should strive to use pools and release resources (such as + database connections) prior to forwarding control to the + appropriate View component -- even if a bean method you have + called throws an exception. + </li> + + </ul> + + </li> + <li> + <b>Don't throw it, catch it!</b> - Ever used a commercial website only to + have a stack trace or exception thrown in your face after you've already + typed in your credit card number and clicked the purchase button? + Let's just say it doesn't inspire confidence. + Now is your chance to deal with these application errors - in the + <code>Action</code> class. + If your application specific code throws expections you should catch these + exceptions in your Action class, log them in your application's log + (<code>servlet.log("Error message", exception)</code>) and return the + appropriate ActionForward. + </li> + + </ul> + + <p> + It is wise to avoid creating lengthy and complex Action classes. + If you start to embed too much logic in the <code>Action</code> class + itself, you will begin to find the <code>Action</code> class hard to + understand, maintain, and impossible to reuse. + Rather than creating overly complex Action classes, it is generally a + good practice to move most of the persistence, and "business logic" to a + separate application layer. + When an Action class becomes lengthy and procedural, it may be a good time + to refactor your application architecture and move some of this logic + to another conceptual layer; + otherwise, you may be left with an inflexible application which can only + be accessed in a web-application environment. + Struts should be viewed as simply the <b>foundation</b> for implementing + MVC in your applications. + Struts provides you with a useful control layer, but it is not a fully + featured platform for building MVC applications, soup to nuts. + </p> + + <p> + The example application included with Struts stretches this design + principle somewhat, because the business logic itself is embedded in the + <code>Action</code> classes. + This should be considered something of a bug in the design of the example, + rather than an intrinsic feature of the Struts architecture, or an + approach to be emulated. + </p> + +</section> + <section name="4.5 Exception Handler" href="exception_handler"> <p>
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>