Redirect to default action in Struts 2 - redirect

I have an action with an empty string for name defined in the root namespace, and I want to redirect to that action from another action if a certain result is found, but it doesn't seem to work.
Here's the default action
<action name="" class="com.example.actions.HomeAction">
<result name="success" type="freemarker">freemarker/home.ftl</result>
</action>
And I'm defining the redirect in the global-results for the package:
<global-results>
<result name="sendToRouting" type="redirectAction">
<param name="actionName"></param>
<param name="namespace">/</param>
</result>
</global-results>
I've tried taking out the actionName parameter, but that doesn't work. If I put a name in for the HomeAction and reference it by name in the global-results it works, so I'm assuming the problem is lack of action name for the redirect.
Any thoughts?

I think that what you want to do is use <default-action-ref />:
<package name="home" namespace="/" extends="struts-default">
<default-action-ref name="home" />
<action name="home" class="com.example.actions.HomeAction">
<result name="success" type="freemarker">freemarker/home.ftl</result>
</action>
</package>
Sorry...misread the question:
Try changing type="redirectAction" to type="redirect", I'm fairly sure that redirectAction is now redirect.

Were you getting a NullPointerException because the actionName parameter is blank? I hacked around this by providing a string which evaluates to an empty string:
<param name="actionName">${}</param>
Still looking for a more "correct" solution though...

Related

Title element doesn't work with Action Element in Manifest XML

