You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by jh...@apache.org on 2007/07/24 19:33:39 UTC
svn commit: r559127 - in /struts/struts2/trunk/core/src:
main/java/org/apache/struts2/components/
main/java/org/apache/struts2/views/jsp/
main/java/org/apache/struts2/views/util/ site/resources/tags/
test/java/org/apache/struts2/views/jsp/ test/java/or...
Author: jholmes
Date: Tue Jul 24 10:33:38 2007
New Revision: 559127
URL: http://svn.apache.org/viewvc?view=rev&rev=559127
Log:
WW-1938 Bug with multiple s:param tags inside s:url tag
Modified:
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Component.java
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/URL.java
struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java
struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java
struts/struts2/trunk/core/src/site/resources/tags/url.html
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java
Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Component.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Component.java?view=diff&rev=559127&r1=559126&r2=559127
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Component.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Component.java Tue Jul 24 10:33:38 2007
@@ -333,16 +333,19 @@
* @param scheme http or https
* @param includeContext should the context path be included or not
* @param encodeResult should the url be encoded
+ * @param forceAddSchemeHostAndPort should the scheme host and port be forced
+ * @param escapeAmp should ampersand (&) be escaped to &
* @return the action url.
*/
protected String determineActionURL(String action, String namespace, String method,
HttpServletRequest req, HttpServletResponse res, Map parameters, String scheme,
- boolean includeContext, boolean encodeResult) {
+ boolean includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort,
+ boolean escapeAmp) {
String finalAction = findString(action);
String finalNamespace = determineNamespace(namespace, getStack(), req);
ActionMapping mapping = new ActionMapping(finalAction, finalNamespace, method, parameters);
String uri = actionMapper.getUriFromActionMapping(mapping);
- return UrlHelper.buildUrl(uri, req, res, parameters, scheme, includeContext, encodeResult);
+ return UrlHelper.buildUrl(uri, req, res, parameters, scheme, includeContext, encodeResult, forceAddSchemeHostAndPort, escapeAmp);
}
/**
Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java?view=diff&rev=559127&r1=559126&r2=559127
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java Tue Jul 24 10:33:38 2007
@@ -1,3 +1,23 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
package org.apache.struts2.components;
import java.io.IOException;
@@ -29,7 +49,7 @@
String result;
if (urlComponent.value == null && urlComponent.action != null) {
- result = urlComponent.determineActionURL(urlComponent.action, urlComponent.namespace, urlComponent.method, urlComponent.req, urlComponent.res, urlComponent.parameters, scheme, urlComponent.includeContext, urlComponent.encode);
+ result = urlComponent.determineActionURL(urlComponent.action, urlComponent.namespace, urlComponent.method, urlComponent.req, urlComponent.res, urlComponent.parameters, scheme, urlComponent.includeContext, urlComponent.encode, false, urlComponent.escapeAmp);
} else {
String _value = urlComponent.value;
@@ -38,7 +58,7 @@
if (_value != null && _value.indexOf("?") > 0) {
_value = _value.substring(0, _value.indexOf("?"));
}
- result = UrlHelper.buildUrl(_value, urlComponent.req, urlComponent.res, urlComponent.parameters, scheme, urlComponent.includeContext, urlComponent.encode);
+ result = UrlHelper.buildUrl(_value, urlComponent.req, urlComponent.res, urlComponent.parameters, scheme, urlComponent.includeContext, urlComponent.encode, false, urlComponent.escapeAmp);
}
if ( urlComponent.anchor != null && urlComponent.anchor.length() > 0 ) {
result += '#' + urlComponent.anchor;
Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/URL.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/URL.java?view=diff&rev=559127&r1=559126&r2=559127
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/URL.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/URL.java Tue Jul 24 10:33:38 2007
@@ -20,7 +20,9 @@
*/
package org.apache.struts2.components;
-import java.io.IOException;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.ValueStack;
+
import java.io.Writer;
import java.util.Collections;
import java.util.Iterator;
@@ -32,16 +34,11 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.struts2.StrutsConstants;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
-import org.apache.struts2.StrutsException;
-import org.apache.struts2.StrutsConstants;
-import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.views.util.UrlHelper;
-import com.opensymphony.xwork2.inject.Inject;
-import com.opensymphony.xwork2.util.ValueStack;
-
/**
* <!-- START SNIPPET: javadoc -->
*
@@ -52,6 +49,12 @@
* an Iterable all the values will be added to the URL.</p>
*
* <b>NOTE:</b>
+ * <p>By default request parameters will be separated using escaped ampersands (i.e., &amp;).
+ * This is necessary for XHTML compliance, however, when using the URL generated by this tag
+ * with the <s:property> tag, the <b>escapeAmp</b> attribute should be used to disable
+ * ampersand escaping.</p>
+ *
+ * <b>NOTE:</b>
* <p>When includeParams is 'all' or 'get', the parameter defined in <param> tag will take
* precedence and will not be overriden if they exists in the parameter submitted. For
* example, in Example 3 below, if there is a id parameter in the url where the page this
@@ -67,16 +70,20 @@
* <ul>
* <li>action (String) - (value or action choose either one, if both exist value takes precedence) action's name (alias) <li>
* <li>value (String) - (value or action choose either one, if both exist value takes precedence) the url itself</li>
- * <li>scheme (String) - http scheme (http, https) default to the scheme this request is in</li>
+ * <li>scheme (String) - http scheme (http, https) defaults to the scheme this request is in</li>
* <li>namespace - action's namespace</li>
- * <li>method (String) - action's method, default to execute() </li>
- * <li>encode (Boolean) - url encode the generated url. Default is true</li>
- * <li>includeParams (String) - The includeParams attribute may have the value 'none', 'get' or 'all'. Default is 'get'.
+ * <li>method (String) - action's method name, defaults to 'execute'</li>
+ * <li>encode (Boolean) - url encode the generated url. Defaults to 'true'.</li>
+ * <li>includeParams (String) - The includeParams attribute may have the value 'none', 'get' or 'all'. Defaults to 'get'.
* none - include no parameters in the URL
* get - include only GET parameters in the URL (default)
* all - include both GET and POST parameters in the URL
* </li>
- * <li>includeContext (Boolean) - determine wheather to include the web app context path. Default is true.</li>
+ * <li>includeContext (Boolean) - Specifies whether to include the web app context path. Defaults to 'true'.</li>
+ * <li>escapeAmp (Boolean) - Specifies whether to escape ampersand (&) to (&amp;) or not. Defaults to 'true'.</li>
+ * <li>portletMode (String) - The resulting portlet mode.</li>
+ * <li>windowState (String) - The resulting portlet window state.</li>
+ * <li>portletUrlType (String) - Specifies if this should be a portlet render or action URL.</li>
* </ul>
*
* <!-- END SNIPPET: params -->
@@ -96,7 +103,7 @@
* </s:url>
*
* <-- Example 3-->
- * <s:url includeParams="get" >
+ * <s:url includeParams="get">
* <s:param name="id" value="%{'22'}" />
* </s:url>
*
@@ -134,6 +141,7 @@
protected String method;
protected boolean encode = true;
protected boolean includeContext = true;
+ protected boolean escapeAmp = true;
protected String portletMode;
protected String windowState;
protected String portletUrlType;
@@ -293,6 +301,11 @@
@StrutsTagAttribute(description="The anchor for this URL")
public void setAnchor(String anchor) {
this.anchor = anchor;
+ }
+
+ @StrutsTagAttribute(description="Specifies whether to escape ampersand (&) to (&amp;) or not", type="Boolean", defaultValue="true")
+ public void setEscapeAmp(boolean escapeAmp) {
+ this.escapeAmp = escapeAmp;
}
Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java?view=diff&rev=559127&r1=559126&r2=559127
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java Tue Jul 24 10:33:38 2007
@@ -44,6 +44,7 @@
protected String method;
protected String encode;
protected String includeContext;
+ protected String escapeAmp;
protected String portletMode;
protected String windowState;
protected String portletUrlType;
@@ -74,6 +75,9 @@
if (includeContext != null) {
url.setIncludeContext(Boolean.valueOf(includeContext).booleanValue());
}
+ if (escapeAmp != null) {
+ url.setEscapeAmp(Boolean.valueOf(escapeAmp).booleanValue());
+ }
}
public void setEncode(String encode) {
@@ -82,6 +86,10 @@
public void setIncludeContext(String includeContext) {
this.includeContext = includeContext;
+ }
+
+ public void setEscapeAmp(String escapeAmp) {
+ this.escapeAmp = escapeAmp;
}
public void setIncludeParams(String name) {
Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java?view=diff&rev=559127&r1=559126&r2=559127
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java Tue Jul 24 10:33:38 2007
@@ -18,7 +18,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.apache.struts2.views.util;
import java.io.UnsupportedEncodingException;
@@ -91,6 +90,10 @@
}
public static String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map params, String scheme, boolean includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort) {
+ return buildUrl(action, request, response, params, scheme, includeContext, encodeResult, forceAddSchemeHostAndPort, true);
+ }
+
+ public static String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map params, String scheme, boolean includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort, boolean escapeAmp) {
StringBuffer link = new StringBuffer();
boolean changedScheme = false;
@@ -169,7 +172,11 @@
}
//if the action was not explicitly set grab the params from the request
- buildParametersString(params, link);
+ if (escapeAmp) {
+ buildParametersString(params, link);
+ } else {
+ buildParametersString(params, link, "&");
+ }
String result;
Modified: struts/struts2/trunk/core/src/site/resources/tags/url.html
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/site/resources/tags/url.html?view=diff&rev=559127&r1=559126&r2=559127
==============================================================================
--- struts/struts2/trunk/core/src/site/resources/tags/url.html (original)
+++ struts/struts2/trunk/core/src/site/resources/tags/url.html Tue Jul 24 10:33:38 2007
@@ -33,7 +33,7 @@
<td align="left" valign="top"></td>
<td align="left" valign="top">true</td>
<td align="left" valign="top">String</td>
- <td align="left" valign="top">he action generate url for, if not using value</td>
+ <td align="left" valign="top">The action to generate the URL for, if not using value</td>
</tr>
<tr>
<td align="left" valign="top">anchor</td>
@@ -52,6 +52,14 @@
<td align="left" valign="top">Whether to encode parameters</td>
</tr>
<tr>
+ <td align="left" valign="top">escapeAmp</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">true</td>
+ <td align="left" valign="top">true</td>
+ <td align="left" valign="top">Boolean</td>
+ <td align="left" valign="top">Specifies whether to escape ampersand (&) to (&amp;) or not</td>
+ </tr>
+ <tr>
<td align="left" valign="top">id</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top"></td>
@@ -65,7 +73,7 @@
<td align="left" valign="top">true</td>
<td align="left" valign="top">true</td>
<td align="left" valign="top">Boolean</td>
- <td align="left" valign="top">Whether actual context should be included in url</td>
+ <td align="left" valign="top">Whether actual context should be included in URL</td>
</tr>
<tr>
<td align="left" valign="top">includeParams</td>
@@ -105,7 +113,7 @@
<td align="left" valign="top"></td>
<td align="left" valign="top">true</td>
<td align="left" valign="top">String</td>
- <td align="left" valign="top">Specifies if this should be a portlet render or action url</td>
+ <td align="left" valign="top">Specifies if this should be a portlet render or action URL</td>
</tr>
<tr>
<td align="left" valign="top">scheme</td>
Modified: struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java?view=diff&rev=559127&r1=559126&r2=559127
==============================================================================
--- struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java (original)
+++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java Tue Jul 24 10:33:38 2007
@@ -374,6 +374,19 @@
assertEquals("/team.action?section=team&company=acme+inc", writer.toString());
}
+ public void testRequestURIActionIncludeGetDoNotEscapeAmp() throws Exception {
+ request.setRequestURI("/public/about");
+ request.setQueryString("section=team&company=acme inc");
+
+ tag.setAction("team");
+ tag.setIncludeParams("get");
+ tag.setEscapeAmp("false");
+ tag.doStartTag();
+ tag.doEndTag();
+
+ assertEquals("/team.action?section=team&company=acme+inc", writer.toString());
+ }
+
public void testRequestURINoActionIncludeNone() throws Exception {
request.setRequestURI("/public/about");
request.setQueryString("section=team&company=acme inc");
Modified: struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java?view=diff&rev=559127&r1=559126&r2=559127
==============================================================================
--- struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java (original)
+++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java Tue Jul 24 10:33:38 2007
@@ -20,6 +20,8 @@
*/
package org.apache.struts2.views.util;
+import com.mockobjects.dynamic.Mock;
+
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -28,11 +30,8 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.struts2.StrutsConstants;
import org.apache.struts2.StrutsTestCase;
-import com.mockobjects.dynamic.Mock;
-
/**
* Test case for UrlHelper.
@@ -40,8 +39,6 @@
*/
public class UrlHelperTest extends StrutsTestCase {
-
-
public void testForceAddSchemeHostAndPort() throws Exception {
String expectedUrl = "http://localhost/contextPath/path1/path2/myAction.action";
@@ -142,6 +139,25 @@
params.put("foo", "bar");
String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params);
+ assertEquals(expectedString, urlString);
+ }
+
+ /**
+ * just one &, not &
+ */
+ public void testBuildUrlCorrectlyAddsDoNotEscapeAmp() {
+ String expectedString = "my.actionName?foo=bar&hello=world";
+ Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
+ mockHttpServletRequest.expectAndReturn("getScheme", "http");
+ Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
+ mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
+
+ String actionName = "my.actionName";
+ TreeMap params = new TreeMap();
+ params.put("hello", "world");
+ params.put("foo", "bar");
+
+ String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, null, true, true, false, false);
assertEquals(expectedString, urlString);
}