Redirect attribute of actionforward does not work in struts portlet bridge based portlet (JSR-168) - redirect

I did a lot of researching on the matter but cannot seem to find the answer to my question, so I hope you guys can help me out.
We have a struts 1.2.7 web app that we converted to a JSR-168 portlet using the Apache Struts Portlet Bridge.
This is all working very well except for one thing: the actionforwards that specify a redirect do not actually redirect to the specified action. These redirects DO work when running the app as a normal struts web app. Hence, we have a double submit problem in the portlet variant.
We make use of action chaining that ends with an action forwarding to a tile definition. For example:
<action path="/CreateIdmAccountSubmit" validate="true" input="catalog.createaccount.page" type="com.konakart.actions.login.CreateIdmAccountSubmitAction" name="CreateIdmAccountForm">
<forward name="FillRegistrationData" path="/FillRegistrationData.do" redirect="true"/>
</action>
<action path="/FillRegistrationData" validate="false" type="com.konakart.actions.registration.FillRegistrationDataAction" name="FillRegistrationDataForm">
<forward name="FillRegistrationDataPage" path="/FillRegistrationDataPage.do" redirect="false"/>
</action>
<action path="/FillRegistrationDataPage" forward="order.registrationdata.page"/> (tiles-def)
In this example the action /CreateIdmAccountSubmit processes a submitted form (POST) and creates an account in the db. After successfull creation the user is redirected to another action (/FillRegistrationData) which inits an order object and, on its turn, forwards to the orderregistration page which layout is defined in the tiles-defs.xml.
As I said this all works very well, form a functional perspective, but when a user hits f5 on the rendered order-registration-page the action /CreateIdmAccountSubmit is again invoked causing the account to be created double. As I said also this is not happening when running the app as a normal web app. Here, the mechanism works perfectly :)
I think that the problem is being caused by the fact that the redirect is done in the wrong phase but i am really not sure as why this does not work :)
Based on what I read I tried the fowllowing things to fix the redirect problem:
* specified the action that does the form submit as "actionUrl" in struts-portlet-config.xml (hoping that redirect is done in wrong phase?)
* replaced the normal html tag library by the struts-portlet variant (hoping that a valid url actionUrl was produced by my html:form that in some way made the redirect possible?)
These two steps did not seem to help and I am lost at how to accomplish a simple redirect in the portlet so that we can prevent the double submit problem.
Hope you guys can help me out!

I found the answer: the mechanism is dependent on the portal implementation. We use Liferay which does not work with redirects by default.
However, you can switch this on by declaring an element in liferay-portlet.xml called
<action-url-redirect>true</action-url-redirect>
This fixed the problem for us!

Related

Struts 2 missing reset method?