I am creating an add-in for Microsoft Word.
I am getting manifest validation error for Title element inside Action element.
Microsoft Reference documentation for Action Element
Error #1:
XML Schema Violation: Your manifest does not adhere to the current set of XML schema definitions for Office Add-in manifests. (link: https://aka.ms/add-in-manifest-schema-violation)
- Details: The element 'Action' in namespace 'http://schemas.microsoft.com/office/taskpaneappversionoverrides' has invalid child element 'Title' in namespace 'http://schemas.microsoft.com/office/taskpaneappversionoverrides'. List of possible elements expected: 'TaskpaneId, SourceLocation' in namespace 'http://schemas.microsoft.com/office/taskpaneappversionoverrides'.
- Line: 54
- Column: 22
Example:
<Action xsi:type="ShowTaskpane">
<Title resid="Contoso.Taskpane.Title" /> --> //Adding this line throws error
<TaskpaneId>ButtonId1</TaskpaneId>
<SourceLocation resid="Contoso.Taskpane.Url" />
</Action>
Could someone help me here?
The validator checks the order in which the XML elements appear.
Please use the code below:
<Action xsi:type="ShowTaskpane">
<TaskpaneId>ButtonId1</TaskpaneId>
<SourceLocation resid="Contoso.Taskpane.Url" />
<Title resid="Contoso.Taskpane.Title" /> -->
</Action>

How to redirect struts action with dynamic parameter

I want to redirect action with parameter "id".
I used this code in struts.xml
<action name="register" class="com.framework.strust2.UserAffair">
<result name="success" type="redirectAction">
<param name="actionName">viewProfile</param>
<param name="id">${id}</param>
</result>
</action>
It works for action redirecting and parameter name id, but not parameter value ${id}. It only works with constant id, like;
<param name="id">1</param>
Though I searched the solution of my problem, there is nothing case that matches what I needed. Pls.
For passing the parameter with action you should have to define that variable in action and if you are using model driven approach then that parameter should be in pojo i.e
it is your struts.xml action configuration.
<action name="register" class="com.framework.strust2.UserAffair">
<result name="success" type="redirectAction">
<param name="actionName">viewProfile</param>
<param name="id">${id}</param>
</result>
</action>
so in you action class there should be variable sayaing id.
i.e
class UserAffair{
private int id;
//setter and getter
}
and if you are using model drivan then in your pojo there should be a variable saying id.
hope so this will help you a lot

Struts 2 - Persist property value for redirect action

I want to retain a property value after redirecting to a different action. I know that the value will go away since we are navigating to different action (request). But I need to some how that how can I achieve this ?
Here is my code :
<action name="save" class="saveAction" method="saveData">
<result name="success" type="redirectAction">redirectedPageAction</result>
<result name="successView" >successView.jsp</result>
<result name="error" >error.jsp</result>
</action>
<action name="redirectedPageAction" class="month" method="">
<result name="success">employeesList.jsp</result>
</action>
In save action class I am using addActionMessage(String msg) method to set a value. Also I have getter/setter for the same.
I tried this but didn't get success :
<action name="redirectedPageAction" class="month" method="">
<result name="success">employeesList.jsp>
<param name="msg">${msg}</param>
</result>
</action>
I want value which was set by adActionMessage(msg) in my employeelist.jsp page. I am getting null pointer struts exception.
Please help..
Actions are created per-request. If you don't actually pass anything from the first action to the second, there won't be anything for the second action to retrieve. Getters don't change HTTP mechanics.
If you're interested specifically in messages/etc., use the MessageStoreInterceptor, or do it manually.
Since you already mentioned that and you know that it will create a new request cycle and Actions and created per request since they work as Data object also ,which means your request/response parameters will be lost.
Now you have few option
Try using the Struts2 build in support for this message-store-interceptor.
This interceptor has been created to store a ValidationAware action's messages / errors and field errors into HTTP Session and is very useful in your use-case.
If you want wider scope either you can store data in the session and retrieve that at later stage or can pass values as query parameters.
I've faced this problem before, sometimes you need to show a whole new view after an action and the redirect result does not take into consideration any previous data (http request stuff).
We wanted to create a custom interceptor, but before doing it I found this
http://www.mail-archive.com/user#struts.apache.org/msg77854.html
It really helped us a lot.
Having said that, what version of Struts 2 are you using? We use Struts 2.2.3 and the parameters passed to the redirectAtion works fine.
Do you have setter and getters in both actions?
You can pass your property variable with redirectAction as a parameter like this
<action name="save" class="saveAction" method="saveData">
<result name="success" type="redirectAction">
<param name="actionName">redirectedPageAction</param>
<param name="msg">${msg}</param>
</result>
<result name="successView" >successView.jsp</result>
<result name="error" >error.jsp</result>
</action>
Also, dont miss to add getter/setter for msg variable in your redirectedPageAction action

Populate fields after redirect in struts 2

I'm trying to understand if there is an easiest and shorter way to populate the fields of a form, after it fails validation and it's redirected (following the pattern described here).
I have a form that is called from addPerson.action action, and submit action is savePerson.action.
If it fails validation, I redirect passing all parameters, so that the redirected page will populate the fields with the data inserted by the user, avoiding the user the hassle to start from scratch.
The problem of this solution is that I have to list every single parameter of the form in the struts.xml, like in the example below:
<action name="savePerson" class="personAction" method="savePerson">
<interceptor-ref name="store">
<param name="operationMode">STORE</param>
</interceptor-ref>
<interceptor-ref name="myStack" />
<result name="success" type="redirectAction">
<param name="actionName">listPeople</param>
</result>
<result name="input" type="redirectAction">
<param name="actionName">addPerson</param>
<param name="parse">true</param>
<param name="person.name">${person.name}</param>
<param name="person.surname">${person.surname}</param>
<param name="person.gender">${person.gender}</param>
<param name="person.email">${person.email}</param>
<param name="person.mobile">${person.mobile}</param>
</result>
</action>
<action name="addPerson" class="personAction" method="addPerson">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<interceptor-ref name="myStack" />
<result name="success">/person/add.jsp</result>
<result name="input">/person/add.jsp</result>
</action>
I had to use the MessageStoreInterceptor in order to save and retrieve the validation error messages from a redirect.
I'm already using the ajax validation, but I wish to make my pages work in non javascript mode as well. With the code above everything works as expected, but looks weird that I have to list all my parameters inside the result tag.
Is there a better and shorter way of doing it?
thanks
With a redirect you start over, you throw out the value stack except for the parameters you explicitly pass in. What you probably want is chain, which snowballs the value stack.
See here for a list of result types, the link to Chain has some examples: http://struts.apache.org/2.2.1.1/docs/result-types.html
You can then just use the basic result tag and probably will not need a body.
See nmc's comment. This is what I do too, it isn't a good idea to use chain or redirectAction... creates spaghetti actions.

Default route is matched instead specific route

<routes>
<www type="Zend_Controller_Router_Route_Hostname">
<route>www.domain.com</route>
<chains>
<index type="Zend_Controller_Router_Route">
<route></route>
<defaults module="default" controller="index" action="index" />
</index>
<community>
<route>community</route>
<defaults module="community" />
<chains>
<index type="Zend_Controller_Router_Route">
<route>:action/*</route>
<defaults controller="index" action="index" />
</index>
<member type="Zend_Controller_Router_Route_Regex">
<route>member/profile-(\d+)-(.+)</route>
<reverse>member/profile-%d-%s</reverse>
<map>
<id>1</id>
<nom>2</nom>
</map>
<defaults action="viewmember" />
</member>
</chains>
</community>
</chains>
</www>
As you can see, I use a route with :action/* in to cover the homepages and the basics actions on index controller.
domain.com/community/random_action => works good.
domain.com/community/ doesn't work. The whole homepage is displayed.
I checked, and the default route is matched.
I tried assemble() on route "www-community-index" and it gives well www.domain.com/community
I don't see from where comes the problem :(
The first thing you should check is if you deleted the default route.
The second one is....remember that the routes are checked in reverse order. This means that the most specific should be the first and the default the last one.