mirror of
https://github.com/apache/struts.git
synced 2026-08-06 07:06:58 +00:00
WW-1426
- URL Tag cause duplicates query string git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@438940 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -33,7 +33,9 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpUtils;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -157,9 +159,10 @@ public class URL extends Component {
|
||||
}
|
||||
|
||||
if (NONE.equalsIgnoreCase(includeParams)) {
|
||||
mergeRequestParameters(value, parameters, Collections.EMPTY_MAP);
|
||||
ActionContext.getContext().put(XWorkContinuationConfig.CONTINUE_KEY, null);
|
||||
} else if (ALL.equalsIgnoreCase(includeParams)) {
|
||||
mergeRequestParameters(parameters, req.getParameterMap());
|
||||
mergeRequestParameters(value, parameters, req.getParameterMap());
|
||||
|
||||
// for ALL also include GET parameters
|
||||
includeGetParameters();
|
||||
@@ -179,10 +182,7 @@ public class URL extends Component {
|
||||
private void includeGetParameters() {
|
||||
if(!(Dispatcher.getInstance().isPortletSupportActive() && PortletActionContext.isPortletRequest())) {
|
||||
String query = extractQueryString();
|
||||
if (query != null) {
|
||||
//mergeRequestParameters(parameters, HttpUtils.parseQueryString(query));
|
||||
mergeRequestParameters(parameters, UrlHelper.parseQueryString(query));
|
||||
}
|
||||
mergeRequestParameters(value, parameters, UrlHelper.parseQueryString(query));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,14 @@ public class URL extends Component {
|
||||
result = PortletUrlHelper.buildResourceUrl(value, parameters);
|
||||
}
|
||||
else {
|
||||
result = UrlHelper.buildUrl(value, req, res, parameters, scheme, includeContext, encode);
|
||||
String _value = value;
|
||||
|
||||
// We don't include the request parameters cause they would have been
|
||||
// prioritised before this [in start(Writer) method]
|
||||
if (_value != null && _value.indexOf("?") > 0) {
|
||||
_value = _value.substring(0, _value.indexOf("?"));
|
||||
}
|
||||
result = UrlHelper.buildUrl(_value, req, res, parameters, scheme, includeContext, encode);
|
||||
}
|
||||
}
|
||||
if ( anchor != null && anchor.length() > 0 ) {
|
||||
@@ -345,13 +352,52 @@ public class URL extends Component {
|
||||
|
||||
/**
|
||||
* Merge request parameters into current parameters. If a parameter is
|
||||
* already present, than the request parameter will not override its value.
|
||||
* already present, than the request parameter in the current request and value atrribute
|
||||
* will not override its value.
|
||||
*
|
||||
* The priority is as follows:-
|
||||
* <ul>
|
||||
* <li>parameter from the current request (least priority)</li>
|
||||
* <li>parameter form the value attribute (more priority)</li>
|
||||
* <li>parameter from the param tag (most priority)</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param value the value attribute (url to be generated by this component)
|
||||
* @param parameters component parameters
|
||||
* @param contextParameters request parameters
|
||||
*/
|
||||
protected void mergeRequestParameters(Map parameters, Map contextParameters){
|
||||
for (Iterator iterator = contextParameters.entrySet().iterator(); iterator.hasNext();) {
|
||||
protected void mergeRequestParameters(String value, Map parameters, Map contextParameters){
|
||||
|
||||
Map mergedParams = new LinkedHashMap(contextParameters);
|
||||
|
||||
// Merge contextParameters (from current request) with parameters specified in value attribute
|
||||
// eg. value="someAction.action?id=someId&venue=someVenue"
|
||||
// where the parameters specified in value attribute takes priority.
|
||||
|
||||
if (value != null && value.trim().length() > 0 && value.indexOf("?") > 0) {
|
||||
mergedParams = new LinkedHashMap();
|
||||
|
||||
String queryString = value.substring(value.indexOf("?")+1);
|
||||
|
||||
mergedParams = UrlHelper.parseQueryString(queryString);
|
||||
for (Iterator iterator = contextParameters.entrySet().iterator(); iterator.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) iterator.next();
|
||||
Object key = entry.getKey();
|
||||
|
||||
if (!mergedParams.containsKey(key)) {
|
||||
mergedParams.put(key, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Merge parameters specified in value attribute
|
||||
// eg. value="someAction.action?id=someId&venue=someVenue"
|
||||
// with parameters specified though param tag
|
||||
// eg. <param name="id" value="%{'someId'}" />
|
||||
// where parameters specified through param tag takes priority.
|
||||
|
||||
for (Iterator iterator = mergedParams.entrySet().iterator(); iterator.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) iterator.next();
|
||||
Object key = entry.getKey();
|
||||
|
||||
|
||||
@@ -267,18 +267,20 @@ public class UrlHelper {
|
||||
if (queryString != null) {
|
||||
String[] params = queryString.split("&");
|
||||
for (int a=0; a< params.length; a++) {
|
||||
String[] tmpParams = params[a].split("=");
|
||||
String paramName = null;
|
||||
String paramValue = "";
|
||||
if (tmpParams.length > 0) {
|
||||
paramName = tmpParams[0];
|
||||
}
|
||||
if (tmpParams.length > 1) {
|
||||
paramValue = tmpParams[1];
|
||||
}
|
||||
if (paramName != null) {
|
||||
String translatedParamValue = translateAndDecode(paramValue);
|
||||
queryParams.put(paramName, translatedParamValue);
|
||||
if (params[a].trim().length() > 0) {
|
||||
String[] tmpParams = params[a].split("=");
|
||||
String paramName = null;
|
||||
String paramValue = "";
|
||||
if (tmpParams.length > 0) {
|
||||
paramName = tmpParams[0];
|
||||
}
|
||||
if (tmpParams.length > 1) {
|
||||
paramValue = tmpParams[1];
|
||||
}
|
||||
if (paramName != null) {
|
||||
String translatedParamValue = translateAndDecode(paramValue);
|
||||
queryParams.put(paramName, translatedParamValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package org.apache.struts2.views.jsp;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.jsp.JspWriter;
|
||||
@@ -35,6 +36,151 @@ import com.opensymphony.xwork2.util.OgnlValueStack;
|
||||
public class URLTagTest extends AbstractUITagTest {
|
||||
|
||||
private URLTag tag;
|
||||
|
||||
|
||||
/**
|
||||
* To test priority of parameter passed in to url component though
|
||||
* various way
|
||||
* - current request url
|
||||
* - tag's value attribute
|
||||
* - tag's nested param tag
|
||||
*
|
||||
* id1
|
||||
* ===
|
||||
* - found in current request url
|
||||
* - found in tag's value attribute
|
||||
* - found in tag's param tag
|
||||
* CONCLUSION: tag's param tag takes precedence (paramId1)
|
||||
*
|
||||
* id2
|
||||
* ===
|
||||
* - found in current request url
|
||||
* - found in tag's value attribute
|
||||
* CONCLUSION: tag's value attribute take precedence (tagId2)
|
||||
*
|
||||
* urlParam1
|
||||
* =========
|
||||
* - found in current request url
|
||||
* CONCLUSION: param in current request url will be used (urlValue1)
|
||||
*
|
||||
* urlParam2
|
||||
* =========
|
||||
* - found in current request url
|
||||
* CONCLUSION: param in current request url will be used. (urlValue2)
|
||||
*
|
||||
* tagId
|
||||
* =====
|
||||
* - found in tag's value attribute
|
||||
* CONCLUSION: param in tag's value attribute wil; be used. (tagValue)
|
||||
*
|
||||
* param1
|
||||
* ======
|
||||
* - found in nested param tag
|
||||
* CONCLUSION: param in nested param tag will be used. (param1value)
|
||||
*
|
||||
* param2
|
||||
* ======
|
||||
* - found in nested param tag
|
||||
* CONCLUSION: param in nested param tag will be used. (param2value)
|
||||
*/
|
||||
public void testParametersPriority() throws Exception {
|
||||
request.setQueryString("id1=urlId1&id2=urlId2&urlParam1=urlValue1&urlParam2=urlValue2");
|
||||
|
||||
tag.setValue("testAction.action?id1=tagId1&id2=tagId2&tagId=tagValue");
|
||||
|
||||
ParamTag param1 = new ParamTag();
|
||||
param1.setPageContext(pageContext);
|
||||
param1.setName("param1");
|
||||
param1.setValue("%{'param1value'}");
|
||||
|
||||
ParamTag param2 = new ParamTag();
|
||||
param2.setPageContext(pageContext);
|
||||
param2.setName("param2");
|
||||
param2.setValue("%{'param2value'}");
|
||||
|
||||
ParamTag param3 = new ParamTag();
|
||||
param3.setPageContext(pageContext);
|
||||
param3.setName("id1");
|
||||
param3.setValue("%{'paramId1'}");
|
||||
|
||||
|
||||
tag.doStartTag();
|
||||
param1.doStartTag();
|
||||
param1.doEndTag();
|
||||
param2.doStartTag();
|
||||
param2.doEndTag();
|
||||
param3.doStartTag();
|
||||
param3.doEndTag();
|
||||
|
||||
URL url = (URL) tag.getComponent();
|
||||
Map parameters = url.getParameters();
|
||||
|
||||
|
||||
assertNotNull(parameters);
|
||||
assertEquals(parameters.size(), 7);
|
||||
assertEquals(parameters.get("id1"), "paramId1");
|
||||
assertEquals(parameters.get("id2"), "tagId2");
|
||||
assertEquals(parameters.get("urlParam1"), "urlValue1");
|
||||
assertEquals(parameters.get("urlParam2"), "urlValue2");
|
||||
assertEquals(parameters.get("tagId"), "tagValue");
|
||||
assertEquals(parameters.get("param1"), "param1value");
|
||||
assertEquals(parameters.get("param2"), "param2value");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* To test priority of parameter passed in to url component though
|
||||
* various way, with includeParams="NONE"
|
||||
* - current request url
|
||||
* - tag's value attribute
|
||||
* - tag's nested param tag
|
||||
*
|
||||
* In this case only parameters from the tag itself is taken into account.
|
||||
* Those from request will not count, only those in tag's value attribute
|
||||
* and nested param tag.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testParametersPriorityWithIncludeParamsAsNONE() throws Exception {
|
||||
request.setQueryString("id1=urlId1&id2=urlId2&urlParam1=urlValue1&urlParam2=urlValue2");
|
||||
|
||||
tag.setValue("testAction.action?id1=tagId1&id2=tagId2&tagId=tagValue");
|
||||
tag.setIncludeParams("NONE");
|
||||
|
||||
ParamTag param1 = new ParamTag();
|
||||
param1.setPageContext(pageContext);
|
||||
param1.setName("param1");
|
||||
param1.setValue("%{'param1value'}");
|
||||
|
||||
ParamTag param2 = new ParamTag();
|
||||
param2.setPageContext(pageContext);
|
||||
param2.setName("param2");
|
||||
param2.setValue("%{'param2value'}");
|
||||
|
||||
ParamTag param3 = new ParamTag();
|
||||
param3.setPageContext(pageContext);
|
||||
param3.setName("id1");
|
||||
param3.setValue("%{'paramId1'}");
|
||||
|
||||
|
||||
tag.doStartTag();
|
||||
param1.doStartTag();
|
||||
param1.doEndTag();
|
||||
param2.doStartTag();
|
||||
param2.doEndTag();
|
||||
param3.doStartTag();
|
||||
param3.doEndTag();
|
||||
|
||||
URL url = (URL) tag.getComponent();
|
||||
Map parameters = url.getParameters();
|
||||
|
||||
assertEquals(parameters.size(), 5);
|
||||
assertEquals(parameters.get("id1"), "paramId1");
|
||||
assertEquals(parameters.get("id2"), "tagId2");
|
||||
assertEquals(parameters.get("tagId"), "tagValue");
|
||||
assertEquals(parameters.get("param1"), "param1value");
|
||||
assertEquals(parameters.get("param2"), "param2value");
|
||||
}
|
||||
|
||||
public void testIncludeParamsDefaultToGET() throws Exception {
|
||||
request.setQueryString("one=oneVal&two=twoVal&three=threeVal");
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.apache.struts2.config.Settings;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
@@ -281,6 +282,21 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
assertEquals(result.get("ccc"), "");
|
||||
}
|
||||
|
||||
public void testParseEmptyQuery() throws Exception {
|
||||
Map result = UrlHelper.parseQueryString("");
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(result.size(), 0);
|
||||
}
|
||||
|
||||
public void testParseNullQuery() throws Exception {
|
||||
Map result = UrlHelper.parseQueryString(null);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(result.size(), 0);
|
||||
}
|
||||
|
||||
|
||||
public void testTranslateAndEncode() throws Exception {
|
||||
String defaultI18nEncoding = Settings.get(StrutsConstants.STRUTS_I18N_ENCODING);
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user