You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2020/10/19 19:01:19 UTC

[wicket] branch wicket-8.x updated: WICKET-6844 Add support for MethodMismatchResponse for Ajax behaviors

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

mgrigorov pushed a commit to branch wicket-8.x
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/wicket-8.x by this push:
     new 2a622da  WICKET-6844 Add support for MethodMismatchResponse for Ajax behaviors
2a622da is described below

commit 2a622da42068429ac950eb6d8e0b3ee4c424cfde
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
AuthorDate: Mon Oct 19 21:54:59 2020 +0300

    WICKET-6844 Add support for MethodMismatchResponse for Ajax behaviors
    
    (cherry picked from commit ad2dcd6b18c3792298f3b11947f79a7426f648de)
---
 .../wicket/ajax/AbstractDefaultAjaxBehavior.java   |  33 +++++-
 .../form/AjaxFormComponentUpdatingBehavior.java    |  13 +--
 .../ajax/AbstractDefaultAjaxBehaviorTest.java      | 118 ++++++++++++++++++++-
 3 files changed, 149 insertions(+), 15 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java b/wicket-core/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java
index 1a4fd74..60d8b24 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java
@@ -36,6 +36,7 @@ import org.apache.wicket.behavior.AbstractAjaxBehavior;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.markup.html.IComponentAwareHeaderContributor;
+import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.protocol.http.WebApplication;
 import org.apache.wicket.request.Url;
 import org.apache.wicket.request.cycle.RequestCycle;
@@ -44,6 +45,10 @@ import org.apache.wicket.request.resource.ResourceReference;
 import org.apache.wicket.resource.CoreLibrariesContributor;
 import org.apache.wicket.util.string.Strings;
 import org.apache.wicket.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
 
 /**
  * The base class for Wicket's default AJAX implementation.
@@ -55,9 +60,10 @@ import org.apache.wicket.util.time.Duration;
  */
 public abstract class AbstractDefaultAjaxBehavior extends AbstractAjaxBehavior
 {
-
 	private static final long serialVersionUID = 1L;
 
+	private static final Logger LOG = LoggerFactory.getLogger(AbstractDefaultAjaxBehavior.class);
+
 	/** reference to the default indicator gif file. */
 	public static final ResourceReference INDICATOR = new PackageResourceReference(
 		AbstractDefaultAjaxBehavior.class, "indicator.gif");
@@ -156,6 +162,17 @@ public abstract class AbstractDefaultAjaxBehavior extends AbstractAjaxBehavior
 	}
 
 	/**
+	 * This method decides whether to continue processing or to abort the Ajax request when the method
+	 * is different than the {@link AjaxRequestAttributes#getMethod()}'s method.
+	 *
+	 * @return response that can either abort or continue the processing of the Ajax request
+	 */
+	protected Form.MethodMismatchResponse onMethodMismatch()
+	{
+		return Form.MethodMismatchResponse.CONTINUE;
+	}
+
+	/**
 	 * Gives a chance to the specializations to modify the attributes.
 	 * 
 	 * @param attributes
@@ -591,6 +608,20 @@ public abstract class AbstractDefaultAjaxBehavior extends AbstractAjaxBehavior
 	@Override
 	public final void onRequest()
 	{
+		Form.MethodMismatchResponse methodMismatch = onMethodMismatch();
+		if (methodMismatch == Form.MethodMismatchResponse.ABORT)
+		{
+			AjaxRequestAttributes attrs = getAttributes();
+			String desiredMethod = attrs.getMethod().toString();
+			String actualMethod = ((HttpServletRequest) RequestCycle.get().getRequest().getContainerRequest()).getMethod();
+			if (!desiredMethod.equalsIgnoreCase(actualMethod))
+			{
+				LOG.debug("Ignoring the Ajax request because its method '{}' is different than the expected one '{}",
+				          actualMethod, desiredMethod);
+				return;
+			}
+		}
+
 		WebApplication app = (WebApplication)getComponent().getApplication();
 		AjaxRequestTarget target = app.newAjaxRequestTarget(getComponent().getPage());
 
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
index 7d6eeab..e162048 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
@@ -55,9 +55,6 @@ public abstract class AjaxFormComponentUpdatingBehavior extends AjaxEventBehavio
 	private static final Logger log = LoggerFactory
 		.getLogger(AjaxFormComponentUpdatingBehavior.class);
 
-	/**
-	 * 
-	 */
 	private static final long serialVersionUID = 1L;
 
 	/**
@@ -71,10 +68,6 @@ public abstract class AjaxFormComponentUpdatingBehavior extends AjaxEventBehavio
 		super(event);
 	}
 
-	/**
-	 * 
-	 * @see org.apache.wicket.behavior.AbstractAjaxBehavior#onBind()
-	 */
 	@Override
 	protected void onBind()
 	{
@@ -129,10 +122,6 @@ public abstract class AjaxFormComponentUpdatingBehavior extends AjaxEventBehavio
 		attributes.setMethod(Method.POST);
 	}
 
-	/**
-	 * 
-	 * @see org.apache.wicket.ajax.AjaxEventBehavior#onEvent(org.apache.wicket.ajax.AjaxRequestTarget)
-	 */
 	@Override
 	protected final void onEvent(final AjaxRequestTarget target)
 	{
@@ -251,4 +240,4 @@ public abstract class AjaxFormComponentUpdatingBehavior extends AjaxEventBehavio
 			}
 		};
 	}
