You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2020/08/06 20:18:12 UTC

[wicket] 01/02: WICKET-6807 find submitter according to form's method only

This is an automated email from the ASF dual-hosted git repository.

svenmeier pushed a commit to branch WICKET-6807_js_submitter_always_via_hidden_field
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit b6dfed19bb1a6cdad65b528ce707fd8eb62e4b6a
Author: Sven Meier <sv...@apache.org>
AuthorDate: Thu Aug 6 21:29:53 2020 +0200

    WICKET-6807 find submitter according to form's method only
---
 .../org/apache/wicket/markup/html/form/Form.java   | 92 ++++++++++++++++------
 .../wicket/markup/html/form/FormComponent.java     | 32 +-------
 .../wicket/stateless/StatelessFormUrlTest.java     | 14 +++-
 3 files changed, 78 insertions(+), 60 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
index 35be666..3116c1c 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
@@ -50,8 +50,10 @@ import org.apache.wicket.model.Model;
 import org.apache.wicket.protocol.http.servlet.MultipartServletWebRequest;
 import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
 import org.apache.wicket.request.IRequestParameters;
+import org.apache.wicket.request.Request;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.parameter.EmptyRequestParameters;
 import org.apache.wicket.util.encoding.UrlDecoder;
 import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.lang.Bytes;
