This is an automated email from the ASF dual-hosted git repository. mgrigorov pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/wicket.git
The following commit(s) were added to refs/heads/master by this push: new ad2dcd6 WICKET-6844 Add support for MethodMismatchResponse for Ajax behaviors ad2dcd6 is described below commit ad2dcd6b18c3792298f3b11947f79a7426f648de Author: Martin Tzvetanov Grigorov <mgrigo...@apache.org> AuthorDate: Mon Oct 19 21:54:59 2020 +0300 WICKET-6844 Add support for MethodMismatchResponse for Ajax behaviors --- .../wicket/ajax/AbstractDefaultAjaxBehavior.java | 33 +++++- .../form/AjaxFormComponentUpdatingBehavior.java | 13 +-- .../ajax/AbstractDefaultAjaxBehaviorTest.java | 119 ++++++++++++++++++++- 3 files changed, 151 insertions(+), 14 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 7da491b..2bad06b 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 @@ -33,6 +33,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; @@ -43,6 +44,10 @@ import org.apache.wicket.util.string.Strings; import com.github.openjson.JSONArray; import com.github.openjson.JSONException; import com.github.openjson.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; /** * The base class for Wicket's default AJAX implementation. @@ -54,9 +59,10 @@ import com.github.openjson.JSONObject; */ 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"); @@ -155,6 +161,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 @@ -590,6 +607,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 b9f3c5e..a658eb0 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 @@ -17,13 +17,22 @@ package org.apache.wicket.ajax; 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 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.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.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -32,7 +41,7 @@ import org.mockito.Mockito; * * @since 6.0 */ -class AbstractDefaultAjaxBehaviorTest +class AbstractDefaultAjaxBehaviorTest extends WicketTestCase { /** * Checks the generated JSON for Ajax's attributes @@ -90,4 +99,112 @@ class AbstractDefaultAjaxBehaviorTest assertEquals(expected, json); } + + @Test + 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 + 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 + 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()); + } }