Download - Struts best practices
![Page 1: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/1.jpg)
1
Struts Best Practices
![Page 3: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/3.jpg)
3
Disclaimer & Acknowledgments● Even though Sang Shin is a full-time employees of Sun
Microsystems, the contents here are created as their own personal endeavor and thus does not reflect any official stance of Sun Microsystems.
● Sun Microsystems is not responsible for any inaccuracies in the contents.
● Acknowledgments: – Some slides are created from "Jakarta Struts: Seven lessons from trenches"
article written by Chuck Cavaness– Some slides are created from "Struts Best Practices” article written by Brijesh
Deb
![Page 4: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/4.jpg)
4
Revision History● July 2nd, 2005: version 1: created by Sang Shin ● Things to do
![Page 5: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/5.jpg)
5
Extend Only When Needed● Make sure extending the framework is the
last resort– Add maintenance cost
![Page 6: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/6.jpg)
6
Use Declarative Exception Handling● Struts framework includes a class called
ExceptionHandler that by default is responsible for processing any exceptions that occur during action execution
● The default Struts exception handler class creates an ActionError object and stores it in the appropriate scope object
![Page 7: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/7.jpg)
7
Use Application Modules● In a multi-developer environment, a single
struts-config.xml is a bottleneck● Allows parallel development● Necessary for large scale applications
![Page 8: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/8.jpg)
8
Protect JSP Pages● Protect your JSP pages from unauthorized
access or viewing● Front your JSP pages with Struts Actions● Two options– Store your pages in a directory that is below the
Web application's WEB-INF directory– Use security feature of Web application
![Page 9: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/9.jpg)
9
Protect JSP's Behind WEB-INF● Suppose we had an Action mapping in
Struts configuration file for a logoff action, the path must include /WEB-INF<action path="/logoff" type="org.apache.struts.webapp.example.LogoffAction"> <forward name="success" path="/WEB-INF/jsp/index.jsp"/></action>
![Page 10: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/10.jpg)
10
Protect JSP's using Security Features of Web application● Nobody can access JSP pages directly
<web-app> ... <security-constraint> <web-resource-collection> <web-resource-name>no_access</web-resource-name> <url-pattern>*.jsp</url-pattern> </web-resource-collection> <auth-constraint/> </security-constraint> ...</web-app>
![Page 11: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/11.jpg)
11
Use the Prebuilt Actions● Struts framework comes with several prebuilt
Action classes that can save a tremendous amount of development time and reduce the number of files to manage– org.apache.struts.actions.ForwardAction– org.apache.struts.actions.DispatchAction
![Page 12: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/12.jpg)
12
Use DynaActionForm's● Allow you to configure an ActionForm
completely through the Struts configuration file; there's no longer a need to create actual concrete ActionForm classes in your application
● Helps to facilitate automatic presentation-layer validation
![Page 13: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/13.jpg)
13
Use Struts Tools● Adalon (Commercial)● Easy Struts (Open source)● Struts Console (Free)● JForms (Commercial)● Camino (Commercial)● Struts Builder (Open source)● StrutsGUI (Free)
![Page 14: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/14.jpg)
14
Categorize Errors ● To display the error messages of different
categories, define these categories such as FATAL, ERROR, WARNING, or INFO, in an interface
● In the Action or form-bean class, you can then use the following– errors.add("fatal", new ActionError("....")); or– errors.add("error", new ActionError("....")); or– errors.add("warning", new ActionError("....")); or– errors.add("information", new ActionError("...."));– saveErrors(request,errors);
![Page 15: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/15.jpg)
15
Categorize Errors● To display them according to those categories, use
the following code:<logic:messagePresent property="error"><html:messages property="error" id="errMsg" > <bean:write name="errMsg"/></html:messages></logic:messagePresent >
Or use:
<logic:messagePresent property="error"><html:messages property="error" id="errMsg" > showError('<bean:write name="errMsg"/>'); // JavaScript
Function</html:messages></logic:messagePresent >
![Page 16: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/16.jpg)
16
Create Common Action Class● When common operations need to be
included in all the actions, create common Action class– An example of such a requirement in an Online
Shopping application would be to perform user authorization before processing all user requests
● Make all other Action classes extend the common action class to centralize the handling of common operations and reduce code redundancy
![Page 17: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/17.jpg)
17
Create Common Action Class Public abstract class BaseApplicationAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { try { //Call all common methods performAuthorization(); return executeSpecificTask(mapping,form,request,response); } catch(Exception ex){//exception} } // Authorization is an operation common through all the application actions private void performAuthorization() { //Code for user authorization } //Provide implementation of this method in sub-classes public abstract ActionForward executeSpecificTask(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception }
![Page 18: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/18.jpg)
18
Handle Duplicate Form Submission● The problem of duplicate form submission
arises when a user clicks the Submit button more than once before the response is sent back or when a client accesses a view by returning to a previously bookmarked page.
● Handle it by using the saveToken() and isTokenValid() methods of Action class– saveToken() method creates a token (a unique string)
and saves that in the user's current session– isTokenValid() checks if the token stored in the user's
current session is the same as that was passed as the request parameter.
![Page 19: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/19.jpg)
19
Handle Duplicate Form Submissionpublic class PurchaseOrderAction extends DispatchAction { public ActionForward load(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
try { //save the token saveToken(request) // rest of the code for loading the form } catch(Exception ex){//exception} }
![Page 20: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/20.jpg)
20
Handle Duplicate Form Submission
public ActionForward submitOrder(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
try { // check the token. Proceed only if token is valid if (isTokenValid(request,true)) { //implement order submit functionality here } else { return mapping.findForward("failure"); } } catch(Exception ex){ }
}}
![Page 21: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/21.jpg)
21
Use Single ActionForm for Similar Forms● For similar forms, use a single ActionForm
that includes all possible fields instead of having several ActionForms
● This is generally applicable to different forms required to implement the same use case
● It leads to easy maintenance, though all the fields will be not be used for all the Actions
![Page 22: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/22.jpg)
22
Use Single ActionForm for Similar Forms● For example, in the Online Shopping
application we can use a single ActionForm (CustomerProfileForm) for different forms related to customer profile management (like DisplayCustomerProfile.jsp, EditCustomerProfile.jsp, etc.)
![Page 23: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/23.jpg)
23
Use intermediate Action class for common operations● When a common operation needs to be
performed for all actions– ex) authorization
● All action classes then extend the intermediate action class
● Centralize the common operato
![Page 24: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/24.jpg)
24
Use global-forwards to Avoid Redundant forwards● Helps to avoid mentioning for all the actions● The Online Shopping application should
display the login page in case of session timeout. Instead of including for all the actions, add a single entry in the struts-config.xml to throw the login.jsp to the user in case of session timeout encountered in any Action, like this:
![Page 25: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/25.jpg)
25
Remove ActionFrom From Session● If ActionForm is set to session scope, it
should be removed from session whenever it's utility is over
● In the sample online shopping application, in case of the multi-screen customer registration, if the RegistrationForm is set to session scope, it should be removed form the session once the user clicks Cancel
![Page 26: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/26.jpg)
26
Use Business Delegate● Action should not implement complex
business functionalities, rather delegate these to the Model
● Use Business Delegate to talk to the Business tier and the Data Tier
![Page 27: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/27.jpg)
27
Avoid instance/static Variable in Action Class● Instance and static variables should not be
used in an Action class to store information related to the state of a particular request. The same instance of an Action class can be shared among multiple simultaneous requests through multi-threading
● Instance/static variable may however be used to share global resources across requests for the same action.
![Page 28: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/28.jpg)
28
Do Not Include Business Logic in ActionForm● ActionForm represents HTML form(s) and it
is used by Struts to transfer data between View and Controller– They should not be treated as part of the Model– Do not include any business functionality in the
reset() or validate() method of ActionForms as this would lead to tight coupling of application business functionality with the presentation tier (implemented through the Struts framework).
![Page 29: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/29.jpg)
29
Use html:messages (instead of html:errors● For displaying error messages to the end
user, use html:messages instead of html:errors
● html:messages allows to get the markup language out of the resource bundle.
![Page 30: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/30.jpg)
30
Use StrutsTestCase For Unit Testing● Because StrutsTestCase uses the ActionServlet
controller to test the code, you can test not only the implementation of your Action objects, but also the mappings, form beans, and forwards declarations.
● StrutsTestCase provides both container testing and simulated container testing to actually run the Struts ActionServlet, allowing you to test Struts code with or without a running servlet engine.
![Page 31: Struts best practices](https://reader034.vdocuments.us/reader034/viewer/2022052411/5565f51ad8b42a20158b4f92/html5/thumbnails/31.jpg)
31
Passion!