I have a portlet with several jsp pages each containing a form with submit button on it. When the user submits the form on the first jsp I save the data in db and call actionResponse.sendRedirect()
to forward the user to the next jsp page. I have to use redirects in order to prevent the user accidentally resubmitting the same data on the next page by pressing F5. Everything works fine exept that after redirecting to the second page the doView()
method doesn't get executed and I need to load some data there before rendering the page. Is this a normal behaviour or am I doing something wrong? Where can I load that data before rendering the second jsp?
First jsp
<%-- ... --%>
<portlet:actionURL name="createNewMyCustomObj" var="createNewMyCustomObjURL" />
<aui:form action="<%= createNewMyCustomObjURL.toString() %> method="post">
<%-- form fields --%>
<aui:button type="submit" value="Create" />
</aui:form>
Second jsp
<%
MyCustomObj obj = (MyCustomObj) renderRequest.getAttribute("myCustomObj");
%>
<portlet:actionURL name="updateMyCustomObj" var="updateMyCustomObjURL" />
<aui:form action="<%= updateMyCustomObjURL.toString() %> method="post">
<%-- fields with values from myCustomObj --%>
<aui:button type="submit" value="Update" />
</aui:form>
MyMVCPortlet.java
public class MyMVCPortlet extends MVCPortlet {
public createNewMyCustomObj(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortlalException, SystemException {
PortletURL redirectURL = null;
try {
// get data from request
// save it to db
redirectURL = createRedirectURL(actionRequest, "second.jsp");
} catch(Exception e) {
SessionErrors.add(actionRequest, "error-key")
// errors saving data, stay on the same page
redirectURL = createRedirectURL(actionRequest, "first.jsp");
}
actionResponse.sendRedirect(redirectURL.toString());
}
private PortletURL createRedirectURL(ActionRequest actionRequest, String jspPage) {
ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
String portletName = (String) actionRequest.getAttribute(WebKeys.PORTLET_ID);
PortletURL redirectURL = PortletURLFactoryUtil.create(
actionRequest, portletName, themeDisplay.getLayout().getPlid(), PortletRequest.RENDER_PHASE);
redirectURL.setParameter("jspPage", jspPage);
return redirectURL;
}
@Override
public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
/*
* doView() is never called after redirecting to second.jsp
*/
if(/* second jsp page */) {
// get myCustomObj created previously
renderRequest.setAttribute("myCustomObj", myCustomObj);
}
super.doView(renderRequest, renderResponse);
}
}
Take a look at the MVCPortlet.doDispatch(RenderRequest renderRequest, RenderResponse renderResponse)
method in MVCPortlet -- it seems to me that if either mvcPath
or jspPage
parameters are sent with the request, then the doDispatch
method disregards the doView
method entirely and routes directly to the JSP page.
I you would like to run the doView
method on each portlet render, then I suggest to omit these parameters and do the routing yourself in your doView
. Simply invoke the include(path, renderRequest, renderResponse);
method at the end of your doView
, with path
parameter being your desired JSP page path.
Based on your edited question, you may want to try something like this:
MyMVCPortlet.java
public class MyMVCPortlet extends MVCPortlet {
//...
private PortletURL createRedirectURL(ActionRequest actionRequest, String jspPage) {
ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
String portletName = (String) actionRequest.getAttribute(WebKeys.PORTLET_ID);
PortletURL redirectURL = PortletURLFactoryUtil.create(
actionRequest, portletName, themeDisplay.getLayout().getPlid(), PortletRequest.RENDER_PHASE);
redirectURL.setParameter("viewName", jspPage); // note the changed parameter name
return redirectURL;
}
@Override
public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
if(/* ... */) {
// ...
}
String requestedView = renderRequest.getParameter("viewName");
if (StringUtils.isBlank(requestedView)) { // StringUtils comes from commons-lang
include(viewTemplate, renderRequest, renderResponse); // viewTemplate is a protected variable, which may also be called viewJSP depending on Liferay version I think
} else {
include(requestedView, renderRequest, renderResponse);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With