I am migrating a project from struts 1.3 to struts 2.0. Now I have read through various resources available on web but could not find a struts 1.3 reset() form method alternative in struts 2.0.
My action class extends ActionSupport and implements Modeldriven. I have implemented the validate method in action class and that works perfect. However, when the form has no errors and the submission is done properly, the page reloads with initial values.
I expected that I will receive a blank form. I looked for a reset() form method but could find none. Currently, I am explicitly setting all form values to blank. I don't see this as a good programming practice. Please suggest how to implement form reset() in struts 2.0.
EDIT: ok, you are working with Tiles (that I've never used), then I'll try another solution:
if you have an empty JSP tile, and after the user compiled its fields and submitted the form, you want to ALWAYS clear those fields... what about declaring only SETTERS in the Action, and not the GETTERS ?
You could only set from JSP to Action, but not read them from the JSP... then your fields will be always empty in the page, and always rewritten by setters in the Action.
If i got it, you are on JSP, you call the method saveStuff() of the Action (or of another action), then you come back to the page...
in this case, you can use a RedirectAction return type, that will strip all params from the request, and redirecting your request to the execute() method of your Action.
So, instead of
<action name="myAction" class="com.blabla.myAction">
<result name="success">/myPage.jsp</result>
</action>
just do
<action name="myAction" class="com.blabla.myAction">
<result name="success">/myPage.jsp</result>
<result name="stuffSaved" type="redirectAction">
<param name="actionName">myAction</param>
</result>
</action>
This way you re-enter in the initial state (assuming you are not putting anything in session that is read by the JSP).
Because your Action and Form are in the same class in Struts2, you have to implement your own reset() method to clear any data that you would like.

How to call SOAP service from Phonegap (iPhone app)

I am trying to call a SOAP service using this SOAP client but it is not working for me. Please help me. How can I send and receive XML SOAP with Phonegap?
Phonegap is HTML/JS/CSS commonly communicating via XHR/Ajax. It's better to use jQuery Ajax functions. You can get the details here.
Eg:
Posting-XML-SOAP-Requests
AJAX-Requests-Between-jQuery
Simple jQuery client to call a SOAP web service
If you find any cross-domain issues (or working in a browser and not working with simulator/device), please refer to the below steps.
Go to the Resources folder, you can see a file named Cordova.plist. Click on that and you can see the Root elements. Right click on the Root, add a row, set the key as ExternalHosts with type Array.
Expand the item, and add an item as item0. Give it type string and enter the value as '*'.
Don't forget to save the Cordova.plist after changes (just use cmd+s).

Zend AjaxContext, _redirect and hash navigation

first post in SO, even though I've been browsing it for years now to solve those mind-blowing and not so much coding problems.
What I want to do is:
* Use hash navigation (#!/).
* Use Zend controller actions, not php files.
* Load these actions through javascript/jQuery.
So far, I've got this working:
indexController, several Actions, each attached to AjaxContext via addActionContext(), I can call them though my javascript/jQuery file via "hashchange" plugin jQuery(window).hashchange(function(){ bla bla }). I can cycle through actions just fine.
But I want to redirect the user to a login page if he/she is not logged in, which brings me to my issue: How can I achieve that? The redirection is made to another controller (login controller, login action). I was trying something like $this->_redirect('/#!/login/login'); w/o any luck (yes, I've set up an AjaxContext in that controller's init). I keep getting a redirection error ("The page isn't redirecting properly"). If I just type in the address bar "/#!/login/login" I get everything display properly.
Anyway, thanks in advance!
Cheers
Now this starts to get complicated if you ever introduce other non-ajax contexts, but you could add the Ajax context to the Error Controller. Then have the error controller return JSON for the unauthenticated exception if the active context was AJAX (and keep the redirect if the default context was active). Your JS would then listen for that specific error provided by the JSON and manually bounce the user to the appropriate login URL.

GWT - gwt.codesvr= tag being removed

I'm working on a GWT application.
I wish to debug the client side Java code.
I start up the application from Eclipse in debug mode.
The app starts in the browser with the gwt.codesvr= set correctly.
I can debug at this stage.
The app then redirects to the a different jsp page.
The gwt.codesvr= parameter in the URL is dropped.
The app uses History.newItem("xx") quite a bit (as described in http://code.google.com/webtoolkit/articles/mvp-architecture.html#history)
The problem is that I can't now debug the client side code.. as the
gwt.codesvr= parameter has been dropped from the URL.
When I attempt to add it back in, the app History handling code runs,
and the parametes is immediately dropped again.
I checked this on another PC and the same behaviour occurs.
I checked in Chrome and IE8 and the same..
What is the solution ?
Thanks A million,
Fergal.
History.newItem() keeps the query string intact (in this case, the ?gwt.codesvr=... part), so these calls shouldn't be the problem here.
You say, that the app redirects to a different jsp page. Find out, how it does that - it may use something like Window.Location.replace(newURL). Make sure, that newURL contains the gwt.codesvr=... part in its query string.
If the server performs a redirect itself (e.g. if it redirects after a POST request), then make sure, that the server adds the query string in the redirect URL. (You will probably have to submit your codeserver URL with the POST parameters in this case - because this is a client-side concept, and the server cannot simply guess it.)

Handling 'A potentially dangerous Request.Form value was detected from the client'

I am trying to figure out how to handle this error.
A potentially dangerous Request.Form value was detected from the client
The error occurs when a user enters in html or xml tags( <p> or <HeyImXML>) and tries to submit a form. The input is not supposed to contain any sort of markup at all, just plain text.
I am using model binding validation in ASP.NET MVC 2.0 along with Html.EnableClientValidation. This works fine as long as there is no markup entered.
What is the best approach on how to avoid this error message?
My guess is to write a new validation class which checks for this kind of markup?
I want to catch the error in this specific instance. To clarify there is an area with a form for siteadmins that can enter markup and there is a normal users area where they can not enter markup. However this error page appears when a normal users enters markup. My question is, how do I handle this to prevent the site from crashing and showing the error page. I want to display a cleaner error.
MVC will automatically protect your application from some html injection and cross-site scripting (XSS) attacks. This is why you will get the "A potentially dangerous Request.Form value was detected from the client (...)" by default when attempting to post html/javascript.
However, we may sometimes want to allow our users to post html. You might just want to allow users to use characters such as "›", or it might be because your implementing blog functionality and want to support tags like ‹h1›, ‹div›, etc. This can easily be accomplished with MVC by disabling request validation.
Add [ValidateInput(false)] attribute to the action method in the controller you are calling. This will disable request validation for the entire model on the specific action.
Another way is to add the [AllowHtml] attribute to the property which requires html in your model.
These two attributes will only allow html/javascript to GET IN to your application, but MVC will still output them safely by using html encoding. If you want to output it like html, you can use the #Html.Raw(#Model.Content). But use this with caution, since this will open your application to cross-site scripting attacks (XSS)!
i found this solution from some one's blog
also see below code for your solution
you can handle errors within your application in the following way
1. Setting the CustomErros mode section in your Web.Config file of your application
This the lists of options the mode attribute can accept.
RemoteOnly: Generic error pages are shown for remote users. Rich error pages are shown for local requests (requests that are made from the current computer). This is the default setting.
Off: Rich error pages are shown for all users, regardless of the source of the request. This setting is helpful in many development scenarios but should not be used in a deployed application.
On: Generic error pages are shown for all users, regardless of the source of the request. This is the most secure option.
<System.Web>
//map all the erros presented in the application to the error.aspx webpage
<customErrors mode="RemoteOnly" defaultRedirect ="~/error.aspx" />
<System.Web>
2. throught Global.asax file in the Application_Error function
//handle all the errors presented in the application
void Application_Error(object sender, EventArgs e){
Server.Tranfer("error.aspx");
}
I hope this works for you.
from stackoverflow solution
This was introduced early on in ASP.Net to try to help prevent script injection attacks. It isn't unique to MVC.
If you don't want this feature, you can turn it off and write your own.
To disable request validation on a page, set the validateRequest attribute of the Page directive to false:
<%# Page validateRequest="false" %>
To disable request validation for your application, modify Web.config - set the validateRequest attribute of the <pages /> section to false:
<configuration>
<system.web>
<pages validateRequest="false" />
</system.web>
</configuration>