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.
Related
I am looking for an example for simple use of single_media_upload in SULU AdminUI.
I have a player form, and it has single_media_selection type of field, and it works OK.
Now, how can I use single_media_upload, because, when I replace it instead of single_media_selection, it shows not picture in form after save (but it saves image).
<property name="photo" type="single_media_selection" colspan="4" >
<meta>
<title>playerinfo.playerimage</title>
</meta>
<params>
<param name="types" value="image"/>
</params>
</property>
I replace with
<property name="photo" type="single_media_upload" colspan="4" spaceAfter="2">
<params>
<param name="upload_text">
<meta>
<info_text>app.player_info_upload</info_text>
</meta>
</param>
<param name="skin" value="default"/>
<param name="empty_icon" value="su-user"/>
<param
name="collection_id"
type="expression"
value="service('sulu_media.system_collections.manager').getSystemCollection('sulu_media')"
/>
</params>
</property>
In Entity itself, field is MediaInterface type.
The single_media_upload field-type is not interchangeable with the single_media_selection type. It was implemented for managing the avatar/logo of the built-in contact/account entity and was not optimized for other usecases yet. At the moment, the single_media_upload creates a new media version for the selected media entity rather than creating a separate media entity when uploading a file. This behaviour differs substantially from the single_media_selection and might not fit your usecase. This is also the reason why the field-type is not listed in the Sulu documentation yet.
That said, the reason for your problem is likely that the single_media_upload field-type uses a different data format than the single_media_selection. In general, the field-types of the Sulu form view expect that your API returns the data in the same format as it is sent to the server when submitting the form (see the Form configuration section in the Sulu documentation). You can see the data that is sent to the server by inspecting the request that is made when pressing the save button in the network panel development tools of your browser.
In the case of the single_media_upload field-type, the data that is sent to the server looks like this:
{
"id": 33,
"url": "/media/33/download/photo-1535683939029-0030b4de2382.jpeg?v=1",
"thumbnails": {
"sulu-400x400": "/uploads/media/sulu-400x400/03/33-photo-1535683939029-0030b4de2382.jpg?v=1-0",
...
}
}
If you want to use the field-type in the form of your custom entity, you need to adjust your controller (or the serialization of your entity) to match this format.
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
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
It appears from the MediaWiki API:Query page that you can only resolve a redirect one at a time.
The document even says "The example below isn't really useful because it doesn't use any query modules, but shows how the redirects parameter works."
But how can you get the redirect information -- using a query module that does return multiple results?
If you have any result that returns pages, then you can just append redirects to the query and it resolves the redirects. If you don't have results that returns pages, you can usually convert it to that by using a generator.
For example, the query
http://en.wikipedia.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Redirects_from_gender&redirects
returns something like (shortened)
<api>
<query>
<categorymembers>
<cm pageid="648" ns="0" title="Actress" />
<cm pageid="19887132" ns="0" title="Administratrix" />
</categorymembers>
</query>
</api>
If you convert that into a generator
http://en.wikipedia.org/w/api.php?action=query&generator=categorymembers&gcmtitle=Category:Redirects_from_gender
you get
<api>
<query>
<pages>
<page pageid="648" ns="0" title="Actress" />
<page pageid="19887132" ns="0" title="Administratrix" />
</pages>
</query>
</api>
And if you now add redirects
http://en.wikipedia.org/w/api.php?action=query&generator=categorymembers&gcmtitle=Category:Redirects_from_gender&redirects
you get
<api>
<query>
<redirects>
<r from="Actress" to="Actor" />
<r from="Administratrix" to="Administrator (law)" />
</redirects>
<pages>
<page pageid="21504235" ns="0" title="Actor" />
<page pageid="6676496" ns="0" title="Administrator (law)" />
</pages>
</query>
</api>
You can also use prop=redirects with any generator, e.g. generator=allpages. This is a new feature since MW-1.23, fixing bug T59057.
When using generator=allpages with max limits (gaplimit=max and rdlimit=max) and apihighlimits right is available, all redirects on ArchWiki are resolved in a single query ;)
https://wiki.archlinux.org/api.php?action=query&generator=allpages&gapfilterredir=nonredirects&gaplimit=max&prop=redirects&rdprop=pageid|title|fragment&rdlimit=max
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...