Is prefix needed for Struts2 namespace in forms and links? - java

From the Apache documentation:
While the prefix appears in the browser URI, the tags are "namespace
aware", so the namespace prefix does not need to be embedded in forms
and links.
struts.xml:
<package name="testpkg" namespace="/test" extends="struts-default">
<action name="doTest" class="otes.test.TestAction">
<result>/success.jsp</result>
</action>
</package>
index.jsp: (http://localhost:8080/nsdemo/)
<h2>Using HTML tags:</h2>
<h3>doTest without namespace</h3> <!-- 404 error -->
<h3>doTest with namespace</h3> <!-- works -->
<h2>Using Struts2 tags:</h2>
<h3><s:a href="doTest">doTest without namespace (s:a href)</s:a></h3> <!-- 404 error -->
<h3><s:a href="test/doTest">doTest with namespace (s:a href)</s:a></h3> <!-- works -->
<!-- 404 error -->
<s:url action="doTest" var="myAction" />
<h3><s:a href="%{myAction}">doTest without namespace (s:url action)</s:a></h3>
<!-- works -->
<s:url action="test/doTest" var="myAction" />
<h3><s:a href="%{myAction}">doTest with namespace (s:url action)</s:a></h3>
Does this mean I really have to specify the namespace in my forms and links?
(I am using Struts 2.3.20 if that matters.)

First of all: the tags referred in the docs are Struts2 tags (e.g. <s:url>, <s:a>).
And namespace aware means that if you already executed some action in particular namespace then in the JSP you don't need to prefix S2 links and forms with the current namespace.
E.g. if you have this package configuration:
<package name="testpkg" namespace="/test" extends="struts-default">
<action name="index">/index.jsp</action>
<action name="doTest" class="otes.test.TestAction">
<result>/success.jsp</result>
</action>
</package>
and executed the index action (http://localhost/app/test/index.action). Then in index.jsp you can write
<s:a action="doTest">test</s:a>
and that url will take you to the same namespace.
If you want to change namespace there is namespace attribute in some tags that you can use.
E.g. you are in some page (http://localhost/app/index.action) - note no namespace in url, then following link will execute doTest in /test namespace.
<s:a action="doTest" namespace="/test">test</s:a>
BTW don't add action extension to actions in S2 tags.
This is wrong:
<s:form action="doTest.action">
This is correct:
<s:form action="doTest">

The rule is simple: if you defined a package with the namespace attribute then its actions belong to this namespace. And when you use url or a, or form tags you should specify a namespace attribute along with action name which is in action attribute. If you specify both parameters Struts can easy map your URL to the action from the package with namespace. Don't use action extension in these attributes. Struts is using UrlHelper class to build the url and if it can't find the action mapping it will return the string as is. Also if you are using href attribute then Url helper is not involved, so the string remains as is.
This code should work:
<s:url namespace="/test" action="doTest" var="myAction" />
<h2><s:a href="%{#myAction}">doTest with href (s:url action)</s:a></h2>
<h2><s:a namespace="/test" action="doTest">doTest with namespace and action (s:url action)</s:a></h2>

Related

How do I do a Simple Redirect in Struts 2?

I have been searching web for hours, and I can't find answer to a simple question in Struts 2. Basically, I have the following action in Struts 1 which is a simple forward, and I want to reproduce the same in Struts 2:
<action path="/az/api/v22/my-tenants" forward="/components/c/apis/v22/my-tenants.jsp">
</action>
I could write an action class to do this, but I think Struts2 has to have some way of doing this without having to write an action class since it is is a simple redirection.
Create actionless result in the struts.xml
struts.xml:
<package name="v22" namespace="/az/api/v22" extends="struts-default">
<action name="my-tenants">
<result>/components/c/apis/v22/my-tenants.jsp</result>
</action>
</package>
This configuration defines a package with namespace /az/api/v22 and action name my-tenants. So if you use path /az/api/v22/my-tenants it will be mapped to the action config above, because default action mapper is using namespace and action name together to get the action config.
There's no class attribute in the action tag, and it uses class ActionSupport instead. This class is configured by default in struts-default package.
In the result it's enough to define the location of the JSP, because struts2 defaults are using a dispatcher that forwards to JSP, and it's using "success" result code by default in the result config which is returned by default by ActionSupport class.

Struts2 URL unreachable

I'm really racking my head here with Struts2 - I'm able to access the JSP pages by omitting part of the path. Note the path suppose to include pages/welcome_user.jsp. The key is to look at the word pages in the path.
here's the struts.xml file:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="default" namespace="/User" extends="struts-default">
<action name="Login">
<result>pages/login.jsp</result>
</action>
<action name="Welcome" class="com.mkyong.user.action.WelcomeUserAction">
<result name="SUCCESS">pages/welcome_user.jsp</result>
</action>
</package>
</struts>
I'm able to access login.jsp via: http://localhost/Struts2Example/User/Login
and welcome_user.jsp via: http://localhost/Struts2Example/User/Welcome
Note that in both URL, I'm able to drop pages, why?
source:
http://www.mkyong.com/misc/how-to-use-mkyong-tutorial/
Can someone go through the above tutorial and tell me what's wrong?
First, you have used URLs that are mapped to the actions in the struts.xml.
The action method is executed and returns a result code SUCCESS. This result you can find in the action config. Then result is executed, if the type of result isn't set the default is dispatcher, and request is forwarded to the location specified in the result config.
If location is relative the final absolute location will be determined by the namespace of the package used for this action.
More detailed example of usage namespaces and explanation you can find in the example Struts 2 Namespace configuration example and explanation.
You can't drop pages if you are using dispatcher result that forwards to JSP. In this case the URL has been rewritten and you can't see the final URL.

How do I handle multiple actions in single form in wildcard action mapping?

According this solution Struts2 handle multiple actions... I know the Struts2 DMI can handle multiple acitons in single form easily.
Recently, Struts2 turned off DMI mechanism for security issue. Now, we use Wildcard Mappings to map all actions in struts.xml
Example:
<action name="*/*" class="action.{1}Action" method="{2}">
...
</action>
In Wildcard Mappings, it has a little problem to deal with mapping multiple actions/methods in single form.
<s:form action="actionA/method2" theme="simple" >
<s:submit value="lastStep" action="actionA/method1"/>
<s:submit value="nextStep" />
</s:form>
How can I fix this problem?
In Struts2 even if DMI is turned off still possible to use special parameter action:. To use this parameter in JSP you need to configure
in your struts.xml file:
<constant name="struts.mapper.action.prefix.enabled" value="true" />
Special parameters are handled by the action mapper when filter is trying to get action mapping from the filtered URL, and this parameter is added to the form when you use action attribute of the submit tag.

Strut2 having multiple packages cause problems

This is my package structure in Struts.xml file
<package name="default" namespace="/" extends="struts-default">
<!-- Default action name <default-action-ref name="Index" /> -->
<action name="Index" method="index"
class="com.convergent.struts2.actions.UserAction">
<result name="success" type="dispatcher">/WEB-INF/html/index.jsp</result>
</action>
</package>
<include file="struts-admin.xml"></include>
My Index.jsp is access through this url
http://localhost:8888/Index
In Index page there is hyper link that redirect that user to Setting Page. Setting action is in the 'Admin' namespace so it is access as:
Setting
In setting page there is a hyper link to redirect the user to index.jsp page. action is called like this:
go back
As you can seen 'Index' action is in the default package having namespace '/'. So to handle this action namespace is changed and user is redirected to the index.jsp page. My problem is that although user is redirected to index.jsp page but the web url looks like
http://localhost:8888/Admin/Index
I want this url to
http://localhost:8888/Index
I don't know how to solve this problem. can anyone suggest me ?
"As you can see 'Index' action is in the default name space." - no it is in the default package and the namespace "/".
Advice: 1) Don't create namespaces without leading a leading '/', it generally isn't want you want. For basic use of namespaces see http://struts.apache.org/release/2.1.x/docs/namespace-configuration.html although that page does not cover the creation of namespaces without a leading slash, and the interesting behaviour you've experienced.
2) Use the namespace attribute of the struts2 url tag. When using Struts the tag reference is your friend: http://struts.apache.org/release/2.3.x/docs/tag-reference.html
As Roman mentioned, using the anchor tag will be a touch more straight forward.
Using just the url tag you would have:
go back
When this is a bit clearer:
<s:a namespace="/" action="Back">go back</s:a>
To solve this problem what i do rather than redirecting the user to index.jsp I first redirect the user to another action like this
go back
To handle this action mapping in struts-admin.xml is:
<action name="Back">
<result name="success" type="redirectAction">
<param name="namespace">/</param>
<param name="actionName">Index</param>
</result>
</action>
This way I solve the problem.

What does "/" means in namespace attribute of package element in struts.xml?

I'm new in struts so I what know the meaning of "/" in namespace of package.
i.e.
when I put namespace as "/Home"
<package name="base" namespace="/Home" extends="struts-default">
<action name="HelloWorld" class="controller.HelloWorld">
<result>/message.jsp</result>
</action>
</package>
and type this Url : "localhost:8080/Struts2Example/Home/HelloWorld.action" on browser , then page opens.
but when I change the namespace to "Home" then it gives "Error : 404".
So what's this "/" means ?
From Struts Manual http://download.oracle.com/otn_hosted_doc/jdeveloper/j2ee101302/working_with_struts/f1_struts_ide/f1_strutsconfigactionmappings.html
and here
http://struts.apache.org/release/2.1.x/docs/namespace-configuration.html
The request URI path which, when received by the Struts servlet action controller, invokes the action mapping. The path name is a relative path and must include the forward slash (/).
Here's some 101 on name spaces.
The first thing you need to keep in mind is that namespace is not a file path.
Coming to what a namespace does:
What happens is that when a user hits a request to access a struts web application, this url is splitted into hostname, port name, servlet context name, namespace (if any) and the struts action.
Ex. : localhost:8080/myapp/discountModule/getPrice.action
Namespace divides the action configuration into logical modules.
For example if the URL /foo/myfoo/myfooaction.action is requested, the framework will first look for namespace /foo/myfoo. If the action does not exist at /foo/myfoo, the search will immediately fall back to the default namespace "". The framework will not parse the namespace into a series of "folders".
So when do we use names Spaces
Namespace is very useful in large web application that need to seprated into small domains or modules. Example lets say you are managing a shopping cart backend and this has 4 main section - ADMIN, ORDERS, SALES & REFUNDS
As described earlier, namespace is defined inside the tag using namespace attribute. To define these four domain, four tag will be defined with their namespace specification as follows:
Ex - localhost:8080/shoppingCart/admin/doSomeAdmin.action
REMEBER - IT IS NOT MANADTORY TO USE A NAMESPACE.
Struts documentation has few more examples - http://struts.apache.org/release/2.1.x/docs/namespace-configuration.html
Adding to user1428716
only "/" define the root name space.
<package name="base" namespace="/e" extends="struts-default">
<action name="HelloWorld" class="controller.HelloWorld">
<result>/message.jsp</result>
</action>
</package>
root is : "http://localhost:8080/Struts2Example/"
so the url is "http://localhost:8080/Struts2Example/HelloWorld.action"
and when we mention "/namespacename" then it means "~root/namespaceName/your.action"

Categories