查看文章 |
Update DependenciesUpdate your project dependences to use struts2-core-2.1.x and the plugins struts2-core-2.1.x.
Maven users can update their project's pom.xml to reference the new core and plugin versions. Ensure no dependencies in the freemarker groupId are used as the latest version used by Struts is now under the org.freeemarker groupId and will cause classpath conflicts. If you need releases not considered General Availability you can use a staging repository where they are usually available: <repositories>
<repository>
<id>struts2.1.2-staging</id>
<name>Struts 2.1.2 staging repository</name>
<layout>default</layout>
<url>http://people.apache.org/builds/struts/2.1.2/m2-staging-repository/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
Non-Maven users can can download the jars and dependencies in a Distribution 2.1.2
Update Custom Type ConvertersIf your project implements custom type converters you may need to change the imports statements to use the com.opensymphony.xwork2.conversion package. Failing to do so will cause a compile-time error. Before: import com.opensymphony.xwork2.util.TypeConversionException;
After: import com.opensymphony.xwork2.conversion.TypeConversionException;
Update struts.xml ConfigurationResults and Interceptors have been renamed to use camelCase instead of hyphenated names (eg. now redirectAction instead of redirect-action). Interceptors:
Results:
Migrate plugin configurationTiles 2If you use the Tiles 2 plugin, check your tiles.xml file(s) to ensure they contain a DOCTYPE. <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "http://tiles.apache.org/dtds/tiles-config_2_0.dtd"> <tiles-definitions> ...
Ajax Theme / DojoIf your WebApp uses the ajax theme bundled with Struts 2.0 (ajax tags), you need to update every pageas the Dojo support has been moved into a separate plugin and tag library. 1. Add the Dojo plugin as a new dependency for your project <dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-dojo-plugin</artifactId>
<version>2.1.1</version>
</dependency>
2. Modify ALL pages that use the ajax theme to use the Dojo tag library. For each page there are three tasks to complete:
Reference the new Dojo Tag LibraryReference the new taglib in your JSP or FTL pages. <%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags"%> After <%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags"%> <%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
Update the head tagReview the new attributes of the new head Before: <s:head theme="ajax"/>
After: <sx:head parseContent="true"/>
Update all ajax themed tagsSome tags are available only in the Dojo plugin taglib. It will be immediately obvious from your IDE that these tags need to change to the sx: prefix. Before: <s:url id="jobStatus" includeParams="get" value="/RefreshOptimizationJobStatus.action" /> <s:div id="jobStatus" theme="ajax" href="%{jobStatus}" updateFreq="5000" indicator="indicator"> </s:div> <img id="indicator" src="img/indicator.gif" alt="Loading..." style="display:none"/> After: <s:url var="jobStatus" includeParams="get" value="/RefreshOptimizationJobStatus.action" /> <sx:div id="jobStatus" href="%{#jobStatus}" updateFreq="5000" autoStart="true" indicator="indicator"> </sx:div> <img id="indicator" src="img/indicator.gif" alt="Loading..." style="display:none"/>
Check inline javascriptIf your ajax html results contain inline javascript that needs to be executed after updating the DOM, ensure your ajax tags set executeScripts="true" and separateScripts="true". These attributes instruct the widget to search for javascript in the result, eg. The following bind will execute scripts within the result when the Submit button is pressed <s:submit value="Submit" id="submit3" /> <sx:bind targets="div1" highlightColor="#ffffcc" highlightDuration="500" sources="submit3" events="onclick" href="%{#fragment3Url}" errorNotifyTopics="/error" executeScripts="true" separateScripts="true"/> Check inline widgetsIf your ajax html results include dojo widgets, ensure the head tag's parseContent attribute is true. This instructs dojo to parse the ajax responses for widgets. Note that Struts2.0 always enabled this feature and it could not be turned off. Struts2.1 disables this feature and allows it to be turned on as there is a significant performance impact. Convert EL expressions to OGNLStruts2.1 tags do not allow evaluation of JSP EL within their attributes. Instead, Struts2 tags evaluate attribute values as OGNL. Allowing both expression languages within the same attribute opens major security vulnerabilities. todo: how to convert
Reduce verbose loggingStruts 2.1 introduces more verbose logging than Struts 2.0. While extremely valuable, some users may find these annoying. Missing PropertiesThis message states that the framework searched for a property in the value stack and failed to find it. 2008-04-19 14:21:08,177 WARN [http-8443-Processor25] [OgnlValueStack] Could not find property [templateDir] 2008-04-19 14:21:08,177 WARN [http-8443-Processor25] [OgnlValueStack] Could not find property [templateDir] 2008-04-19 14:21:08,177 WARN [http-8443-Processor25] [OgnlValueStack] Could not find property [templateDir] 2008-04-19 14:21:08,178 WARN [http-8443-Processor25] [OgnlValueStack] Could not find property [org.apache.catalina.jsp_file] To hide these messages, turn off the WARN level logging for OgnlValueStack. eg. Include a new limit category in your log4j.xml file (only log errors or worse): <category name="com.opensymphony.xwork2.ognl.OgnlValueStack"> <priority value="error"/> </category> TextProvider missing keysThese messages state that the framework searched for text in a resource bundle and failed to find it. 2008-04-19 14:32:30,106 WARN [http-8443-Processor23] [TextProviderHelper] The first TextProvider in the ValueStack (package.Action) could not locate the message resource with key 'companyDetails.addressId' 2008-04-19 14:32:30,107 WARN [http-8443-Processor23] [TextProviderHelper] The default value expression 'companyDetails.addressId' evaluated to '10' To hide those messages, turn off the WARN level logging for TextProviderHelper. eg. Include a new limit category in your log4j.xml file (only log errors or worse): <category name="org.apache.struts2.util.TextProviderHelper"> <priority value="error"/> </category> Update Unit TestsThere are two known major migration issues affecting user's unit tests.
Review the Unit Tests included with Struts2 for recommended practices to setup the Configuration and context. A quick fix for ActionContext.getContext() returning null : ConfigurationManager configurationManager = new ConfigurationManager(); configurationManager.addContainerProvider(new XWorkConfigurationProvider()); Configuration config = configurationManager.getConfiguration(); Container container = config.getContainer(); ValueStack stack = container.getInstance(ValueStackFactory.class).createValueStack(); stack.getContext().put(ActionContext.CONTAINER, container); ActionContext.setContext(new ActionContext(stack.getContext())); assertNotNull(ActionContext.getContext()); Trouble-shootingThe issues are listed in the same order as encountered after changing jars over from 2.0.x to 2.1.x. Noteworthy, the migration was done under the following setup: Fedora core 6, JDK 1.6.0_2 and Tomcat 6.0.10 running from MyEclipse plugin. Result type "redirect-action" was renamed to "redirectAction":SEVERE: Exception starting filter struts2
Unable to load configuration. - action - file:/home/giaz/code/.metadata/.plugins/
com.genuitec.eclipse.easie.tomcat.myeclipse/tomcat/webapps/webui/WEB-INF/classes/struts.xml:39:98
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:58)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:370)
...
Caused by: Error building results for action ScheduleJob in namespace - action - file:/home/giaz/code/.metadata/.plugins/
com.genuitec.eclipse.easie.tomcat.myeclipse/tomcat/webapps/webui/WEB-INF/classes/struts.xml:39:98
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addAction(XmlConfigurationProvider.java:372)
... 30 more
Caused by: There is no result type defined for type 'redirect-action' mapped with name 'success' - result -
file:/home/giaz/code/.metadata/.plugins/com.genuitec.eclipse.easie.tomcat.myeclipse/tomcat/webapps/webui/
WEB-INF/classes/struts.xml:40:50
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.buildResults(XmlConfigurationProvider.java:616)
... 35 more
The struts.xml before: <action name="ScheduleJob" class="com.sag.optimizer.ui.web.action.scheduler.ScheduleJobAction"> <result name="success" type="redirect-action"> <param name="actionName">ListDisplayOptimizationJobStatus</param> </result> <result name="error" type="tiles">webui.requestFailed</result> </action> To resolve this issue modify the struts.xml action definition to: <action name="ScheduleJob" class="com.sag.optimizer.ui.web.action.scheduler.ScheduleJobAction"> <result name="success" type="redirectAction"> <param name="actionName">ListDisplayOptimizationJobStatus</param> </result> <result name="error" type="tiles">webui.requestFailed</result> </action> or to: <action name="ScheduleJob" class="com.sag.optimizer.ui.web.action.scheduler.ScheduleJobAction"> <result name="success" type="redirect">ListDisplayOptimizationJobStatus.action</result> <result name="error" type="tiles">webui.requestFailed</result> </action> Tiles 2.1.x plugin tiles.xml now requires DOCTYPE:Problem Symptom: Nov 22, 2007 11:38:11 AM org.apache.tiles.impl.BasicTilesContainer init INFO: Initializing Tiles2 container. . . Nov 22, 2007 11:38:11 AM org.apache.commons.digester.Digester error SEVERE: Parse Error at line 2 column 19: Document is invalid: no grammar found. org.xml.sax.SAXParseException: Document is invalid: no grammar found. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195) at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131)
The tiles.xml page before: <?xml version="1.0" encoding="ISO-8859-1" ?> <tiles-definitions/> To resolve the issue simply add: <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "http://struts.apache.org/dtds/tiles-config_2_0.dtd"> <tiles-definitions/> <s:head theme="ajax"/> is obsolete, use a different theme:Problem Symptom: Accessing any page that includes <s:head theme="ajax"/> produces the following error: Nov 22, 2007 1:54:51 PM freemarker.log.JDK14LoggerFactory$JDK14Logger error
SEVERE:
Expression parameters.parseContent is undefined on line 45, column 28 in template/ajax/head.ftl.
The problematic instruction:
----------
==> ${parameters.parseContent?string} [on line 45, column 26 in template/ajax/head.ftl]
----------
Java backtrace for programmers:
----------
freemarker.core.InvalidReferenceException: Expression parameters.parseContent is undefined on line 45,
column 28 in template/ajax/head.ftl.
at freemarker.core.TemplateObject.assertNonNull(TemplateObject.java:124)
at freemarker.core.TemplateObject.invalidTypeException(TemplateObject.java:134)
Resolution is to either remove the "<s:head theme="ajax"/>" or use a different theme e.g. <s:head theme="xhtml" /> Ajax UI tags were moved to the new dojo plugin, use /struts-dojo-tags taglib instead of (or in addition to) /struts-tags:Problem Symptom: Accessing a page containing ajax UI tags through using the struts 2 taglib will produce the following error: SEVERE: Servlet.service() for servlet jsp threw exception org.apache.jasper.JasperException: /jsp/list/listOptimizationJobStatus.jsp(6,0) Attribute href invalid for tag div according to TLD at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40) at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407) JSP before migration: <%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="display" uri="http://displaytag.sf.net" %> <%@ taglib prefix="s" uri="/struts-tags"%> <s:url id="jobStatus" includeParams="get" value="/RefreshOptimizationJobStatus.action" /> <s:div id="jobStatus" theme="ajax" href="%{jobStatus}" updateFreq="5000" indicator="indicator"> </s:div> <img id="indicator" src="img/indicator.gif" alt="Loading..." style="display:none"/> Resolution is to import and use struts-dojo-tags plugin instead: <%@ page contentType="text/html; charset=UTF-8" language="java" %> <%@ taglib prefix="s" uri="/struts-tags"%> <%@ taglib prefix="sx" uri="/struts-dojo-tags" %> <s:url var="jobStatus" includeParams="get" value="/RefreshOptimizationJobStatus.action" /> <sx:div id="jobStatus" href="%{#jobStatus}" updateFreq="5000" autoStart="true" indicator="indicator"> </sx:div> <img id="indicator" src="img/indicator.gif" alt="Loading..." style="display:none"/>
User-defined converter (subclassing StrutsTypeConverter) will no longer be needed when using datetimepicker:Problem Symptom: Your custom StrutsTypeConverter implementation does not longer work in version 2.1.x. In 2.0.x you needed to implement a custom StrutsTypeConverter e.g. StringToDateConverter to be able to parse and convert to Date the String posted from a datetimepicker control into the action. In version 2.0.x datetimepicker was posting a String formatted as specified in the "displayFormat" field e.g. <%@ taglib prefix="s" uri="/struts-tags"%> <s:datetimepicker label="Begin Date" name="beginDate" displayFormat="yyyy.MM.dd"> In version 2.1.x datetimepicker will post a String Date in RFC 3339 format, so you can define your setter to receive a Date directly and avoid using converters for this purpose e.g. <%@ taglib prefix="s" uri="/struts-tags"%> <%@ taglib prefix="sx" uri="/struts-dojo-tags" %> <sx:datetimepicker label="Begin Date" name="beginDate" displayFormat="yyyy.MM.dd"> ActionMappingParamsParameters set by the action mapping are not set/not available through ParameterAware (This change is only needed when going to 2.1.x (where x>0)) These are now only available if you use the new interceptor named "actionMappingParams".
|