@@ -447,6 +449,8 @@ public class Form<T> extends WebMarkupContainer
 	 */
 	public final IFormSubmittingComponent findSubmitter()
 	{
+		final IRequestParameters parameters = getRequestParameters(this);
+
 		IFormSubmittingComponent submittingComponent = getPage().visitChildren(
 			IFormSubmittingComponent.class, new IVisitor<Component, IFormSubmittingComponent>()
 			{
@@ -462,7 +466,6 @@ public class Form<T> extends WebMarkupContainer
 					if ((form != null) && (form.getRootForm() == Form.this))
 					{
 						String name = submittingComponent.getInputName();
-						IRequestParameters parameters = getRequest().getRequestParameters();
 						if ((!parameters.getParameterValue(name).isNull()) ||
 							!parameters.getParameterValue(name + ".x").isNull())
 						{
@@ -581,20 +584,11 @@ public class Form<T> extends WebMarkupContainer
 
 		AppendingStringBuffer buffer = new AppendingStringBuffer();
 		buffer.append(String.format("var f = document.getElementById('%s');", root.getMarkupId()));
-		if (root.encodeUrlInHiddenFields())
-		{
-			buffer.append(String.format("document.getElementById('%s').innerHTML += '",
-				root.getHiddenFieldsId(HIDDEN_FIELDS_PARAMS_IDX)));
-			
-			writeParamsAsHiddenFields(new String[] {param}, buffer);
-			
-			buffer.append("';");
-		}
-		else
-		{
-			String action = root.getActionUrl().toString();
-			buffer.append("f.action += '" + (action.indexOf('?') > -1 ? '&' : '?') + param + "';");
-		}
+		buffer.append(String.format("document.getElementById('%s').innerHTML += '",
+			root.getHiddenFieldsId(HIDDEN_FIELDS_PARAMS_IDX)));
+		writeParamsAsHiddenFields(new String[] {param}, buffer);
+		buffer.append("';");
+
 		if (triggerEvent)
 		{
 			buffer.append("Wicket.Event.fire(f, 'submit');");
@@ -1717,9 +1711,15 @@ public class Form<T> extends WebMarkupContainer
 	}
 
 	/**
-	 * Should URL query parameters be encoded in hidden fields.
+	 * Should URL query parameters be encoded in hidden fields, by default <code>true</code>
+	 * for {@link #METHOD_GET} only.
+	 * <p>
+	 * In that case, the parameters must <em>not</em> be written as query parameters, as the browser
+	 * would strip them from the action url before appending the form values.
 	 *
 	 * @return true if form's method is 'get'
+	 * 
+	 * @see #getMethod()
 	 */
 	protected boolean encodeUrlInHiddenFields()
 	{
@@ -1764,14 +1764,12 @@ public class Form<T> extends WebMarkupContainer
 	 */
 	public final void writeHiddenFields()
 	{
-		// if it's a get, did put the parameters in the action attribute,
-		// and have to write the url parameters as hidden fields
+		getResponse().write(String.format("<div id=\"%s\" hidden=\"\" class=\"%s\">",
+			getHiddenFieldsId(HIDDEN_FIELDS_PARAMS_IDX),
+			getString(HIDDEN_FIELDS_CSS_CLASS_KEY)));
+		// if the parameters are not in the action attribute, they have to be written as hidden fields
 		if (encodeUrlInHiddenFields())
 		{
-			getResponse().write(String.format("<div id=\"%s\" hidden=\"\" class=\"%s\">",
-				getHiddenFieldsId(HIDDEN_FIELDS_PARAMS_IDX),
-				getString(HIDDEN_FIELDS_CSS_CLASS_KEY)));
-
 			AppendingStringBuffer buffer = new AppendingStringBuffer();				
 
 			String url = getActionUrl().toString();
@@ -1782,10 +1780,9 @@ public class Form<T> extends WebMarkupContainer
 			writeParamsAsHiddenFields(params, buffer);
 
 			getResponse().write(buffer);
-			
-			getResponse().write("</div>");
 		}
-
+		getResponse().write("</div>");
+		
 		// if a default submitting component was set, handle the rendering of that
 		if (hasDefaultSubmittingComponent())
 		{
@@ -2186,6 +2183,51 @@ public class Form<T> extends WebMarkupContainer
 	}
 
 	/**
+	 * Get the request parameters for a form submit,
+	 * according to the request's method or the form's method as fallback.
+	 *  
+	 * @param component any component inside the form or the form itself
+	 * @return parameters
+	 */
+	static IRequestParameters getRequestParameters(Component component) {
+		String method = Form.METHOD_POST;
+		final Request request = component.getRequest();
+		if (request.getContainerRequest() instanceof HttpServletRequest)
+		{
+			method = ((HttpServletRequest)request.getContainerRequest()).getMethod();
+		}
+		else
+		{
+			final Form<?> form;
+			if (component instanceof Form) {
+				form = (Form<?>)component;
+			} else {
+				form = component.findParent(Form.class);
+			}
+			
+			if (form != null)
+			{
+				method = form.getMethod();
+			}
+		}
+
+		final IRequestParameters parameters;
+		switch (method.toLowerCase(Locale.ROOT))
+		{
+			case Form.METHOD_POST:
+				parameters = request.getPostParameters();
+				break;
+			case Form.METHOD_GET:
+				parameters = request.getQueryParameters();
+				break;
+			default:
+				parameters = EmptyRequestParameters.INSTANCE;
+		}
+
+		return parameters;
+	}
+
+	/**
 	 * Response when a submission method mismatch is detected
 	 * 
 	 * @see Form#getMethod()
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
index 9c283d7..6ba10e9 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
@@ -31,8 +31,6 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
-import javax.servlet.http.HttpServletRequest;
-
 import org.apache.wicket.Application;
 import org.apache.wicket.Component;
 import org.apache.wicket.IConverterLocator;
@@ -49,8 +47,6 @@ import org.apache.wicket.model.IObjectClassAwareModel;
 import org.apache.wicket.model.IPropertyReflectionAwareModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.request.IRequestParameters;
-import org.apache.wicket.request.Request;
-import org.apache.wicket.request.parameter.EmptyRequestParameters;
 import org.apache.wicket.util.convert.ConversionException;
 import org.apache.wicket.util.convert.IConverter;
 import org.apache.wicket.util.lang.Args;
@@ -798,33 +794,7 @@ public abstract class FormComponent<T> extends LabeledWebMarkupContainer impleme
 	 */
 	protected List<StringValue> getParameterValues(String inputName)
 	{
-		String method = Form.METHOD_POST;
-		final Request request = getRequest();
-		if (getRequest().getContainerRequest() instanceof HttpServletRequest)
-		{
-			method = ((HttpServletRequest)getRequest().getContainerRequest()).getMethod();
-		}
-		else
-		{
-			final Form<?> form = findParent(Form.class);
-			if (form != null)
-			{
-				method = form.getMethod();
-			}
-		}
-
-		final IRequestParameters parameters;
-		switch (method.toLowerCase(Locale.ROOT))
-		{
-			case Form.METHOD_POST:
-				parameters = request.getPostParameters();
-				break;
-			case Form.METHOD_GET:
-				parameters = request.getQueryParameters();
-				break;
-			default:
-				parameters = EmptyRequestParameters.INSTANCE;
-		}
+		final IRequestParameters parameters = Form.getRequestParameters(this);
 
 		return parameters.getParameterValues(inputName);
 	}
diff --git a/wicket-core/src/test/java/org/apache/wicket/stateless/StatelessFormUrlTest.java b/wicket-core/src/test/java/org/apache/wicket/stateless/StatelessFormUrlTest.java
index ef30976..73d79e3 100644
--- a/wicket-core/src/test/java/org/apache/wicket/stateless/StatelessFormUrlTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/stateless/StatelessFormUrlTest.java
@@ -17,7 +17,7 @@
 package org.apache.wicket.stateless;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.Page;
@@ -58,7 +58,10 @@ class StatelessFormUrlTest extends WicketTestCase
 	@Test
 	void submitLinkInputNameNotEncodedIntoFormAction()
 	{
-		tester.executeUrl("?0-1.IFormSubmitListener-form&text=newValue&submitLink=x");
+		tester.getRequest().getPostParameters().setParameterValue("text", "newValue");
+		tester.getRequest().getPostParameters().setParameterValue("submitLink", "x");
+		tester.executeUrl("?0-1.-form");
+		assertEquals("newValue", tester.getTagById("text3").getAttribute("value"));
 		assertEquals("./?-1.-form", tester.getTagById("form1").getAttribute("action"));
 	}
 
@@ -68,8 +71,10 @@ class StatelessFormUrlTest extends WicketTestCase
 	@Test
 	void formComponentNameNotEncodedIntoFormAction()
 	{
-		tester.executeUrl("?0-1.IFormSubmitListener-form&text=newValue");
-		assertFalse(tester.getLastResponseAsString().contains("text=newValue"));
+		tester.getRequest().getPostParameters().setParameterValue("text", "newValue");
+		tester.executeUrl("?0-1.-form");
+		assertEquals("newValue", tester.getTagById("text3").getAttribute("value"));
+		assertEquals("./?-1.-form", tester.getTagById("form1").getAttribute("action"));
 	}
 
 	/** */
@@ -87,6 +92,7 @@ class StatelessFormUrlTest extends WicketTestCase
 			StatelessForm<Void> form = new StatelessForm<>("form");
 			add(form);
 			TextField<String> textField = new TextField<>("text", Model.of("textValue"));
+			textField.setOutputMarkupId(true);
 			form.add(textField);
 			SubmitLink submitLink = new SubmitLink("submitLink");
 			form.add(submitLink);