19,35 €
Struts 2.1 is a modern, extensible, agile web application framework suitable for both small- and large-scale web applications.
The book begins with a comprehensive look at Struts 2.1 basics, interspersed with detours into more advanced development topics. You'll learn about configuring Struts 2.1 actions, results, and interceptors via both XML and Java annotations. You'll get an introduction to most of the Struts 2.1 custom tags and learn how they can assist in rapid application prototyping and development.
From there you'll make your way into Struts 2.1's strong support for form validation and type conversion, which allows you to treat your form values as domain objects without cluttering your code. A look at Struts 2.1's interceptors is the final piece of the Struts 2.1 puzzle, allowing you to leverage the standard Struts 2 interceptors as well as implement your own custom behavior.
After covering Struts 2.1 you'll journey into the world of JavaScript, a surprisingly capable language, the Document Object Model (DOM), and CSS, and learn how to create clean and concise client-side behavior. You'll leverage that knowledge as you move on to Struts 2 themes and templates, which give you a powerful way to encapsulate site-wide user interface behavior.
The book closes with a look at some tools that make the application development life cycle easier to manage, particularly in a team environment, and more automatic.
This book provides an in-depth introduction to Struts 2 and crash-courses in JavaScript, CSS, Test-Driven Development, agile programming techniques, and tool development, focusing on the delivery of complete, documented, maintainable web applications.
This book takes a clear approach, focusing on one topic per chapter, but interspersing other issues in the mainline text and in chapter detours. Taking a practical approach, it discusses agile web development using Struts 2, with plenty of examples for better understanding.
This book is for Java developers who are interested in developing web applications using Struts. If you need a comprehensive introduction to Struts 2.1, along with the most important aspects of additional web application development technologies, agile programming practices, tool creation, and application life cycle management this book is for you. You don't need to know JavaScript and CSS to use this book as the author will teach you the required basics.
If you are a Struts 1 or WebWork user and wish to go ahead and migrate to Struts 2, this practical guide is also for you.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 483
Veröffentlichungsjahr: 2009
Copyright © 2009 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, Packt Publishing, nor its dealers or distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: June 2009
Production Reference: 2040609
Published by Packt Publishing Ltd. 32 Lincoln Road Olton Birmingham, B27 6PA, UK.
ISBN 978-1-847193-39-1
www.packtpub.com
Cover Image by Vinayak Chittar (<[email protected]>)
Author
Dave Newton
Reviewers
Sandeep Jadav
Dale Newfield
Michael Minella
Sharad Sharma
Acquisition Editor
Viraj Joshi
Development Editor
Ved Prakash Jha
Technical Editor
Gaurav Datar
Copy Editors
Sumathi Sridhar
Leonard D'Silva
Indexer
Monica Ajmera
Editorial Team Leader
Akshara Aware
Project Team Leader
Lata Basantani
Project Coordinator
Abhijeet Deobhakta
Proofreader
Joel T. Johnson
Production Coordinators
Shantanu Zagade
Adline Swetha Jesuthas
Cover Work
Shantanu Zagade
Dave has been programming for as long as he can remember, and probably a bit longer than that. He began by playing a Star Trek game on a library computer, and quickly graduated to educating his grade school teachers about computers and the BASIC language. Receiving a TRS-80 Model 1 was pretty much the end of his social life, and he's never looked back.
A diverse background in both programming languages and problem spaces has provided him with a wide range of experience. Using a diverse set of languages, which includes Pascal, Forth, Fortran, Lisp, Smalltalk, assembly, C/C++, Java, and Ruby, brings an appreciation for many programming paradigms. Working on AI, embedded systems, device drivers, and both desktop and web application programming, has brought him an appreciation for the problems and solutions that each environment offers.
Even after thirty years of typing in his first infinite loop, he's still entertained by the process of programming. He never tires of looking for ways to do less work, and is convinced that he should never have to repeat himself to a computer. He still occasionally writes an infinite loop.
I'd like to thank Packt for providing me an opportunity to share what I hope is some useful information about my favorite Java web application framework, Struts 2, and along the way, throw in some techniques I've found my clients appreciate (and many of them mean I get to do less work, so it's a win-win!)
My parents, of course, deserve far more thanks than I could ever hope to express. From them, I received a robust sense of exploration and curiosity, which are traits that have served me well during my personal and professional career. They, and the rest of my family, have prodded me along by continually asking, "How's the book coming?", which was surprisingly motivating. They have also provided, along with my friends, much needed moral support during recent months.
I'd like to thank my co-workers, who have zero compunction about telling me when I'm completely wrong, and who provide me with a constant stream of ideas about programming, the associated processes, and how to make programming easier and more flexible.
The creators of the frameworks and libraries we use every day deserve more than they usually receive. Putting one's code out there for everyone to see and use is a brave step. They're under-appreciated when everything works, and unfairly punished when it doesn't. I hope this book pays homage to them in some small way, and contributes back to the various communities that have made my programming work easier.
Finally, the open source and Java communities deserve a hearty "Huzzah!" It includes places like the Struts 2 mailing lists, where all types of developers contribute by asking and answering questions, making suggestions, and politely reminding those involved with the framework that our documentation could be better. It also includes JavaRanch, where "No question is too simple", and sometimes the "simplest" questions turn out to be surprisingly interesting. Finally, the Apache Foundation and fellow Struts developers, who have made Struts possible in all its incarnations. All those people who write the code that we use, contribute to discussions, and try to help others out know who they are. I can't possibly begin to list all of them, but thanks.
Sandeep Jadav has been in the IT industry for three years and is currently working as a Software Engineer for an IT firm. Sandeep is an MCA qualified professional and is well-versed with Java technologies. He empowers people around him to work and play better, by helping them resolve complex issues with the simplest and most durable solutions.
In addition to reviewing, Sandeep has a history of using his technical skills for more practical purposes—providing technical leadership to past companies. He has an experience in developing on a large scale, n-tier and Web applications, for business and engineering uses.
Sandeep has a large network of friends and makes frequent contributions to a variety of content areas in many online IT communities.
I would first like to thank Packt Publishing, and the author Dave Newton, for spearheading this edition of Apache Struts 2 Web Application Development, and giving me an opportunity to revisit and improve upon the first efforts.
I am deeply grateful to my family for allowing me to encroach on many months of what should have been my family's quality time.
I extend my deepest appreciation to my friends, for all their support, encouragement, and guidance throughout my work.
I appreciate Packt Publishing for allowing me to gain a very new and delighting experience of reviewing the book.
While reviewing may seem a solitary pursuit, it is actually very much a collaborative effort, and as such, I extend my thanks and appreciation to my author, editor, and the staff at Packt Publishing for their support throughout this project.
Finally, I especially thank Payal for providing great support on each and every step of my life.
Dale Newfield is a computer scientist trained at Carnegie Mellon and the University of Virginia (ABD). Mr. Newfield has designed, built, and maintained a wide variety of systems in many languages. He has vertical knowledge in fields as disparate as graphics, user interfaces, virtual environments, networking, network technology design, network modeling, distributed and disconnected computation, bioinformatics, along with both web and POS systems requiring tight integration of hardware and software. Having built scalable web applications using both Struts1 and Struts2, his input was helpful in keeping this text focused on teaching best practices.
Michael T Minella has been working with, and teaching about, open source software and agile methodologies for over seven years. He holds degrees from Northern Illinois University and DePaul University in Computer Science and E-Commerce Technologies respectively.
Michael lives just outside Chicago, IL, and works at a major financial exchange there. In addition to his day job, Michael currently teaches at DeVry University, has authored a Refcard on JUnit and EasyMock (http://refcardz.dzone.com/refcardz/junit-and-easymock), and maintains the site http://www.michaelminella.com.
Michael would like to thank his wife Erica for her continued support in all the ways he expands his career.
Sharad Sharma is working as a Software Engineer with a reputed MNC. He completed his Bachelors in Technology (B.Tech) from Sikkim Manipal University, Sikkim, and has a passion to learn and teach new technologies. He has successfully completed many projects based on Java/J2EE technology. In spite of having less experience, due to his dedication and hard work, he was able to achieve the top position among all the developers of the organization. This is the first book he has worked upon and wishes to work on many more in future.
I would like to thank my family and friends for the support they have provided me in all the areas.
Struts 2.1 is a modern, extensible, agile web application framework, which is suitable for both small- and large-scale web applications.
The book begins with a comprehensive look at the basics of Struts 2.1, interspersed with detours into more advanced development topics. You'll learn about configuring Struts 2.1 actions, results, and interceptors via both XML and Java annotations. You'll get an introduction to most of the Struts 2.1 custom tags, and also learn how they can assist in rapid application prototyping and development.
From there, you'll make your way into Struts 2.1's strong support for form validation and type conversion, which allows you to treat your form values as domain objects without cluttering your code. A look at Struts 2.1's interceptors is the final piece of the Struts 2.1 puzzle, which allows you to leverage the standard Struts 2 interceptors, as well as implement your own custom behavior.
After covering Struts 2.1, you'll journey into the world of JavaScript (a surprisingly capable language), the Document Object Model (DOM), and CSS, and learn how to create clean and concise client-side behavior. You'll leverage that knowledge as you move on to Struts 2 themes and templates, which give you a powerful way to encapsulate site-wide user interface behavior.
The book closes with a look at some tools that make the application development life cycle easier to manage, particularly in a team environment, and more automatic.
Chapter 1 gives us a bird's-eye view of Struts 2 and examines some useful techniques of lightweight, agile development.
Chapter 2 gives an introduction to Struts 2 application configuration, using both XML and annotations. It also covers the beginning of our sample application, RecipeBox.
Chapter 3 covers some of the functionality provided by Struts 2's ActionSupport class, including I18N, and a first look at form validation. It also covers some basic RecipeBox functionality after gathering some user stories.
Chapter 4 examines several common, standard Struts 2 result types. It also covers how to write our own custom result types.
Chapter 5 gives an in-depth look at the generic Struts 2 custom tags. These include tags for iteration, list generation, conditionals, and internationalization (I18N).
Chapter 6 continues our exploration of Struts 2 custom tags, focusing especially on its form tags.
Chapter 7 examines Struts 2 form validation, including both XML and annotation-driven validation. It also teaches more about how Struts 2 converts our form values into domain objects, and shows how to create our own type converters to handle custom data types.
Chapter 8 finishes our comprehensive introduction to Struts 2, by checking out the included Struts 2 interceptors. It also discusses how to write and configure our own interceptors.
Chapter 9 looks at how to handle errors in Struts 2, as well as discusses error and exception handling in general. It also covers some general Java logging topics, focusing on using Apache Commons Logging and Log4J.
Chapter 10 explores how to best leverage JavaScript and how to keep it modular.
Chapter 11 covers the client-side functionality, which depends on more than JavaScript. By using CSS and the DOM effectively, we can accomplish a lot with a minimal amount of code.
Chapter 12 covers Struts 2 themes and templates. The themes and templates in Struts 2 allow for application-wide functionality on the client side, keeping our JSP pages lightweight and adaptable. Rather than writing boilerplate HTML on our pages, we can separate it into themes and templates.
Chapter 13 takes a look at some of Struts 2's built-in support for Ajax using the Dojo tags. It also covers the Struts 2 REST plug-in that furthers our "convention over configuration" path.
Chapter 14 covers how to apply the TDD concepts to several testing aspects, including unit, functional, and acceptance tests.
Chapter 15 looks at many aspects of documentation, including "self-documenting" code, Javadocs, generators, methodologies, and so on, with a focus on automating as much documentation as possible.
You'll need all the typical Java web application development tools. An IDE is very handy, but it doesn't matter which one you use. Almost any modern application server can be used to run the sample application.
Having an Internet connection while reading is extremely useful. The Struts 2 download includes the documentation wiki, along with the XWork and Struts 2 API Javadocs. However, we may also need to reference the Servlet API, various library APIs, and so on. Having access to the Struts 2 user mailing list can also be very beneficial, as sometimes searching the web for a question is the quickest way to get it answered.
The most important requirements aren't dependent on a particular Java version or specification. Curiosity, willingness to experiment, and patience will never be written up as a JSR, but they're critical qualities in a developer. It's perfectly fine to never learn the ins and outs of a framework. However, by digging into the documentation, and especially the source, we gain a much better understanding of why things happen the way they do. This increases our efficiency, our usefulness, and our value.
This book is for Java developers who are interested in developing web applications using Struts. If you need a comprehensive introduction to Struts 2.1, along with the most important aspects of additional web application development technologies, agile programming practices, tool creation, and application life cycle management, this book is for you. You needn't know JavaScript and CSS to use this book, as the author will teach you the required basics.
If you are a Struts 1 or WebWork user, and wish to go ahead and migrate to Struts 2, this is a perfectly practical guide for you.
In this book, you will find a number of styles of text that distinguish between different kinds of information. Here are some examples of these styles, and an explanation of their meaning.
Code words in text are shown as follows: "ActionSupport is an XWork class that provides validation and default implementations of several common interfaces needed for I18N."
A block of code will be set as follows:
When we wish to draw your attention to a particular part of a code block, the relevant lines or items will be shown in bold:
Any command-line input or output is written as follows:
New terms and important words are shown in bold.
Warnings or important notes appear in a box like this.
Tips and tricks appear like this.
Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or may have disliked. Reader feedback is important for us to develop titles that you really get the most out of.
To send us general feedback, simply drop an email to <[email protected]>, and mention the book title in the subject of your message.
If there is a book that you need and would like to see us publish, please send us a note in the SUGGEST A TITLE form on www.packtpub.com or email <[email protected]>.
If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide on www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
Visit http://www.packtpub.com/files/code/3391_Code.zip to directly download the example code.
The downloadable files contain instructions on how to use them.
Although we have taken every care to ensure the accuracy of our contents, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in text or code—we would be grateful if you would report this to us. By doing so, you can save other readers from frustration, and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/support, selecting your book, clicking on the let us know link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata added to any list of existing errata. Any existing errata can be viewed by selecting your title from http://www.packtpub.com/support.
Piracy of copyright material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or web site name immediately so that we can pursue a remedy.
Please contact us at <[email protected]>with a link to the suspected pirated material.
We appreciate your help in protecting our authors, and our ability to bring you valuable content.
You can contact us at <[email protected]>if you are having a problem with any aspect of the book, and we will do our best to address it.
Congratulations! Our team has been airdropped into brand-new Java web application with a non-existent specification and a ridiculous deadline. Thought it couldn’t happen? Many factors can conspire to create development nightmares. Staying light on our feet allows us to outmaneuver changes.
We've chosen Struts 2 for our framework. Our deliverables not only include the application and its associated industry-standard buzzwords, but also include complete testing (including unit, functional, and acceptance tests), along with full documentation.
Fortunately for our team (and the client), this is possible and enjoyable! Struts 2 not only meets the requirements of a modern web application development, but it exceeds them. Struts 2 fits nicely into the world of Web 2.0, and allows a rapid development cycle, necessary for both the client and developer to remain competitive.
Struts 2 began as WebWork. It was an answer to some of the perceived deficiencies in Struts 1—arguably the most popular and long-lived Java web application framework. Struts 1 was tied closely to the servlet specification and contained several Struts 1-specific constructs. This made testing difficult. In addition, because the constructs were Struts 1-specific, using them in non-Struts applications was more difficult than necessary.
Struts 2 reduces (and in most cases eliminates) ties to the servlet specification, making the testing process substantially easier. Struts 2 also allows Dependency Injection (DI) at many levels, meaning that both testability and re-usability are enhanced.
Dependency Injection (DI) or Inversion of Control (IoC) will be covered throughout the book, from several angles. In a nutshell, this means that rather than a class deciding which implementation it wants to use, it is told which implementation to use through one of several mechanisms. If you're familiar with Spring or an equivalent, then it is probable that you're already quite comfortable with the idea.
Architecturally, S2 is conceptually simple, if somewhat more complex in practice. The request cycle process can be summarized as: "Requests are filtered through interceptors and are implemented by actions. The actions return results, which are executed and returned to the browser."
Under standard configuration, Struts 2 gets a chance to process every incoming request. It is implemented as a filter (Struts 1 used a servlet) and mapped to all of the requests (Struts 1 was generally mapped to an extension such as *.do). The reason Struts 2 (usually) needs to examine all of the requests will be discussed later. However, for now, it's enough to know that the filter is the first step in processing a Struts 2 request.
Interceptors are similar to Servlet Filters, but specific to Struts 2. Interceptors are configurable for an entire application, groups of Struts 2 actions, a single action, or any combination thereof. Interceptors provide the bulk of the core framework functionality of Struts 2. Most of the "cool stuff" lives in the interceptors!
Validation, page setup, access to session and request parameters, and so on, are all provided by interceptors. They're great for providing wide-ranging functionality that cuts across an entire web application or parts thereof.
For those of us familiar with Struts 1, the (somewhat close) corollary is the Struts 1 request processor. Once, where we might have extended the request processor, we might now configure or implement an interceptor.
Many application will need only the interceptors provided by Struts 2, although we might need to configure them differently. However, many applications can benefit from even very simple custom interceptors. We'll cover details of the most useful and common Struts 2 interceptors as we go along. We will also cover (in Chapter 8) detailed interceptor configuration and implementation to add impressive and quick-to-implement functionality.
"Struts 2's actions are POJOs! Struts 2's actions are POJOs!". You'll hear that a lot. Note the following things about Struts 2's actions:
Every Struts 2 action could be a POJO. Unless we want the cool built-in functionality of Struts 2 such as form validation, I18N, and little things like that.
Let's put it this way: Struts 2's actions are more like POJO than ever before and aren't tied to the servlet spec (unless we specifically tie them to it, which is necessary on some occasions). The non-POJO aspects are wrapped up in the ActionSupport superclass, which provides a default implementation of the most useful non-POJO functionality.
This makes testing and reusing actions much easier, and eliminates one of the biggest Struts 1 headaches (we'll cover actions in depth in: Chapter 3).
Results determine what will be sent back to the browser, typically a JSP that produces HTML. Struts 2 has several other result types defined in addition to the standard dispatch to a JSP. These include redirection, redirection to actions, action chaining, FreeMarker templates, file streaming, JasperReports, and more.
We can also create and configure our own result types to provide additional application functionality that is not available in the standard Struts 2 distribution. We'll cover results, configuration, and creation of custom result types in: Chapter 4.
Struts 2 is extensible using its plug-in mechanism. Plug-ins can be used to provide additional functionality such as the JasperReports result. They could also be used to completely change the way we use Struts 2. An example of this is the REST plug-in, which provides Ruby on Rails-like URL handling and lessens our XML configuration. Plug-ins are a neat way to encapsulate functionality that can be used across our own applications, or even released into the wild for others to use.
Extreme Programming (XP) was the buzzword several years ago. It involves test-first development, pair programming, on-site customers, and more. Compare and contrast this with the waterfall method (or BDUF: Big Design Up Front), where detailed requirements are built upfront, followed by the application design. Finally, comes the implementation, verification, and maintenance part. It's still (arguably) the most common development model, despite repeated failures.
Many companies are pretty firmly entrenched in the waterfall method (XP or anything like it borders on heresy). The problem is that as soon as the toner on the specification has cooled, it's probably already incomplete or incorrect. As soon as development begins, the unanticipated will almost certainly appear.
At this point, either the original spec (or more likely, an emailed copy of a Word document with a date appended to the filename) might be updated to reflect the new reality, or the software will continue developing until it barely resembles the original design document. Generally, there will either be a formal change management process, or a customer that doesn’t end up with what they wanted. (Or ends up with what they thought they wanted, but they were wrong.).
If the application and specification are significantly out-of-sync, the specification is no longer a useful document. A developer being introduced to the project for the first time needs to either ignore the specification and look only at the code, or reconcile differences between the two.
Whether or not a client buys in to a full-blown agile methodology may not be up to us (the consultant). However, by picking and choosing components typically associated with the agile development, we can get many of the benefits.
One of the more useful XP concepts is the "user story". User stories capture system interaction at a fairly high level. Details that are unable to be determined without testing, or that are not as important as the basic functionality, may be omitted during the design phase (and may never be formally specified). We'll cover user stories as we develop the sample application.
One of the most important aspects of agile development is testing and testability. It allows for both minor and localized changes, as well as sweeping application changes, while ensuring that the functionality isn't broken.
Applications can be tested at various levels. At one end of the spectrum is unit testing, focusing on small units of functionality, and preferably not involving any of the other system's components.
Functional testing focuses on the overall system, and can consist of testing the application by using a browser driven by any of several methods. We'll discuss several types of testing in depth in Chapter 14. However, we will touch upon testing issues throughout the book.
Refactoring includes the process of identifying and consolidating similar functionality at any level in the application. Consistent and correct refactoring is made possible (or at least made much easier and more reliable) by the presence of tests. Without the ability to test easily, refactoring becomes an error-prone, hit-or-miss proposition.
Aggressive refactoring at all levels in the application (Java, JSP, HTML, CSS, and so on) can significantly reduce absolute code size, along with the cognitive overhead needed to understand the application.
Which one of the following options would you choose:
Yes, the first option gives us a chance to do the mythical "complete rewrite". However, clients rarely seem willing to fund the development of the same application twice. Moreover, refactoring is, in essence, a chance to rewrite early and often.
XP's take on this (and it is extreme) is that there should be a client on site during much of the development, providing immediate feedback on the direction of application development. This gives the developers a chance to nip problems in the bud, whether they're issues with the domain model, user interface, documentation, and so on.
While an on-site client might not be possible (or desirable!) it’s easy to give clients access to the work-in-progress. This allows the client to review functionality and provide feedback early in the process. Both functionality and design can be addressed in parallel. This can help identify usability issues, application flow changes, functional requirement changes, and so on.
However, along with shorter iterations comes a responsibility to keep the client informed about the real cost of change, both now and in the future. Big changes (or lots of little ones) may require a change in the schedule, the deliverable, or both.
Real-world web applications are much more than just the underlying web framework. Database access, CSS, Ajax, reporting, testing, the build and deploy cycle, documentation, and administration, all factor in to deliver a complete application that can be handed off to a client.
We'll cover some of the most basic aspects of making our application look good, using CSS and Struts 2’s themes and templates. These offload the bulk of "prettification" to FreeMarker templates and keep our JSP (or FreeMarker) pages fairly clean.
We'll include some CSS basics, while focusing on separating content from presentation. We will also see how we can use CSS, along with JavaScript, to provide us with easy ways to enhance functionality, usability, and testability. Along with making our applications look nice, markup that is intelligent and semantic also gives us more ways to manipulate our pages with JavaScript and Ajax.
We'll spend some time looking at JavaScript, which is the dominant player in the browser. While this isn't a complete JavaScript book, it's very important to understand how to use it to good effect, as it's a remarkably powerful language.
Grasping some of the more advanced topics makes working with existing libraries (for example, jQuery, which is used later in the book) much easier. It also makes our own JavaScript much cleaner, safer, and easier to maintain. Like any other language, using JavaScript effectively takes time, but the time it saves over using it poorly is well worth the effort.
Documentation, perhaps one of the least entertaining aspects of application development, can be made to be a relatively automated process by using a combination of existing tools and custom tools. A small amount of effort throughout the life of a project can make a big difference and enhance our final deliverable.
Scattered throughout the book will be tips and tricks that can be used to ease our development process, facilitate the creation of useful tools, and open the development process for automation. These tips and tricks enhance our "bag of tricks", making our lives easier, and our clients happier.
At the time of writing this book, the most recent version of Struts is 2.1.6. Downloading a release is straightforward, just follow the links on the Struts website. There are currently five downloads: "all", "apps", "lib", "docs", and "src". The "all" download, of course, includes everything. The "apps" download includes all of the Struts 2 sample applications, including the "blank" application (which isn't totally blank, but close).
The "lib" download includes all of the libraries required by Struts 2. This includes Struts 2 core libraries, Struts 2 plug-in libraries, and all of their dependencies. The "docs" download contains...wait for it...the documentation, including the API JavaDocs for both Struts 2 and XWork, as well as the entire Struts 2 documentation wiki. Finally, the "src" download contains the source for Struts 2, but not for XWork.
There are several ways in which we can create a Struts 2 application:
AppFuse also allows the use of Struts 2 for the backend.
Again, we're assuming some general familiarity with JEE web application development, and comfort with whatever development environment we're using.
We could just grab the necessary libraries from the "lib" distribution and do things completely by hand. It works, and it's simple (in a way). Determining which libraries are necessary can be surprisingly irritating. However, poking inside the blank sample application tells us that we really only need a few.
Getting that list of libraries is left as an exercise for the reader. This seems unnecessarily cruel. However, I really want to foster an attitude of exploration, discovery, and familiarization, with the framework and the tools we can use to expand our own knowledge and skills. Yes, I'm a little mean. By poking around we learn much more than having all the answers handed to us on a silver platter. (Especially, as it's a simple matter of looking inside the blank application WAR file. That’s a hint for the future.)
The biggest drawback to this approach, despite its simplicity, is that as soon as we start adding libraries (which we do in the next chapter), we don't necessarily understand the relationships between required libraries. In other words, we may not understand which libraries depend on which other libraries.
One of the tasks Maven was created to tackle is transitive dependencies. Simply put, Maven allows us to say: "I want to use so-and-so library", and Maven will respond with: "Oh, okay, you also need these other libraries in order to do that, and here they are for you." (Maven is actually capable of much more.)
When we look at the source for the blank sample application, we start getting a handle on how Maven works (sort of), so that we can declare a project's dependencies. However, some of the magic is hidden, as the blank application relies on a non-local resource that declares the bulk of the dependencies.
Another option is to use a Maven "archetype". In this case, it would be a representative Struts 2 application that includes everything necessary to get started. There are a few Struts 2 Maven archetypes, including a generic blank application, a RESTful application (discussed later), and so on. The Struts 2 documentation wiki explains the process of using Maven archetypes. However, you are encouraged to read the Maven documentation if that's the chosen path.
This book takes a non-committal approach to its source. The apps are available as Maven projects, or as complete non-Maven bundles. If you're interested in using Maven archetypes and typing the code yourself (or copying the source into a Maven project), then that's fine. For the most part, I will completely ignore environmental issues to focus solely on the issue(s) at hand.
Struts 2 is a flexible web application framework that can be used to create highly-functional applications very quickly. The features provided by Struts 2 give developers many ways to increase functionality, while keeping the development cost low and the client happy. By leveraging the power of standard browser technologies, along with a combination of existing and custom tools, Struts 2 can be used as an integral part of an agile development process, which eases the creation of complete applications, satisfies the client, and helps the consultant look good in the process.
There are several ways we can configure our Struts 2 applications. These include using everybody's favorite, XML, annotations, and some agile convention-over -configuration methods.
In this chapter we'll cover the minimum necessary to get an application up and running, deferring more complex topics until they're necessary. We'll also begin our journey into lightweight application specification capture by introducing the "user story" concept. Along the way, we'll also begin coding our sample application.
Our first task is to get a minimal Struts 2 application running. We're not concerned with application functionality at this point. Our goal is to make sure our builds and deploys are working properly, and to sanity-check our Struts 2 configuration.
We won't cover any IDE-specific setup requirements, or discuss application-server -specific deployment issues. We'll assume an environment including Java 1.5, Servlet 2.4, and JSP 2+.0.
Struts 2.0 is shipped with a set of JAR files usable under Java 1.4. Struts 2.1 no longer ships those libraries. The build process, however, still supports their creation. Struts 2 states a requirement of Servlet 2.4; however, full applications have been run under Servlet 2.3. Again, this capability may not always exist.
The sample applications are available in both a Maven-based distribution and a typical non-Maven directory layout. When we refer to source code, it will almost always be obvious where the directories and files belong (if you're not very familiar with Maven and wish to do things the "Maven way", there's an introduction to the Maven directory layout on the Maven website). The book text assumes that we're already able to get a Java web application compiled and deployed.
Being dependent on an IDE's build process is, in general, a bad idea. Creating a build file allows our build process to be replicated across developers, IDEs, and tools. For example, a build file might be used by a Continuous Integration server to automate compilation, testing, and deployment. We won't delve deeply into the various build process options. Therefor, you may build the book source code in whatever manner you're most accustomed to, including relying on only an IDE.
Our sanity-checking application will be as simple as possible. It will consist of only the minimum libraries necessary to get:
The Struts 2 Configuration Browser Plug-in lets us check out what Struts 2 thinks our configuration is. (Believe it or not, we do occasionally make mistakes. And ultimately it's the framework that decides what works, not us!)
Log4J is the ubiquitous logging framework. We'll discuss logging later in the book; however, we will use logging before then. Logging statements in the code can be safely ignored until then. The following is the table listing the minimum jar files to get a Struts 2 application running:
Required JAR file(s)
The Struts 2 application
struts2-core-2.1.6.jar
Struts 2 framework.
xwork-2.1.2.jar
XWork framework.
ognl-2.6.11.jar
OGNL, an expression language similar to JSP's EL, used by the Struts 2 tags.
freemarker-2.3.13.jar
FreeMarker, a templating library used to implement Struts 2's UI custom tags.
commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar
commons-logging-1.1.1.jar
FileUpload and IO are used for Struts 2's file uploading capabilities. Logging is used as a logging library wrapper.
struts2-config-browser-Plug-in-2.1.6.jar
Struts 2 Config Browser Plug-in, used to examine application configuration.
log4j-1.2.14.jar
Ubiquitous logging library.
The dependency on the Commons FileUpload package and IO libraries is required, even if we're not uploading files in our application (not having them will cause the application to fail on startup). Note that we can decide to use other file upload libraries.
Including a Struts 2 plug-in may introduce additional dependencies. For example, if we were using the Spring or JasperReports plug-ins, we would need to include their dependencies as well. Otherwise, our application may fail on startup. This is one area in which Maven is particularly handy. (There are dependency managers for Apache Ant as well. However, if we're gluttons for punishment, we can figure out the dependencies on our own.)
Struts 2 dispatches requests with a filter (Struts 1 used a servlet). By default, Struts 2 expects to have a look at all requests. This allows Struts 2 to serve static content from the classpath. This includes JavaScript files for Dojo/Ajax support and FreeMarker templates for Struts 2's custom tags.
The default filter configuration defines the filter and its mapping.
Note that we map the Struts 2 filter to /*, and not to /*.action (the default Struts 2 extension). We can check whether our server and environment are correctly configured or not. If we visit any URL ending with .action, such as /sanity/foo.action, we should see an error message along the lines of: There is no Action mapped for namespace / and action name foo. This lets us know that Struts 2 at least attempted to process our request, but it couldn't.
If we don't see a similar error message, we have to troubleshoot our build and deploy environment. We can place a simple JSP file in our web context root to determine if we're able to process any request, and to determine whether we're processing JSP files correctly. (The URLs shown in the text won't include host or port information, and assume the root context.)
The specifics of troubleshooting are environment, IDE, and server-specific. These won't be covered here. The usual suspects include classpath and deployment issues.
We'll start by writing one of the simplest actions possible:
As could be seen from above, the action doesn't extend or implement anything—it just has a method named execute() that returns a String. The execute() method is the method Struts 2 will call by default (we'll see how to call others a bit later on).
Struts 2 configuration files are expected to be on the classpath (in Struts 1 they were typically located under /WEB-INF). By default, Struts 2 will look for a file named struts.xml in the root of the classpath. The top-level elements of our Struts 2 configuration file are shown here:
The constant element defining struts.devMode puts Struts 2 into "developer mode", increasing the variety and quantity of error messages, reloading Struts 2 configuration files when they change, and so on.
It's also possible to define constants in our web.xml file; this is useful when we don't need an XML-based configuration. Either is acceptable: which is used depends on our needs and preferences. We can also define constants in a file named struts.properties, also on the classpath, but this is not preferred.
The<package> element defines a unit of configuration that our actions will live in. We'll learn more about packages later on. For now, it's enough to know that Struts 2 packages are a way of dividing up an application's functionality and configuration. The namespace attribute defines the URL prefix used for all actions in the package, and should begin with a slash (/).
We configure our simple action by placing an action element inside our package and giving our action a result—a JSP in this case.
For the most part, every action will have name and class attributes. The name attribute is used to map a URL to the action class, specified by the class attribute.
Visiting /verysimple.action should display the contents of our JSP file. If it doesn't, we need to troubleshoot our deployment.
Results determine what gets returned to the browser after an action is executed. The string returned from the action should be the name of a result. Results are configured per-action as above, or as a "global" result, available to every action in a package.
Results have optional name and type attributes. The default name value is success. In the previous example, we didn't give our result a name. This is because we're returning success from the execute() method, so we don't need to provide the name explicitly.
We also did not define the type attribute of the result. However, we can surmise that as we provided the pathname of a JSP file and we end up seeing the JSP contents in the browser, it's some sort of dispatching process. In fact, the default result type is dispatcher, which dispatches to our JSP using the normal JEE mechanism.
We could have specified both the name and the type attributes as seen here:
If we have a JSP that needs no additional processing, we can omit the action's class attribute. Struts 2 will forward to the JSP (similar to Struts 1's ForwardAction).
This keeps our JSP files hidden from direct access, and normalizes our application to use only action-based URLs. If we later modified the action to use an action class, the URL wouldn't need to be changed.
Our very simple action had a single method, execute(), which will be called by default. Consider an action with multiple action methods:
We can define which method to call using the method attribute as seen here:
Some people prefer creating separate classes for every action, rather than filling an action with several methods. Which route to take can depend on several factors, including personal preference. In some cases it makes perfect sense to keep related functionality in a single class, in other cases it may not.
This last example seems repetitive—the method and result names are the same and the JSPs have similar naming conventions. Struts 2 allows wildcard mapping in several ways, which we'll use now to help lay out our application flow.
The traditional model of application development generally starts with the gathering of requirements, followed by separate design, implementation, verification, and maintenance phases. This is called the waterfall method and has been around for many years.
In contrast, more agile models of development focus on the user experience, rapid turnaround of functionalities, and iterative development. This allows our clients to provide feedback in parallel with development, requesting changes in functionality, detecting usability and application flow issues, and so on, early in the process. In many circumstances, this lightweight development cycle can greatly speed up the development time, and deliver an application that more accurately meets the client's needs.
Our client is building a recipe swapping website, which allows us to build a shopping list from a set of selected recipes. Even without any further requirements, we know we'll need at least five pages—home, recipe search, recipe list, recipe entry, and shopping list.
The first tool we'll explore for capturing application functionality are user stories. User stories are very short descriptions of functionalities (often captured on index cards) that represent a user experience.
User stories do not contain implementation or specification details. A simple example might be: "A user can search for recipes." This might even be expanded to read: "A user can search for recipes by name, ingredients, and so on." Anything significantly more detailed than that is (usually) better expressed as additional, equally short stories.
At this stage in our application requirements gathering, we have five user stories; a couple of them with some minor reminders of expected functionality:
Obviously, this isn't a complete application specification. However, it is enough to get started on coding the most basic website pages, organizing our development effort, and defining a tangible set of deliverables for the client. Even at this stage, the client might identify some missing functionalities, poor application flow, and so on.
We already know enough to define our action mappings to create skeletons of these pages, although they're a bit heavy considering our simple needs. Struts 2 provides handy wildcard configuration mechanisms making early prototyping really simple.
Wildcard action definitions are a quick way to create the skeleton of an application. The following configuration, along with the required JSP files, is enough:
The {1} refers to the first (in this case only) wildcard in the action's name attribute. In this case, visiting /foo.action would return the /WEB-INF/jsps/foo.jsp file.
Supplying a JSP page for each story creates an outline of the application. We might use the previously shown wildcard technique and create home.jsp, recipesearch.jsp, recipelist.jsp, recipenew.jsp, and shoppinglist.jsp. Visiting /home.action would give us /WEB-INF/jsps/home.jsp. We're not actually going to do it this way: the URLs are ugly, and we suspect there must be a better way.
We have at least two different major divisions in our application—recipes and shopping lists. In the examples above we had pages such as /recipenew.action, rather than the more natural and hierarchical /recipe/new.action.
One solution would be to use multiple wildcards. Multiple wildcards allow us to map individual portions of the URL to action names, JSPs, directories, and so on. For example, see the following:
Here, we use the first wildcard as a directory (like /WEB-INF/jsps/recipe). The second defines the page (JSP) to be shown, such as list.jsp, new.jsp, and so on. Now the cleaner /recipe/list.action URL would return /WEB-INF/jsps/recipe/list.jsp.
Using this method means that we have a slash (/) in our action name. To do this, we must set the struts.enable.SlashesInActionNames in our struts.xml file (shown next), our web.xml, or (not preferred) our struts.properties file.
<constant name="struts.enable.SlashesInActionNames" value="true"/>
