You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 16 Next »

Feature Comparison

Unknown macro: {table}

Feature | SAF 1.x | SAF 2.x
Action classes | SAF 1.x requires Action classes to extend an Abstract base class. This shows a common problem in SAF 1 of programming to abstract classes instead of interfaces. | An Action may implement the com.opensymphony.xwork.Action Interface, with a series of other Interfaces for other services, like in WebWork 1.x. SAF 2 has its own ActionSupport base class that implements these Interfaces.
Threading Model | SAF 1 Actions must be thread-safe because there will only be one instance to handle all requests. This places restrictions on what can be done with SAF 1 Actions as any resources held must be thread-safe or access to them must be synchronized. | SAF 2 Actions are instantiated for each request, so there are no thread-safety issues. In practice, Servlet containers generate many throw-away objects per request, and one more object does not prove to be a problem for performance or garbage collection.
Servlet Dependency | SAF 1 Actions have dependencies on Servlets because they are passed the HttpServletRequest and HttpServletResponse when they are executed. | SAF 2 Actions are not tied to the web or any container. SAF 2 Actions CAN choose to access the request and response from the ActionContext, but it is not required and should be done only when ABSOLUTELY neccessary to avoid coupling code to a container.
Testability | Many strategies have sprung up around testing SAF 1 applications, but the major hurdle is the fact that SAF 1 Actions are coupled to a servlet environment. This often leads people to test SAF 1 Actions inside a container, which is both slow and is not true unit testing. A Junit extension, Struts TestCase (http://strutstestcase.sourceforge.net/), can use either mocks or Cactus. | SAF 1 Actions can be tested by instantiating your Action, setting the properties, and invoking execute or an alias. SAF 2's usuage of dependency injection makes testing even simpler, as you can just set a Mock implementation of your services into your Action for testing, instead of having to set up service registries or static singletons
FormBeans | SAF 1 requires the use of a FormBean for input forms, necessitating either a lot of extra classes or the use of DynaBeans | SAF 2 allows you to have all of your properties directly accessible on your Action as regular Javabeans properties, including rich Object types which can have their own properties which can be accessed from the web page. SAF 2 not only supports the FormBean pattern, it allows ModelDriven Actions that can use a rich Object type or domain object as your form bean, with its properties directly accessible to the web page, rather than accessing them as sub-properties of a property of the Action.
Expression Language | SAF 1 integrates with JSTL, so it uses the JSTL EL. The EL has basic object graph traversal, but relatively weak collection and indexed property support. | SAF 2 uses OGNL, a powerful expression language, with additions for accessing the ValueStack. OGNL supports very powerful collection and indexed property support. OGNL also supports powerful features like projections (calling the same method on each member of a collection and building a new collection of the results), selections (filtering a collection with a selector expression to return a subset), list construction, and lambda expressions (simple functions which can be reused). OGNL allows access to static methods, static fields, and constructors of classes. SAF 2 can also use JSTL.
Binding values into views | SAF 1 uses the standard JSP mechanism for binding objects into the page context for access, which tightly couples your view to the form beans being rendered | SAF 2 sets up a ValueStack which the taglibs access to dynamically find values without coupling your view to the types it is rendering. This strategy allows you to reuse views across a range of types which have the same properties.
Type Conversion | SAF 1 FormBeans properties are usually all Strings. SAF 1 uses Commons-Beanutils for type conversion. Converters are per-class, and not configurable per instance. Getting a meaningful type conversion error out and displaying it to the user can be difficult. | SAF 2 uses OGNL for type conversion with added converters provided for all basic types. Type converters default to these converters, but type conversion can be specified per field per class. Type conversion errors also have a default error message but can be set per field per class using the localization mechanism in SAF 2 and will be set into the field error messages of the Action.
Modular Before & After Processing | Class hierarchies of base Actions must be built up to do processing before and after delegating to the Action classes, which can lead deep class hierarchies and limitations due to the inability to have multiple inheritance | SAF 2 allows you to modularize before and after processing in Interceptors. Interceptors can be applied dynamically via the configuration without any coupling between the Action classes and the Interceptors.
Validation | SAF 1 calls validate() on the FormBean. SAF 1 users often use Commons Validation for validation. Because FormBean properties are usually Strings, many validations are perfomed by converting input and then throwing away the result. The SAF 1 validator can have different validation contexts for the same class, but it cannot chain to validations on sub-objects. | SAF can use a validate method or or use the XWork Validation framework. The XWork Validation Framework allows you to define validations in an XML format with default validations for a class and custom validations added for different validation contexts. The XWork Validation Framework is enabled via an Interceptor and is therefore completely decoupled from Action classes. The XWork Validation Framework also allows you to chain the validation process down into sub-properties using the validations defined for the properties class type and the validation context.
Control Of Action Execution | SAF 1 provides a single request processor per module, which utilizes a uniforum lifecycle for each Action in a module. | SAF 2 can specify request life cycles (Interceptor Stack) on a per Action basis.

  • No labels