Struts 2 Double form submit - why? - struts2

I have a few simple actions:
<action name="edit" class="EditAction">
<result>/WEB-INF/jsp/form.jsp</result>
</action>
<action name="preview" class="PreviewAction">
<result>/WEB-INF/jsp/preview.jsp</result>
<result name="input">/WEB-INF/jsp/form.jsp</result>
</action>
<action name="store" class="StoreAction">
<result>/WEB-INF/jsp/confirmation.jsp</result>
<result name="input">/WEB-INF/jsp/preview.jsp</result>
</action>
<global-results>
<result name="invalid.token">/WEB-INF/jsp/invalidToken.jsp</result>
</global-results>
and classic scenario: user interacts with text inputs, press Save, view a Preview page and press Save on it to save data, without double-press buttons, refreshing page etc.
Why double submit can occurs in such situation?

Even I had double form submit problem in struts2 on browser refresh. I resolved the problem using post-redirect-get pattern to avoid double or duplicate form submissions. It happens because hitting "refresh page" for a reponse based on a POST request will re-issue the POST request.It repeats what you did to reach current page even for double button press. It happens for both success and error in struts2.
I suggets you to make this change where-ever necessary.
<action name="onStoreRedirect">
<result name="success" type="redirect">store</result>
</action>
<action name="store" class="StoreAction">
<result>/WEB-INF/jsp/confirmation.jsp</result>
<result name="input">/WEB-INF/jsp/preview.jsp</result>
</action>

Related

struts2 tokensession not setting request in Action excludedMethod [duplicate]

This question already has an answer here:
Prevent same action called twice as long as user is in current session
(1 answer)
Closed 5 years ago.
I'm trying to avoid double-submit problems using tokenSession. My action methods are working fine without tokenSession technique.
I add <s:token/> in upsert_crypto_sources.jsp and tokenSession interceptor in struts.xml but I receive request as null in my action excludedMethod of list().
The list page doesn't need to avoid double submit problem but if I add <s:token/> in view_crypto_sources_list.jsp and remove list() from excludedMethod then I always receive result invalid.token.
My struts.xml is like:
<struts>
<package name="key-manager" namespace="/shared/km" extends="console-default" strict-method-invocation="true">
<action name="manage_cs_*" method="{1}" class="console.shared.km.ASC_ManageCryptoProfilesAction">
<interceptor-ref name="tokenSession">
<param name="excludeMethods">
list, initInsert, load, delete
</param>
</interceptor-ref>
<result name="list">/shared/km/view_crypto_sources_list.jsp</result>
<result name="insert">/shared/km/upsert_crypto_sources.jsp</result>
<result name="update">/shared/km/upsert_crypto_sources.jsp</result>
<result name="load">/shared/km/upsert_crypto_sources.jsp</result>
<allowed-methods>list, insert, load, update, delete, testConnection, forward, cancel</allowed-methods>
</action>
My action implements ServletRequestAware interface therefore it gets the request member variable set using setServletRequest() method.
I added a defaultStack interceptor and it is working fine:
<struts>
<package name="key-manager" namespace="/shared/km" extends="console-default" strict-method-invocation="true">
<action name="manage_cs_*" method="{1}" class="console.shared.km.ASC_ManageCryptoProfilesAction">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="tokenSession">
<param name="excludeMethods">
list, initInsert, load, delete
</param>
</interceptor-ref>
<result name="list">/shared/km/view_crypto_sources_list.jsp</result>
<result name="insert">/shared/km/upsert_crypto_sources.jsp</result>
<result name="update">/shared/km/upsert_crypto_sources.jsp</result>
<result name="load">/shared/km/upsert_crypto_sources.jsp</result>
<allowed-methods>list, insert, load, update, delete, testConnection, forward, cancel</allowed-methods>
</action>

How to redirect with parameter

