Table of Contents
foreword xv
preface xvii
acknowledgments xix
about this book xxi
a look at the future xxvi
about the title xxvii
about the cover illustration xxviii
Part 1 Introduction to WebWork 1
- 1 An overview of WebWork 3
- Why MVC is important 5
- Classic MVC becomes outdated 6, Classic MVC gets an update:
the Front Controller 7, MVC evolves: the Page Controller 7
- Understanding frameworks and containers 9
- What is a framework? 9, What a container can do 11
- WebWork: past, present, and future 13
- The history of WebWork 13, Understanding the XWork core 13
- Future directions 15
- The CaveatEmptor application 15
- How CaveatEmptor is organized 16
- Summary 17
- 2 HelloWorld, the WebWork way 19
- Downloading WebWork 20
- Preparing the skeleton 20
- Creating the web.xml deployment file 21, Creating the xwork.xml configuration file 23, Creating the webwork.properties
configuration file 23, Tips for developing WebWork apps 24
- Your first action 24
- Saying hello, the WebWork way 25, Displaying output to
the web browser 26, Configuring your new action 27
- Dealing with inputs 28
- Advanced control flow 31
- Letting WebWork do the work 33
- Taking advantage of ActionSupport 34, Intermediate modifications to the JSP 35, Exploring the UI tag library 36
- Summary 37
- 3 Setting up WebWork 38
- Configuring actions, results, and interceptors 39
- Overview of terminology 39, Actions 40
- Results 46, Interceptors 48
- Advanced configuration 52
- The xwork.xml DTD 52, Namespaces and packages 53
- Componentization using the include tag 57
- Other configuration files 66
- Web-app configuration: web.xml 66
- Feature configuration: webwork.properties 67
- Setting up your web app 70
- General layout 70, Required libraries 71, Optional libraries 72
- Summary 72
Part 2 Core concepts 75
- 4 Implementing WebWork actions 77
- The Action interface 78
- Result codes 78, Handling exceptions 79
- Using the ActionSupport base class 80
- Understanding basic validation 80
- Validating an action: Validateable 81
- Displaying error messages: ValidationAware 82
- Using localized message texts 86
- Retrieving the user?s locale: LocaleProvider 86
- Displaying the localized text: TextProvider 86
- Providing messages for other languages 89
- Advanced inputs 90
- Intermediary objects 90, Using domain objects directly 91
- Working with ModelDriven actions 95
- Implementing ModelDriven actions 96
- Considerations when using ModelDriven 100
- Accessing data through the ActionContext 102
- CaveatEmptor: accessing the session 102
- Example: accessing the request and response 105
- Handling file uploads 107
- Accessing uploaded files through the request wrapper 107
- Automating file uploads 109, Configuration settings 110
- Summary 111
- 5 Adding functionality with interceptors 112
- How interceptors are called 113
- Using the prepackaged interceptors 114
- Utility interceptors 117, Setting parameters 119
- Defining workflow 123
- Using prepackaged interceptor stacks 126
- Building your own interceptors 128
- Using the AroundInterceptor as a base 129, Looking at an example custom interceptor 130, Getting callbacks before the result is
executed with the PreResultListener 133, Looking out for
interceptor interactions 134
- Interceptors vs. servlet filters 135
- Summary 136
- 6 Inversion of Control 137
- Examining the pattern 138
- Common patterns for active resource management 138, Inverting
resource management 142, How IoC helps with testing 145
- IoC essentials 146
- WebWork?s IoC history 146, Dependencies 148
- Scope and lifecycle 149
- Using WebWork?s IoC framework 151
- Configuration 151, Creating a new component 154, Using IoC on any object 158, Dealing with complex dependencies 159
- An example from CaveatEmptor 162
- The HibernateSessionFactory component 163, The Persistence
Manager component 165, Configuring the components 168
- Using the new components 169
- Alternatives 170
- Alternative IoC containers 170, Non-IoC alternatives 172
- Summary 173
Part 3 Displaying content 175
- 7 Using results 177
- Life after the action 178
- A simple result 178, Configuring a result 180
- Common results 182
- Dispatching to a page 182, Redirecting to a page 188
- Chaining to another action 192
- Other results 197
- Streaming Velocity templates directly to the output 197
- FreeMarker: an alternative to Velocity 202
- Generating reports with JasperReports 203
- Summary 207
- 8 Getting data with the expression language 209
- What is an expression language? 210
- Why an expression language? 210, Why OGNL? 211
- Other expression languages 212, Key OGNL concepts 213
- Basic expression language features 213
- Accessing bean properties 214, Literals and operators 215
- Calling methods 217, Setting values and expression lists 218
- Accessing static methods and fields 218, Accessing the OGNL
context and the ActionContext 218
- Working with collections 220
- Working with lists and arrays 220, Working with maps 221
- Filtering and projecting collections 222, The multiple uses
of ?#? 223
- Advanced expression language features 224
- Linking the value stack to the expression language 224
- Data type conversion 226, Handling null property access 227
- Creating lambda expressions on the fly 228
- Summary 228
- 9 Tag libraries 230
- Getting started 231
- An overview of WebWork tags 232
- The WebWork tag syntax 233
- Data tags 235
- The property tag 235, The set tag 236, The push tag 237
- The bean tag 238, The action tag 240
- Control tags 242
- The iterator tag 242, The if and else tags 245
- Miscellaneous tags 246
- The include tag 246, The URL tag 247, The i18n
and text tags 250, The param tag 252
- Summary 253
- 10 Velocity 254
- Introduction to Velocity 255
- What is Velocity? 255, Getting ready to use Velocity 257
- Basic syntax and operations 259
- Property access 259, Method calls 261, Control statements:
if/else and loops 261, Assigning variables 265
- Advanced techniques 265
- The VelocityContext 265, WebWork-supplied objects in
the context 266, Customizing the Velocity context 267
- Using JSP tags in Velocity 268
- Loading Velocity templates 269
- Summary 269
- 11 UI components 271
- Why bother with UI tags? 272
- Eliminating the pain 272, More than just form elements 280
- UI tag overview 283
- Templates 283, Themes 285, Tag attributes 291
- UI tag reference 291
- Common attributes 291, Simple tags 294
- Collection-based tags 299, Advanced tags 305
- Summary 309
Part 4 Advanced topics 311
- 12 Type conversion 313
- Why type conversion? 314
- The Servlet specification 314, An action without type conversion 315, A view without type conversion 317
- What WebWork?s type conversion gives you 319
- Configuration 320
- Role of a type converter 321, Global type converters 322
- Class-level type converters 322
- Simple type conversion 323
- Basic type conversion 323, Built-in type conversion 325
- Handling null property access 326
- Advanced topics 326
- Handling null Collection access 326, Handling conversion errors 329, An example that puts it all together 330
- Summary 331
- 13 Validating form data 333
- Manually validating data 336
- Validating in the execute() method 336
- Implementing the Validateable interface 337
- Using the Validation Framework 340
- Building your first *-validation.xml file 340, Registering validators 341, Applying the validation interceptor 345, Pulling it all together 346, Looking at some validation XML examples 348
- Exploring the advanced features
of the Validation Framework 350
- Implementing a custom validator 351, Validating with
different contexts 353, Short-circuiting validation 354
- The ExpressionValidator 355, Reusing validations with
the visitor field validator 356
- Summary 359
- 14 Internationalization 360
- Exploring a quick internationalization example 361
- Sources for messages 362
- Understanding the ResourceBundle search order 364. Adding
default resource bundles 366, The tag 366
- Using internationalized messages 368
- Parameterizing localized texts 368, Using getText() in taglib attributes 369, Formatting dates and numbers 370, Using localized messages in validations 370, Using internationalized texts for type conversion messages 371
- Tips and tricks 373
- Programmatically setting the locale 373, Implementing ResourceBundles as classes 375, Using the tag to pass dynamically generated text to message texts 378, Setting the encoding: here, there, and everywhere 381, A note on Java PropertyResourceBundles 382, A final note 382
- Summary 383
- 15 Best practices 384
- Setting up your environment 385
- Setting up your IDE 386, Reloading resources 388
- Unit-testing your actions 389
- Using mock objects 389, The advantage of IoC for testing 391
- Handling statics and ThreadLocals 391
- Putting the pieces together: integration testing 393
- Testing your configuration 393
- Seeing the configuration with the config browser 396
- Testing validations 398
- Testing programmatic validations 398
- Testing validation.xml files 398
- Advanced UI tag usage 402
- Overriding existing templates 403, Writing custom templates 406
- Writing custom themes 407
- Using form tokens to prevent
duplicate form submissions 409
- Using the tag 410, Applying the TokenInterceptor 412, Transparently re-rendering pages with the TokenSessionStoreInterceptor 413
- Displaying wait pages automatically 413
- A Single action for CRUD operations 417
- Creating new categories with newCategory 418, Reading and
updating with viewCategory and editCategory 419, Saving categories with saveCategory 420, Setting the parentCategory 422
- Summary 423
 
WebWork architecture 424
index 439