Package changesWebwork1.x was seperated into two projects, XWork and Webwork. From this, several classes have been moved to different package names.
Configuration changes
java org.apache.xalan.xslt.Process -IN actions.xml -XSL actions.xsl -OUT xwork.xml
Remember that you'll need to Xalan libraries in your classpath to run the above command. WebWork 1.x configuration used a pull paradigm to load action configurations when they are asked for, whereas WebWork2 builds the configuration up-front to make the configuration queryable. The webwork.MigrationConfiguration must therefore act as an adapter between these two paradigms. It does this by returning a custom RuntimeConfiguration which first tries the default XWork Configuration (which, by default, loads configuration information from a file named "xwork.xml" in the root of the classpath) and then attempts to load action configuration using the Configuration classes from WebWork 1.x. In this way, an application can be slowly converted over to WebWork2 while reusing the configuration and Actions from a WebWork 1.x application. One caveat in this is that your migrated application MUST be rebuilt against the WebWork2 and migration jar files, as the classloader will rightly recognize that the webwork.Action and webwork.ActionSupport in WebWork 1.x are not the same as those provided by the migration jar files. Other than that, it should be seamless (and let us know if it isn't). If the webwork.MigrationRuntimeConfiguration does not find the action configuration using the RuntimeConfiguration from the supplied RuntimeConfiguration (which is acquried from the Xwork DefaultConfiguration and will load configurations from all of the sources configured for XWork / WebWork2), it will build an ActionConfiguration by instantiating an Action using the ActionFactories from WebWork 1.x. The ActionFactory stack used is a subset of the default ActionFactory stack used in WebWork 1.x: factory = new JavaActionFactory(); factory = new ScriptActionFactoryProxy(factory); factory = new XMLActionFactoryProxy(factory); factory = new PrefixActionFactoryProxy(factory); factory = new JspActionFactoryProxy(factory); factory = new CommandActionFactoryProxy(factory); factory = new AliasingActionFactoryProxy(factory); factory = new CommandActionFactoryProxy(factory); factory = new ContextActionFactoryProxy(factory); Some of the ActionFactory classes have been left out as they are handled by Interceptors in WebWork2. If the Action instance is created (meaning that the configuration has been found in the webwork.properties or actions.xml files used by the WebWork 1.x configuration classes) a parameter Map is created by introspecting the Action instance. A Map is needed for results and, again, WebWork 1.x used a pull paradigm to find results when they were needed, so a LazyResultMap is created which extends HashMap and overrides get() to look up the Result configuration if it has not previously been loaded. If the result ends in the Action suffix (defaulting to ".action"), then a ChainingResult is created, otherwise a ServletDispatcherResult is created. Using the Action class of the instantiated Action, the Map of parameters introspected from the Action instance, and the LazyResultMap, a new ActionConfig is created. The ActionConfig is saved into a special Package, "webwork-migration", so that it will pick up the default Interceptor stack defined for that package. The "webwork-migration" package is defined in a webwork-migration.xml file which is included in the migration jar file and which is automatically added to the Xwork configuration providers when the MigrationConfiguration is used: <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <include file="webwork-default.xml"/> <package name="webwork-migration" abstract="true" extends="webwork-default"> <interceptors> <interceptor-stack name="migrationStack"> <interceptor-ref name="timer"/> <interceptor-ref name="logger"/> <interceptor-ref name="chain"/> <interceptor-ref name="static-params"/> <interceptor-ref name="prepare"/> <interceptor-ref name="params"/> <interceptor-ref name="workflow"/> </interceptor-stack> </interceptors> <default-interceptor-ref name="migrationStack"/> </package> </xwork> Here we can see that a number of the functions previously performed by ActionFactories in WebWork 1.x are now replaced by Interceptors in WebWork2, including the parameters, the chaining, calling prepare(), and the workflow (which was formerly implemented in ActionSupport in WebWork 1.x). By creating and saving the ActionConfig in the PackageConfig for the "webwork-migration" package, the ActionConfig for the migrated Action is available for future calls, obviating the need to re-parse the old configuration files and making the configuration for the Action available for querying via the configuration API for tools such as the configuration browser. Tag ChangesThe biggest change is the use of OGNL for accessing object properties. Properties are no longer accessed with a forward slash "/" but with a dot "." Also, rather than using ".." to traverse down the stack, we now use "[n]" where n is some positive number. Lastly, in WebWork 1.x one could access special named objects (the request scope attributes to be exact) by using "@foo", but now special variables are accessed using "#foo". However, it is important to note that "#foo" does NOT access the request attributes. "#foo" is merely a request to another object in the OgnlContext other than the root. See OGNL reference for more details. Also see JSP Expression Language Comparison with WebWork 1.x for a table of the expression language changes. property tagThe property tag is now only used to print out values from the stack. In WW1, it was also used to set a variable in the scope, and to push properties to the top of the stack. These functions are now performed by the set and push tags. action tagThe action tag does not evaluate the body section any more and does not push the executed action onto the ValueStack. Instead, use the "id" attribute to assign a name to the action and reference it as "#id". ExamplesLets enumerate some examples of differences between code snips using WW:WebWork and WW:WebWork.
There are numerous changes in syntax. First of all there are new tags and secondly there is a new expression language. Here's a small example: Webwork 1 <ww:property value="a/b"> <ww:property value="foo" /> </ww:property> Webwork 2 <ww:push value="a.b"> <ww:property value="foo" /> </ww:push> One can note that the "push" tag doesn't just push it pops too at the end of the tag. Surprise! Also note the "." instead of the "/" for traversing object properties.
Update your web.xml file
WebWork will use this file to initialize the Velocity engine. The search path for the file is:
ResultException doesn't exist anymoreIt might be possible to copy WW1's ResultException, and write an Interceptor that catches the ResultExceptions and add the result of getMessage() to the actionErrors of the Maybe it would be possible to include ResultException in WW2 too to make migration easier?! DateFormatter doesn't exist anymoreIt can be replaced by directly using java.text.DateFormat addError(String, String) in webwork.action.ActionSupport has been removedThe new method to use is addFieldError(String, String). addErrorMessage(String) in webwork.action.ActionSupport has been removedThe new method is now addActionError(String). webwork.util.ValueStack has been removedThe ValueStack is com.opensymphony.xwork.util.OgnlValueStack The old methods pushValue and popValue are renamed to simply push and An instance of the ValueStack can be obtained by using ActionContext.getContext().getValueStack instead of the old ValueStack.getStack(). *Aware-Interfaces have been removedInstead of implementing ServletRequestAware etc the CommandDriven interface removedThe CommandDriven interface is removed. It is not neccesary to implement a special interface when working with commands anymore. Use the method attribute in your action-Element in xwork.xml to tell xwork which method to invoke on your action. isCommand(String) method has been removedYou can see which alias you're accessing by doing this: ActionContext.getContext().getActionInvocation().getProxy().getActionName() |