<action name="AddedPaid" class="iland.payment.SupplierPaidAction" method="insert">
<result name="success" type="redirect">ShowPaid</result>
<result name="input">/pages/payment/addToPay.jsp</result>
<result name="login">/pages/login.jsp</result>
</action>
<action name="ShowPaid" class="iland.payment.SupplierPaidAction" method="fetchAllByfk">
<result name="success">/pages/paid/showPaidDetails.jsp</result>
<result name="input">/pages/payment/ShowPay.jsp</result>
<result name="login">/pages/login.jsp</result>
</action>
Here AddedPaid Action is used to add form data in to database.
After adding data in to database I am redirecting result to ShowPaid action.
This is working properly.
Now I want whenever I redirect AddedPaid action to ShowPaid.
ShowPaid must show data of perticular supplierPaymentId for which I have added data in AddedPaid.
After redirect it is howing url
http://localhost:8082/ClothStore/ShowPaid
I want
http://localhost:8082/ClothStore/ShowPaid?supplierPaymentId=4
It's strange, usually people have 2 and want 1 :)
Btw, since you are using PostRedirectGet, you need to manually pass the parameter in Struts configuration.
Assuming you have a variable named supplierPaymentId with getter and setter, it's achievable like follows:
<action name="AddedPaid" class="iland.payment.SupplierPaidAction" method="insert">
<result name="success" type="redirectAction">
<param name="actionName">ShowPaid</param>
<param name="supplierPaymentId">${supplierPaymentId}</param>
</result>
<result name="input">/pages/payment/addToPay.jsp</result>
<result name="login">/pages/login.jsp</result>
</action>
Also use redirectAction instead of redirect, that is meant to be used to redirect to external URLs or non-Action URLs
First of all use redirectAction result instead of redirect to redirect to another action.
And use param tag to add parameters in your result configuration.
<result type="redirectAction">
<param name="actionName">ShowPaid</param>
<param name="supplierPaymentId">${supplierPaymentId}</param>
</result>
Note you need to have getter/setter for supplierPaymentId in your action class.

Avoid duplicate Struts2 form Submission when clicking on refresh button

I am using struts 2 and i want to avoid the duplicate form submission when clicking on refresh button...After getting the result from the Action class, i am coming back to the same jsp and it holds the value entered and also the message that it has been successfully submitted but the problem is that when i refresh the page..it again tries to submit the request....for that i am trying to use Token Interceptor available in struts 2...but i think I'm missing something...
<package name="FOCAccept" extends="struts-default">
<action name="focSubmitRequest" class="bpel.invoke.action.FOCAcceptAction" method="execute">
<interceptor-ref name="token"/>
<result name="invalid.token">/postfocaccept.jsp</result>
<result name="input">/postfocaccept.jsp</result>
<result name="success">/postfocaccept.jsp</result>
<result name="failure">/postfocaccept.jsp</result>
<result name="invalid" type="redirectAction">LogoutCred.action</result>
</action>
</package>
I have use this and it is working fine for me...at anyhow all it's matter is the output. i have added this in the jsp and when i presses the refresh button it does not hit the controller and also makes the entered field value empty..
here is the code......
$(document).bind('keypress keydown keyup', function(e) {
if(e.which === 116) {
$("#submitRequest_pon").val("");
$(".errorMessage").html("");
return false;
}
if(e.which === 82 && e.ctrlKey) {
return false;
}
});

I want to call/redirect to a Portal page from Struts2Portlet Action Class?

Hi We are developing a Struts2Portlet Application in WebSpherePortal6.0.1. In my application I want to redirect to another portlet page after fullfilling the validations in my struts action class.How to achieve it. Please help me.
Thanks in Advance.
I have done some R&D to fix this issue,finally i found a solution.We cant call/redirect the portal page from struts2Portlet Action class.We can have to give a result type in strut action class,then we have to configure the action in the result.
<action name="view" class="com.ibm.rock.ViewAction" method="prepareview">
<result name="view">*/view/viewportalpage.action*</result>
</action>
<action name="viewportalpage" class="com.ibm.rock.ViewAction" method="prepareview">
<result name="preview">/_Rock/jsp/html/Preview.jsp</result>
</action>
Synatax:
<result name="success">*/Namespace/view.action*</result>
<action name="view" class="com.ibm.rock.ViewAction" method="prepareview">
<result name="preview">/_Rock/jsp/html/Preview.jsp</result>
</action>

Tiles2 + Struts2 xml validation

i have a problem, i have my login with Strits2, Tiles2 and Struts xml validations, when i run my webapp the first page is the login and the struts2 xml validator send me the error, how do i tell that for the first time do not validate until submit?
<action name="loginPage" class="com.webapp.login.action.LoginAction">
<result name="input" type="tiles">loginPage</result>
<result name="success" type="tiles">loginPage</result>
</action>
Whenever you want to go to a "blank form", you should execute the input() method of your Action. This tells Struts 2 that you do not want to perform any validation for the action:
<action name="loginPage" class="com.webapp.login.action.LoginAction"
method="input">
<result name="input" type="tiles">loginPage</result>
<result name="success" type="tiles">loginPage</result>
</action>
Then, you should submit your login form to another action definition that executes the default action execute(). Struts 2 will then try to perform Action validation:
<action name="loginPageSubmit" class="com.webapp.login.action.LoginAction">
<result name="input" type="tiles">loginPage</result>
<result name="success" type="tiles">loginPage</result>
</action>

Resources