I am facing a problem that I couldn't find a key word for googleing the following situation:
<package name="Main" namespace="/" extends="struts-default">
<action name="administrator" class="com.xyz.AdminAction">
<result name="success">/WEB-INF/jsp/admin.jsp</result>
</action>
</package>
The above url should be http://xyz.com/administrator and it works fine. However, if I change the url to http://xyz.com/asdasd/asdasdasd/administrator and it still works, but I can't accept this! So any setting to tell struts only http://xyz.com/administrator is accepted? Thanks!
Set the alwaysSelectFullNamespace property to true.
From struts-default.properties:
### Whether to always select the namespace to be everything before the last slash or not
struts.mapper.alwaysSelectFullNamespace=true
XML configuration is preferred, so in your struts.xml:
<struts>
<constant name="struts.mapper.alwaysSelectFullNamespace" value="true" />
...
Related
I'm working with a Struts 2 webapp with the following action mapping:
<action name="something_*" class="foo.whatever.MyAction" method="{1}">
<result>blah/myJsp.jsp</result>
...
</action>
So if I load the URL /something_load.action, it calls to MyAction.load(), and so on. Piece of cake. What puzzles me is that loading /something.action does work too (I guess it's invoking the execute() method). How is it possible? My action mapping is supposed to match "something_", but there is no underescore in my URL. It should give me an error! Shouldn't it?
I've double checked that there isn't another mapping for "something.action" in the struts config files. I also checked the web.xml file, just in case...
The only explanation that I can imagine is that the underscore is ignored in Struts if I use wildcard mappings. But then it would make no difference to load /something_load.action, /some_thing_lo_ad.action... and that's not true.
I'm aware that this must be a very noobish question, but I've been unable to solve the mistery, neither looking through Stackoverflow questions nor the Struts documentation.
This is the main struts.xml file:
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="false" />
<constant name="struts.freemarker.templatesCache" value="true" />
<package name="default" extends="struts-default">
<!-- interceptors ... -->
<!-- global results for error pages -->
</package>
<!-- lots of includes -->
</struts>
It appears that wildcards are matched loosely in order to support some legacy syntax. So the issue isn't with underscore but with loose matching pattern.
From the javadocs:
Patterns can optionally be matched "loosely". When the end of the pattern matches \*[^*]\*$ (wildcard, no wildcard, wildcard), if the pattern fails, it is also matched as if the last two characters didn't exist. The goal is to support the legacy "*!*" syntax, where the "!*" is optional.
In struts2, is it possible to have an action name with a space?
I'm using the RegexPatternMatcher
<constant name="struts.patternMatcher" value="regex"/>
<constant name="struts.enable.SlashesInActionNames" value="true"/>
<constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>
My action is defined as
<action name="/users/{username}"
method="execute"
class="com.test.UserAction">
<result name="success" type="tiles">.test.user</result>
</action>
When I try a url like, http://localhost:8080/users/a%20space
The a%20space is set as aspace in the model. The %20 is not escaped and is just removed. I've also tried http://localhost:8080/users/a+space and the same thing happens.
Environment
Struts2 version, 2.3.15.1
You can allow spaces in action names by setting the parameter in the struts configuration,
struts.allowed.action.names
The default is
[a-zA-Z0-9._!/\-]*
The DefaultActionMapper uses this regex to validate the action name. If it doesn't match, it'll try to clean it up.
So modifying the setting to
<constant name="struts.allowed.action.names" value="[ a-zA-Z0-9._!/\-]*"/>
allows spaces
Assume I have this struts2 form
<s:form action="login" method="post">
<s:textfield key="login_name" name="login_name"/>
<s:submit></s:submit>
</s:form>
And also with this struts.xml setting
<constant name="struts.custom.i18n.resources" value="messageResource" />
<constant name="struts.devMode" value="true" />
<package name="login" namespace="/" extends="struts-default">
<action name="login" class="actions.index.index">
<interceptor-ref name="i18n"/>
<result name="LOGIN_SUCCESS">/Main.jsp</result>
<result name="LOGIN">/Login.jsp</result>
</action>
</package>
If I have added <interceptor-ref name="i18n"/> to the setting, login_name will have no value after form submitted; otherwise I can retrieve the value successfully.
If you want me to provide further detail, please just let me know. Thanks in advance!
You are adding only one interceptor for your action by doing so all other interceptors are not included. The default stack already includes i18n interceptor so no point to add it by yourself.
In struts2 I am writing an app where I need to make sure that the url redirection works the same whether or not there is a trailing slash at the end.
E.g. example.com/app should behave same way as if user entered example.com/app/. Currently I changed mapping in struts.xml like so -
<struts>
<package name="default" namespace="/" extends="secure">
<interceptors> ... <interceptors>
<action name="app">
<result type="redirectAction">/app/</result>
</action>
</package>
</struts>
and
<struts>
<package name="app" namespace="/app" extends="secure">
<interceptors> ... <interceptors>
<action name="" class="com.example.action.app.LoginAction" method="display">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<interceptor-ref name="basic" />
<result type="redirectAction">home</result>
<result name="display">/jsp/base/content/login/loginForm.jsp</result>
</action>
</package>
</struts>
But this seems hackish since if I go to example.com/app it will show example.com//app/.html in the URL.
Any help appreciated.
Answer was derived in comments under the answer.
Quaternion:
Personally I would write all my urls with out the trailing slash...
and then I would use something external to the application to rewrite
urls as appropriate, perhaps iptables could determine if there is a
trailing slash and if so always strip it.
Mohana Rao SV:
As suggested above follow without tailing slash. And override
StrutsPrepareAndExecuteFilter one of the filter job is from the url it
has to identify the namespace and action name and invoke respective
action. So here remove tailing slash from url.
Quaternion:
In namespace "/" you have an action called app. That is all there is
to it to invoke CONTEXT_ROOT/app (that is what struts2 expects), you
don't ever expect to see a "/" on the end of the url, so you want to
find a method that parses the url before struts2 resolves the mapping.
What you have described only requires something to remove a trailing
"/" if it exists. I'd look to iptables because I've used it before or
some other url rewriter... Mahana would keep it all part of the web
app and use a filter, methods differ but the effect is the same.
I am trying get Struts 2 and Tiles to work and I am using netbeans 7.1 as my IDE. Most of the examples are built on eclipse and I can seem to find a working example , So i tried to follow a tutorial And tried to get it sorted. Now I have the proeject runningwell and I can access individual tiles by url.
ie.
http://localhost:8088/sample2/example/body.jsp
But the action to mapping doesnt seem to work.
below are the files :
struts.xml = http://pastebin.com/5uWLSXWj
example.xml = http://pastebin.com/UQh68YNE
web.xml = http://pastebin.com/ZgVXfW1E
LinkAction.Java = http://pastebin.com/8cvKdmai
Appreciate any guidance , and links to netbeans and struts 2 example code.
<package name="example" namespace="/example" extends="struts-default">
Problem with Struts.xml file. You are loading two <package>s with same configuration.
Thats why one package is loading(with plain JSP result), and another is silently dropped (with Tiles results.) Try combining them into one, like this :
<struts>
<package name="example" namespace="/example" extends="struts-default">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
</result-types>
<action name="HelloWorld" class="example.HelloWorld">
<result>/example/HelloWorld.jsp</result>
</action>
<action name="Body" class="example.HelloWorld">
<result>/example/body.jsp</result>
</action>
<action name="*Link" method="{1}" class="example.LinkAction">
<result name="welcome" type="tiles">welcome</result>
<result name="friends" type="tiles">friends</result>
<result name="office" type="tiles">office</result>
</action>
</package>
</struts>