-}
\ No newline at end of file
+}
diff --git a/wicket-core/src/test/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehaviorTest.java b/wicket-core/src/test/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehaviorTest.java
index 539b495..a4cef7b 100644
--- a/wicket-core/src/test/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehaviorTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehaviorTest.java
@@ -15,15 +15,21 @@
  * limitations under the License.
  */
 package org.apache.wicket.ajax;
-
 import java.util.Locale;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.wicket.Component;
+import org.apache.wicket.MockPageWithLink;
+import org.apache.wicket.MockPageWithOneComponent;
 import org.apache.wicket.ajax.attributes.AjaxAttributeName;
 import org.apache.wicket.ajax.attributes.AjaxCallListener;
 import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
 import org.junit.Assert;
 import org.junit.Test;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.util.tester.WicketTestCase;
 import org.mockito.Mockito;
 
 /**
@@ -31,7 +37,7 @@ import org.mockito.Mockito;
  * 
  * @since 6.0
  */
-public class AbstractDefaultAjaxBehaviorTest extends Assert
+public class AbstractDefaultAjaxBehaviorTest extends WicketTestCase
 {
 	/**
 	 * Checks the generated JSON for Ajax's attributes
@@ -89,4 +95,112 @@ public class AbstractDefaultAjaxBehaviorTest extends Assert
 
 		assertEquals(expected, json);
 	}
+
+	@Test
+	public void onMethodMismatch_whenAbortAndMethodsDiffer_thenDoNotProcess()
+	{
+		AtomicBoolean respondMethodCalled = new AtomicBoolean(false);
+		MockPageWithOneComponent page = new MockPageWithOneComponent();
+		Label component = new Label(MockPageWithOneComponent.COMPONENT_ID, "");
+		page.add(component);
+
+		AbstractDefaultAjaxBehavior behavior = new AbstractDefaultAjaxBehavior()
+		{
+			@Override
+			protected void respond(AjaxRequestTarget target)
+			{
+				respondMethodCalled.set(true);
+			}
+
+			@Override
+			protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+				super.updateAjaxAttributes(attributes);
+				attributes.setMethod(AjaxRequestAttributes.Method.GET);
+			}
+
+			@Override
+			protected Form.MethodMismatchResponse onMethodMismatch() {
+				return Form.MethodMismatchResponse.ABORT;
+			}
+		};
+		component.add(behavior);
+
+		tester.startPage(page);
+		tester.getRequest().setMethod(Form.METHOD_POST);
+		tester.executeBehavior(behavior);
+
+		assertFalse(respondMethodCalled.get());
+	}
+
+	@Test
+	public void onMethodMismatch_whenAbortAndMethodsSame_thenProcess()
+	{
+		AtomicBoolean respondMethodCalled = new AtomicBoolean(false);
+		MockPageWithOneComponent page = new MockPageWithOneComponent();
+		Label component = new Label(MockPageWithOneComponent.COMPONENT_ID, "");
+		page.add(component);
+
+		AbstractDefaultAjaxBehavior behavior = new AbstractDefaultAjaxBehavior()
+		{
+			@Override
+			protected void respond(AjaxRequestTarget target)
+			{
+				respondMethodCalled.set(true);
+			}
+
+			@Override
+			protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+				super.updateAjaxAttributes(attributes);
+				attributes.setMethod(AjaxRequestAttributes.Method.GET);
+			}
+
+			@Override
+			protected Form.MethodMismatchResponse onMethodMismatch() {
+				return Form.MethodMismatchResponse.ABORT;
+			}
+		};
+		component.add(behavior);
+
+		tester.startPage(page);
+		tester.getRequest().setMethod(Form.METHOD_GET);
+		tester.executeBehavior(behavior);
+
+		assertTrue(respondMethodCalled.get());
+	}
+
+	@Test
+	public void onMethodMismatch_whenContinueAndMethodsDiffer_thenProcess()
+	{
+		AtomicBoolean respondMethodCalled = new AtomicBoolean(false);
+		MockPageWithOneComponent page = new MockPageWithOneComponent();
+		Label component = new Label(MockPageWithOneComponent.COMPONENT_ID, "");
+		page.add(component);
+
+		AbstractDefaultAjaxBehavior behavior = new AbstractDefaultAjaxBehavior()
+		{
+			@Override
+			protected void respond(AjaxRequestTarget target)
+			{
+				respondMethodCalled.set(true);
+			}
+
+			@Override
+			protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+				super.updateAjaxAttributes(attributes);
+				attributes.setMethod(AjaxRequestAttributes.Method.GET);
+			}
+
+			@Override
+			protected Form.MethodMismatchResponse onMethodMismatch() {
+				return Form.MethodMismatchResponse.CONTINUE;
+			}
+		};
+		component.add(behavior);
+
+		tester.startPage(page);
+		tester.getRequest().setMethod(Form.METHOD_POST);
+		tester.executeBehavior(behavior);
+
+		assertTrue(respondMethodCalled.get());
+	}
 }