diff --git a/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java b/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java
index 4d73813eeb..6bc28ed252 100644
--- a/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java
+++ b/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java
@@ -168,8 +168,8 @@ private void resolveMethod() {
this.method = config.getMethodName();
if (StringUtils.isEmpty(this.method)) {
this.method = ActionConfig.DEFAULT_METHOD;
+ methodSpecified = false;
}
- methodSpecified = false;
}
}
diff --git a/core/src/main/java/org/apache/struts2/ActionProxy.java b/core/src/main/java/org/apache/struts2/ActionProxy.java
index d5e19e44da..ad800d4063 100644
--- a/core/src/main/java/org/apache/struts2/ActionProxy.java
+++ b/core/src/main/java/org/apache/struts2/ActionProxy.java
@@ -93,9 +93,11 @@ public interface ActionProxy {
String getMethod();
/**
- * Gets status of the method value's initialization.
+ * Gets status of the method value's initialization. Returns {@code true} when the method was explicitly provided
+ * (e.g. via URL parameter, wildcard substitution, or action configuration), and {@code false} only when the
+ * framework defaults to {@code "execute"} because no method was specified anywhere.
*
- * @return true if the method returned by getMethod() is not a default initializer value.
+ * @return true if the method returned by getMethod() is not the default "execute" fallback.
*/
boolean isMethodSpecified();
diff --git a/core/src/test/java/com/opensymphony/xwork2/DefaultActionProxyTest.java b/core/src/test/java/com/opensymphony/xwork2/DefaultActionProxyTest.java
index 125c5b4bd6..5db2f68cf8 100644
--- a/core/src/test/java/com/opensymphony/xwork2/DefaultActionProxyTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/DefaultActionProxyTest.java
@@ -18,15 +18,14 @@
*/
package com.opensymphony.xwork2;
+import com.opensymphony.xwork2.config.ConfigurationException;
import com.opensymphony.xwork2.mock.MockActionInvocation;
import org.apache.struts2.StrutsInternalTestCase;
import org.apache.struts2.config.StrutsXmlConfigurationProvider;
-import org.junit.Test;
public class DefaultActionProxyTest extends StrutsInternalTestCase {
- @Test
- public void testThorwExceptionOnNotAllowedMethod() throws Exception {
+ public void testThrowExceptionOnNotAllowedMethod() {
final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml";
loadConfigurationProviders(new StrutsXmlConfigurationProvider(filename));
DefaultActionProxy dap = new DefaultActionProxy(new MockActionInvocation(), "strict", "Default", "notAllowed", true, true);
@@ -35,8 +34,52 @@ public void testThorwExceptionOnNotAllowedMethod() throws Exception {
try {
dap.prepare();
fail("Must throw exception!");
- } catch (Exception e) {
- assertEquals(e.getMessage(), "Method notAllowed for action Default is not allowed!");
+ } catch (ConfigurationException e) {
+ assertEquals("Method notAllowed for action Default is not allowed!", e.getMessage());
}
}
+
+ public void testMethodSpecifiedWhenPassedExplicitly() {
+ final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml";
+ loadConfigurationProviders(new StrutsXmlConfigurationProvider(filename));
+ DefaultActionProxy dap = new DefaultActionProxy(new MockActionInvocation(), "", "NoMethod", "onPostOnly", true, true);
+ container.inject(dap);
+ dap.prepare();
+
+ assertTrue("Method passed explicitly should be marked as specified", dap.isMethodSpecified());
+ assertEquals("onPostOnly", dap.getMethod());
+ }
+
+ public void testMethodSpecifiedWhenResolvedFromConfig() {
+ final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml";
+ loadConfigurationProviders(new StrutsXmlConfigurationProvider(filename));
+ DefaultActionProxy dap = new DefaultActionProxy(new MockActionInvocation(), "", "ConfigMethod", null, true, true);
+ container.inject(dap);
+ dap.prepare();
+
+ assertTrue("Method resolved from action config should be marked as specified", dap.isMethodSpecified());
+ assertEquals("onPostOnly", dap.getMethod());
+ }
+
+ public void testMethodNotSpecifiedWhenDefaultingToExecute() {
+ final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml";
+ loadConfigurationProviders(new StrutsXmlConfigurationProvider(filename));
+ DefaultActionProxy dap = new DefaultActionProxy(new MockActionInvocation(), "", "NoMethod", null, true, true);
+ container.inject(dap);
+ dap.prepare();
+
+ assertFalse("Method defaulting to execute should not be marked as specified", dap.isMethodSpecified());
+ assertEquals("execute", dap.getMethod());
+ }
+
+ public void testMethodSpecifiedWithWildcardAction() {
+ final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml";
+ loadConfigurationProviders(new StrutsXmlConfigurationProvider(filename));
+ DefaultActionProxy dap = new DefaultActionProxy(new MockActionInvocation(), "", "Wild-onPostOnly", null, true, true);
+ container.inject(dap);
+ dap.prepare();
+
+ assertTrue("Method resolved from wildcard should be marked as specified", dap.isMethodSpecified());
+ assertEquals("onPostOnly", dap.getMethod());
+ }
}
\ No newline at end of file
diff --git a/core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderAllowedMethodsTest.java b/core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderAllowedMethodsTest.java
index 1ac2315bc4..00604757d5 100644
--- a/core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderAllowedMethodsTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderAllowedMethodsTest.java
@@ -42,7 +42,7 @@ public void testDefaultAllowedMethods() throws ConfigurationException {
Map actionConfigs = pkg.getActionConfigs();
// assertions
- assertEquals(5, actionConfigs.size());
+ assertEquals(8, actionConfigs.size());
ActionConfig action = (ActionConfig) actionConfigs.get("Default");
assertEquals(1, action.getAllowedMethods().size());
diff --git a/core/src/test/java/org/apache/struts2/interceptor/httpmethod/HttpMethodInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/httpmethod/HttpMethodInterceptorTest.java
index 98e78c3fa5..f68b01df3f 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/httpmethod/HttpMethodInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/httpmethod/HttpMethodInterceptorTest.java
@@ -217,6 +217,43 @@ public void testPostOnPutOrPostMethod() throws Exception {
assertEquals(HttpMethod.POST, action.getHttpMethod());
}
+ public void testWildcardResolvedMethodWithPostAnnotationRejectsGet() throws Exception {
+ // given
+ HttpMethodsTestAction action = new HttpMethodsTestAction();
+ prepareActionInvocation(action);
+ actionProxy.setMethod("onPostOnly");
+ actionProxy.setMethodSpecified(true);
+
+ invocation.setResultCode("onPostOnly");
+
+ prepareRequest("GET");
+
+ // when
+ String resultName = interceptor.intercept(invocation);
+
+ // then
+ assertEquals("bad-request", resultName);
+ }
+
+ public void testWildcardResolvedMethodWithPostAnnotationAllowsPost() throws Exception {
+ // given
+ HttpMethodsTestAction action = new HttpMethodsTestAction();
+ prepareActionInvocation(action);
+ actionProxy.setMethod("onPostOnly");
+ actionProxy.setMethodSpecified(true);
+
+ invocation.setResultCode("onPostOnly");
+
+ prepareRequest("POST");
+
+ // when
+ String resultName = interceptor.intercept(invocation);
+
+ // then
+ assertEquals("onPostOnly", resultName);
+ assertEquals(HttpMethod.POST, action.getHttpMethod());
+ }
+
private void prepareActionInvocation(Object action) {
interceptor = new HttpMethodInterceptor();
invocation = new MockActionInvocation();
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml
index 247b4ef271..0c78ff5cf9 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml
@@ -29,7 +29,7 @@
-
+
@@ -43,6 +43,18 @@
foo,bar
+
+
+ regex:.*
+
+
+
+ regex:.*
+
+
+
+ regex:.*
+