4

I'm currently playing around with my Struts2 config for wildcard testing and I'm stuck with this one.

    <action name="/*/*" class="checkBlogUrl" method="testing">
        <param name="blogSiteUrl">{1}</param>
        <param name="test">{2}</param>
        <result name="success">/WEB-INF/jsp/cmsPages/index.jsp</result>
    </action>
    
    <action name="/*/postPreview1" class="blogPostAction" method="test">
        <param name="blogSiteUrl">{1}</param>
        <result name="success">/WEB-INF/jsp/cmsPages/templatePicker.jsp</result>
    </action>

If I access myurl.com/hello/hi I will be redirected to index.jsp.

But if I access myurl.com/hello/postPreview1 I will also be redirected to index.jsp instead of templatePicker.jsp.

Am I doing something wrong here? The struts wildcard doc said that the last one will win

EDIT:

Just tried to switch them around and it worked! Am I misreading the doc?

Roman C
  • 49,761
  • 33
  • 66
  • 176
Jiro Manio
  • 137
  • 10

2 Answers2

4

You are using slashes in action name, that incorrectly works with wildcard mapper. As I said in the linked answer, the best pattern matcher in this case is the regex pattern matcher.

<constant name="struts.patternMatcher" value="regex"/>

See Advanced Wildcards.

<action name="/{blogSiteUrl}/{test}" class="checkBlogUrl" method="testing">
    <result name="success">/WEB-INF/jsp/cmsPages/index.jsp</result>
</action>

<action name="/{blogSiteUrl}/postPreview1" class="blogPostAction" method="test">
    <result name="success">/WEB-INF/jsp/cmsPages/templatePicker.jsp</result>
</action>

About docs for wildcard mapper. Lets look at the example blank application:

<package name="example" namespace="/example" extends="default">

    <action name="HelloWorld" class="example.HelloWorld">
        <result>/WEB-INF/jsp/example/HelloWorld.jsp</result>
    </action>

    <action name="Login_*" method="{1}" class="example.Login">
        <result name="input">/WEB-INF/jsp/example/Login.jsp</result>
        <result type="redirectAction">Menu</result>
    </action>

    <action name="*" class="example.ExampleSupport">
        <result>/WEB-INF/jsp/example/{1}.jsp</result>
    </action>

    <!-- Add actions here -->
</package>

So URLs will be matched in the order:

  1. http://localhost:8080/example/HelloWorld
  2. http://localhost:8080/example/Login_input
  3. http://localhost:8080/example/Register

I would say that more specific mapping goes before less specific/common mapping and it wins because it's found first in the order of action configs. Everything that doesn't match the ordered configs fall into last mapping which is less specific.

Roman C
  • 49,761
  • 33
  • 66
  • 176
  • Hello, can you add an example how annotation approach will looks like in this case? – Maksim Kostromin Nov 10 '18 at 22:36
  • ` ` I have this in my struts.xml, along with the xml tag for patternMatcher with the value of regex. But I get the error `There is no Action mapped for action name 2` when I access using the URL `http://localhost:8080/wildcard_sample/2/hello/3.json`. I am using `Struts 2.5.29`. @Roman C – Kavin Raju S Feb 09 '22 at 02:23
0

In your case,from the official docs,

Mappings are matched against the request in the order they appear in the framework’s configuration file. If more than one pattern matches the last one wins, so less specific patterns must appear before more specific ones. However, if the request URL can be matched against a path without any wildcards in it, no wildcard matching is performed and order is not important.

https://struts.apache.org/core-developers/wildcard-mappings.html#wildcards

Kavin Raju S
  • 1,214
  • 2
  • 17
  • 25