Reputation: 3468
If I submit to the URL produced by:
<portlet:actionURL name="myAction" />
I end up with the something like the ff. URL in the browser after the render phase:
http://localhost:8080/...&_myportlet_WAR_myportlet_javax.portlet.action=myAction&...
The problem with this is that, if I click on the browser's refresh button, the action gets executed again. Presumably, this is due to the presence of that parameter in the URL.
Does anyone know why Liferay includes that parameter in the URL post-render and if there is a fix or workaround for it?
EDIT: My portlet class extends from com.liferay.util.bridges.mvc.MVCPortlet
.
Upvotes: 3
Views: 3084
Reputation: 27080
The problem with this is that, if I click on the browser's refresh button, the action gets executed again. Presumably, this is due to the presence of that parameter in the URL.
I doubt so. It is probably because you submitted data through the HTTP POST method. Or are you submitting your data through GET? If so, that would be a strange behavior.
About the parameter in the URL: I do not have an answer but this behavor is no surprise to me. Suppose for example that we create a servlet with doGet()
and doPost()
methods. If I submit some data to a URL through post (presumably to execute some action) the response of the doPost()
method would be relative to the submitted URL, so the URL of the resulting page will be the same. We can follow the same logic here: if you submitted to the action phase, the submitted URL will be the resulting one.
How to deal with it? The answer is the POST-REDIRECT-GET pattern. You should send a HTTP 302 response to the browser from your processAction()
method, usually redirecting the browser to the original page.
To do it is simple. The JSP of the form page should store the current URL in an input of your form:
<%
String redirect = PortalUtil.getCurrentURL(renderRequest);
%>
<input type="hidden" name="<portlet:namespace />redirect" value="<%= redirect %>">
Then you redirect to this URL in the processAction()
. If you are using Liferay MVCPortlet, you just need to call the sendRedirect()
method after all operations:
public void processAction(ActionRequest req, ActionResponse resp) {
// Doing stuff
sendRedirect(req, resp);
}
If the value of the original URL is in a request parameter called "redirect"
then this method will magically redirect you back to the original page.
If you are not using Liferay MVC but instead a mere subclass of GenericPortlet
, just retrieve the URL from the request and use the method ActionResponse.sendRedirect()
:
public void processAction(ActionRequest req, ActionResponse resp) {
// Doing stuff
String redirect = (String)actionRequest.getAttribute("redirect");
resp.sendRedirect(redirect);
}
Upvotes: 4