Wildcard Action Mapping no longer working after updating to Struts 2.5
Asked Answered
Q

1

10

I have the following action mapping in my application's struts.xml, which was working just fine with Struts 2.3.28.1; calls to the /editApplication action where being handled by the x.ApplicationHandler.edit method.

<action name="*Application" class="x.ApplicationHandler" method="{1}">
    <result name="input">/WEB-INF/application.jsp</result>
    <result name="success" type="redirectAction">
        <param name="actionName">browseApps</param>
    </result>
</action>   

After upgrading to Struts 2.5, this no longer works. Attempting to call the /editApplication action shows the 404 error:

HTTP Status 404 - There is no Action mapped for namespace [/] and action name [editApplication]

I've reviewed the Struts 2.5 release notes, and don't see any mention of updates to the way wildcard based action mapping works. Is there any reason why this configuration no longer works?

Quixotic answered 13/5, 2016 at 20:21 Comment(3)
It's because of SMI as already explained by Aleksandr and it's do the fact that if method is not allowed an exception is thrown with missing method. I wonder if it would be better to throw exception with "This method is not allowed", wdyt?Lundy
Yes, a more meaningful exception might be very helpful here.Quixotic
I have registered an issue to cover this issues.apache.org/jira/browse/WW-4640Lundy
S
26

It is Strict Method Invocation and since Struts 2.5 it is enabled by default.

From the docs about SMI and wildcard mappings:

When using wildcard mapping in actions' definitions SMI works in two ways:

  • SMI is disabled - any wildcard will be substituted with the default RegEx, ie.: <action name="Person*" method="perform*"> will be translated into allowedMethod = "regex:perform([A-Za-z0-9_$]*)".
  • SMI is enabled - no wildcard substitution will happen, you must strictly define which methods can be accessed by annotations or <allowed-method/> tag.

You can disabled it per <package>.

<package strict-method-invocation="false">

OR you can add allowed methods names per action using <allowed-methods> tag.

<action name="*Application" class="x.ApplicationHandler" method="{1}">
    <result name="input">/WEB-INF/application.jsp</result>
    <result name="success" type="redirectAction">
        <param name="actionName">browseApps</param>
    </result>

    <allowed-methods>firstMethod, secondMethod, thirdMethod</allowed-methods>
</action>

OR add allowed methods names per package using <global-allowed-methods> tag.

<package extends="struts-default">

    <global-allowed-methods>firstMethod, secondMethod, thirdMethod</global-allowed-methods>

</package>

NOTE In order to use above tags in struts.xml you must update DTD definition to 2.5.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
...
</struts>

There is also @AllowedMethods annotation in struts2-convention-plugin which allows actions to specify allowed action methods.

This annotation can be used directly on Action classes or in the package-info.java class in order to specify global allowed methods for all sub-packages.

Spirochete answered 13/5, 2016 at 20:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.