CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER

CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER TOOLS 621 for messages as an application init parameter. We used this setting, as well as the nocache init parameter. In Struts 1.1, these settings have been deprecated and moved to a element in the struts-config.xml file. The following setting can be found in metadata/web/ struts-controller.xml: The nocachesetting tells the controller to add HTTP headers to prevent caching of content it s off by default. You can also specify a forwardPattern attribute, such as WEB-INF/pages/$M$P, where the $M variable indicates the module prefix and $P indicates the pathattribute of the selected element, although it isn t used here. The inputForward attribute allows you to use local or global forwards in the inputattribute of an action mapping. This is a very handy and much needed feature. Note More information on optional values and their meanings can be found online at http:// struts.apache.org/userGuide/configuration.html. The application s ResourceBundle is now specified in a element in struts-config.xml. If you re using XDoclet, you can place this in a struts-message-resources.xml file. In the struts-resume application, this file is located in the same location as the rest of the Struts configuration fragments: Since we keep this file (ApplicationResources.properties) directory under WEB-INF/ classes, there is no need to specify a package name. You can also specify alternate resource bundles for the application by adding a second element and specifying a key attribute: This can be useful if, for instance, you re building a product using Struts and you only want to expose a minimal amount of options that customers may change. To use this ResourceBundle with the tag, you only need to specify a bundleattribute that matches the key: Now that you ve seen how to set up modules for an application, let s see how to switch between them. For demonstration purposes, we ve added an upload module to struts-resume for uploading r sum s. This module doesn t demonstrate much more than file upload and module switching. It could be developed into a feature that allows for simple uploading of existing r sum s, but not much more than that. At the time of writing, there are two basic techniques to switching modules. The first involves using a forward (global or local) with a

Note: If you are looking for good and high quality web space to host and run your jsp application check Lunarwebhost jsp web hosting services

CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER

620 CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER TOOLS Since the development of modules is very similar to developing a standard Struts application, we ll show you how to set them up, and we ve actually implemented an upload feature that uses them in the struts-resume application. The setup is rather simple, consisting of the following three steps: 1. Prepare a config file for your module. 2. Inform the controller of the module. 3. Use forwards or actions to switch to your new module. We won t detail the first step here, because this is the same as creating a new Struts application. You could probably use XDoclet to create your configuration files for the different modules, but you would have to coax your Ant webdoclet task to output struts-config.xml to different directories. Of course, the purpose of submodules is to make development and configuration easier, and XDoclet already does this for you! The second step involves adding a new init parameter to the ActionServlet s definition in the application s deployment descriptor, web.xml. In the struts-resume application, this configuration is located at metadata/web/servlets.xml: action org.apache.struts.action.ActionServlet config /WEB-INF/struts-config.xml config/upload /WEB-INF/struts-upload.xml debug 2 detail 2 2 This configuration indicates that there are two modules in this application the default module, which has no forward slash (/) in its name, and the second, our upload feature. The configuration files for both modules are located in the WEB-INF directory. The recommended standard for naming module configuration files is struts-module.xml. While you re looking at the ActionServlet s configuration, we want to point out a few changes between 1.0 and 1.1/1.2. In 1.0, it was common practice to specify the ResourceBundle

Note: If you are looking for good and high quality web space to host and run your jsp application check Lunarwebhost jsp web hosting services

CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER

CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER TOOLS 619 that it s easier to do our job with this knowledge. If editing XML files by hand, we recommend XMLSpy (http://www.xmlspy.com). This is a great tool for any XML-related development because it validates your XML against a DTD or XML Schema and also performs auto-completion as you type. Another reason to learn the DTDs or Xml Schema is because tools like XDoclet assemble the struts-config.xmlfile from a number of XML fragments, and most IDE tools only support editing fully assembled struts-config.xml files. There are also applications that have been created simply to provide a development environment for Struts s application development. Let s take a look at a couple of these now. Struts Console Struts Console (found at http://www.jamesholmes.com/struts/) is a free application for managing Struts-based applications. Struts Console is a visual editor for JSP Tag Library, Struts, Tiles, and Validator configuration files. It can be used as a stand-alone Swing application or as a plug-in for your favorite IDE. Supported IDEs are JBuilder (v4.0+), Eclipse (v1.0+), IBM WebSphere Appl. Dev. (v4.0.3+), IDEA (v3.0, build 668+), NetBeans (v3.2), Sun ONE/Forte (v3.0+), and JDeveloper (v9i+). It has support for managing all your Struts-related XML files, such as struts-config.xml, tiles-config.xml, and validation.xml. When using this tool, as with many others, you ll lose any formatting you ve applied to the document. However, it does allow formatting within the tool to pretty up your XML. It also has a wizard for converting JSP and HTML pages into Struts JSP pages a very handy feature if you re converting an existing application to Struts. Easy Struts The Easy Struts project (see http://easystruts.sourceforge.net/) provides a set of tools for Struts development, including a struts-config.xmleditor, XSLT generation, tooltips from the Struts DTD, support for modules, and an input helper. Easy Struts is only available as an IDE plug-in; no stand-alone application is available. Supported IDEs are Eclipse (v2.0+) and JBuilder (v5.0+). Using Modules in Team Development Environments Have you ever worked on a project where many developers were working on the same codebase? Many development teams work in this type of environment, while others allocate development roles to single individuals. Let s imagine two types of teams; the first has fifteen developers and the second has three individuals. We ll pretend that both teams are developing similar applications that use Struts and EJBs for handling credit card payments for a large bank. The large team will probably divide the work among tiers, where five people work on each tier EJBs, ActionServlets, and business layer, and the web tier comprising JSP pages or Velocity templates. The second (smaller) team will simply assign one person to each tier. In a team environment where many people are configuring and manipulating deployment descriptors, it can be difficult to keep your web.xml and struts-config.xml in sync. The simplest solution we ve found is to use XDoclet to generate these configuration files, but there is another option modules. When initially developed by the Struts development team, they were called subapplications, which is a more descriptive name. Modules allow you to separate different areas of an application out into different modules. Modules are a core feature of Struts 1.1 and can be very helpful for large projects as well as for creating pluggable features.

Note: If you are looking for good and high quality web space to host and run your jsp application check Lunarwebhost jsp web hosting services

616 CHAPTER 15 USING STRUTS, XDOCLET, AND

618 CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER TOOLS Figure 15-14. Using a Tiles controller, the application can track the number of sessions and display that number in the header. You can see that the Tiles controller can be a very valuable asset in your Struts toolbox. You can reduce the amount of code needed in your actions and move specific logic to specific tiles. You might even eliminate the need to chain actions together, using multiple tiles and controller combinations instead. You re encouraged to consider using controllers because they can greatly help organize your code and view logic. By using controllers, actions can focus on page flow rather than preparing views. If you re developing a very small and simple application, Tiles might not be necessary. The difficult part of Tiles is finding a good example to operate from and extend. We hope that these examples, in combination with the struts-resume application, will make your Struts development journey easier. You should be able to use the basicLayout.jsp and tiles-config.xml files to get up and running. If you already know Struts and aren t using Tiles, you owe it to yourself (and your deadlines) to try it out. Using IDEs and Struts Development Environments We used to use Macromedia s HomeSite and vi for all our Java editing, because we hated the bloat and RAM wastage of an IDE. Furthermore, IDEs always seemed to complicate things more than they helped. With the maturity of tools like IDEA and Eclipse, using an IDE is fun again and worth our time (a gig of RAM doesn t hurt either). We ve never felt the need to use an IDE to help us configure our struts-config.xml or web.xml file. However, this was probably because these tools didn t exist when we first started working with Struts and web application. Now we re glad we learned the DTDs and we feel

Note: If you are looking for good and high quality web space to host and run your jsp application check Lunarwebhost jsp web hosting services

616 CHAPTER 15 USING STRUTS, XDOCLET, AND

CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER TOOLS 617 The UserCounterController is simply grabbing an attribute out of the application scope and putting it into the request scope. However, you could easily add more complex logic in this method. In this example, you re storing the attribute in the request attribute for simplicity, but it could also be stored in the ComponentContext using the following code: tilesContext.putAttribute(UserCounterListener.COUNT_KEY, userCounter); This would ensure that the attribute was only available for this tile. To configure struts-resume to use this controller, we edited tiles-config.xml file (in web/WEB-INF). We decided we wanted to display this Current Users counter in the header of the page and since we only defined the header in the “baseLayout” definition, this was an easy change. Before the change, the header tile was simply pointing to the header.jsp file: To make the header tile controller-enabled, we created a new definition for it and pointed to it from the baseLayout definition: This means that for each page that the “.header.userCount” tile appears on, UserCounterController.perform() will be called. To display the counter in the header.jsp, we then added the following JSP code: < %-- Check to ensure "userCounter" is in request, if not, don't display --%>

:

To test it, we logged in to the struts-resume application with two different browsers, which created two different sessions. After the sessions were created, the User Counter text in the header (see Figure 15-14) shows that there are currently two users active in the application. We realize this may not be a precise count, but it s about as accurate as it gets with web applications.

Note: If you are looking for good and high quality web space to host and run your jsp application check Lunarwebhost jsp web hosting services

616 CHAPTER 15 USING STRUTS, XDOCLET, AND

616 CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER TOOLS Tiles Controllers Tiles controllers can be very helpful in improving the architecture of your Tiles-enabled application. They haven t received much press in current publications, but can be a very useful feature. At its core, a Tiles controller is designed to prepare data for presentation on a tile. You might think of it as a mini-action. However, these controllers aren t designed to determine application flow; that s the responsibility of the ActionServlet. If you re developing a portal site or you have tiles that require their own custom data, you should definitely considering using one. Of course, it will be easier to understand if we give you an example. Therefore, we ve created a feature for struts-resumethat counts the current number of active sessions and displays it as Current Users. We did this by first creating a UserCounterListenerthat implements ServletContextListener and HttpSessionListener. This listener increments an applicationscoped variable when new sessions are created and decrements from the same variable when sessions are destroyed. This source file is located in struts-resumeat src/web/org/appfuse/ webapp/listener. We ve used XDoclet s @web:listener tag to create a entry for this class in web.xml. To implement a Tiles controller, we created a UserCounterController class that implements the Controllerinterface and its method: public final class UserCounterController implements Controller { /** * This method illustrates a simple example of using a Tiles Controller * to get a “current users” counter for this application. * * @param tileContext Current tile context * @param request Current request * @param response Current response * @param servletContext Current Servlet Context */ public void perform(ComponentContext tilesContext, HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) throws ServletException, IOException { // Get the number of current users from the application’s context String userCounter = (String) servletContext.getAttribute(UserCounterListener.COUNT_KEY); // Add this number to the request for display request.setAttribute(UserCounterListener.COUNT_KEY, userCounter); } } You can see that the perform() method s signature is similar to the Actionclass s signature except there s no ActionMapping or ActionForm. The ComponentContext is a scope similar to that of a request or session; however, it s specific to Tiles and is used to store its configuration information.

Note: If you are looking for good and high quality web space to host and run your jsp application check Lunarwebhost jsp web hosting services

CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER

CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER TOOLS 615 In tiles-config.xml, the “.resumeList” definition is a simple definition that defines a title, header, and content page. In struts-resume, the BaseAction class extends LookupDispatchAction, and Tiles definitions are used extensively for assembling pages. The logic flow from a JSP s URL to an action s method to a Tiles definition can be somewhat confusing, especially when you bring XDoclet into the mix to define the action s mapping and local forwards. Figure 15-13 illustrates the logical flow of it all. MainMenu (JSP) The link is associated with the global-forward , which in turn is associated with the path Therefore, flow goes through to path View My Resumes viewResumes /viewResumes.do?action=search. ActionServlet(*.do) */viewResumes.do. ResumeAction (Action) Xdoclet tags in JavaDoc of define a parameter named . The path defined earlier specified that , so flow passes to the method. ResumeAction.java action action=search search() search() Method Method contains the line ; This list forward is defined using Xdoclet: * * * return mapping.findForward( list ) @struts.action-forward name= list path= .resumeList .resumeList tiles-config.xml Definition from Figure 15-13. The logical flow of control from JSP to Tiles In the previous diagram, the ResumeAction class extends LookupDispatchAction. Basically, it allows you to use a parameter (action) to specify which method to call in your Action class. The figure shows the XDoclet tags used to create the ResumeAction s mapping in the Struts configuration file as well its local forward. All of these tags are written in the class s header Javadoc comments.

Note: If you are looking for good and high quality web space to host and run your jsp application check Lunarwebhost jsp web hosting services

CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER

614 CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER TOOLS and instructions on how to implement it are documented at http://www.alistapart.com/ stories/alternate/. Basically, it uses JavaScript and cookies to disable or enable your preferred stylesheets. We ve used it on several projects and have found it very useful. After you ve set up the template and baseLayout definition to render multiple stylesheets, you can override the list in a child definition. One thing to note is doesn t allow extension, so you have to replace the entire thing. The means that if all you want to do is add an additional stylesheet, you also have to include the original (default.css) stylesheet. In the mainMenu definition, you re using the Struts Menu (http://www.sourceforge.net/projects/ struts-menu) as your menuing system. This menu requires an additional stylesheet file as well as an additional JavaScript file. Therefore, you should replace the original lists with new ones: Pretty slick huh? We ve used this technique for the last year and it s worked great. Tiles, XDoclet, and Forwards Using Tiles to assemble and define your pages can be quite handy, but how do you call these definitions? The easiest way to reference your Tiles definitions is using an ActionForward. When you add the Tiles plug-in to your Struts configuration file, a smart Tiles-aware processor is used to execute requests. This processor, named TilesRequestProcessor, subclasses the Struts default RequestProcessor to intercept calls to includes and forwards to see if the specified URI (path) is a definition name. To configure Tiles definition forwarding in your application, all you need to do is match up the path attribute of a with the nameattribute of a definition. For example, in struts-resume, the ResumeAction s search()method returns an ActionForward to a local named list: return mapping.findForward(“list”); This forward is defined in struts-config.xml for the ResumeAction class as follows:

Note: If you are looking for good and high quality web space to host and run your jsp application check Lunarwebhost jsp web hosting services

CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER

CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER TOOLS 613 definitions file, so this was a simple solution. If you re using JSP 2.1, you can replace the with ${variable}. You can also replace the tag for the stylesheet with the more modern method of importing stylesheets, using @import. Using this syntax, the stylesheet import would look as follows:

This technique can be used to decrease the amount of HTML written as well as to disable stylesheets for older browsers (that is, Netscape 4.x). This may sound foolish, but why would you want to disable stylesheets for older browsers? The reason is simple. If your site is developed using CSS and

elements for layout, the chances are that viewing your site without stylesheets is still readable, but it s just plain text, in black and white, with no fancy layout. This allows older browsers to still see your content, and you don t have to worry about making your CSS compatible with old browsers. Of course, this luxury is purely dependent on your customers. Our advice is to drop support for older browsers we guarantee that that alone will speed up your productivity. If you re willing to use a standards-compliant server (Java EE), why not expect a standards-compliant client? Surely most users have upgraded to newer browsers by now. BROWSERS AN ALTERNATE VIEW At least one author of this book, however, disagrees with the advice to arbitrarily drop support for older browsers. As of July 2005, 68% of web users were using Internet Explorer 6 (http://www.w3schools.com/ browsers/browsers_stats.asp). But looked at from another point of view, 32% of your potential users are using some browser other than Internet Explorer 6. And when Internet Explorer 7 is released, you can expect that many people will stay with version 6 for many months before upgrading. In addition to using older browsers, a great number of the users of your website may be using dial-up connections (41% according to http://www.websiteoptimization.com/bw/0506/). As W3Schools says on their website: Global averages may not always be relevant to your website. Different sites attract different audiences. Some websites attract professional developers using professional hardware, other sites attract hobbyists using older low spec computers. Part of your application design should be a consideration of the characteristics of the users of your site. If you determine that enough of them will be using bleeding edge technology, then your design decisions will be different from if you decide that many of them are older users with antiquated computers connecting through 56K dial-up modems. In the struts-resume application, we re using the syntax so we can use a stylesheet switcher in the future. Paul Sowden developed the stylesheet switcher we ve implemented,

Note: If you are looking for good and high quality web space to host and run your jsp application check Lunarwebhost jsp web hosting services

610 CHAPTER 15 USING STRUTS, XDOCLET, AND

612 CHAPTER 15 USING STRUTS, XDOCLET, AND OTHER TOOLS ApplicationResources.properties file is an easier way to internationalize your application, because then all language changes are available in one file. Earlier we mentioned that CSS stylesheets can be used to greatly improve your layout flexibility. We ve worked on many projects where we used different stylesheets for different pages or even for different users. There are two approaches that we ve used to switch stylesheets, the first being on a page basis, and the second for users. The first uses Tiles definitions to set the stylesheet for any given page. While you re at it, you might as well add this same feature for including JavaScript files. First of all, you can add the files you want to include in your baseLayout definition: Then in the baseLayout.jsp file you can use Tiles tags and the JSTL to get these attributes and render them as follows: < %-- Get JavaScript List --%> < %-- Get List of Stylesheets --%> ” /> We had to add the scriptlet < %=request.getContextPath()%> since the addvalue inside a putList only renders the literal value. We didn t want to hard-code the contextPath in the

Note: If you are looking for good and high quality web space to host and run your jsp application check Lunarwebhost jsp web hosting services