Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Liferay portlet doView() after redirect

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);
    }
}
like image 228
dimitar.yanev Avatar asked Aug 04 '14 10:08

dimitar.yanev


1 Answers

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);
        }
    }
}
like image 128
Michal M Avatar answered Oct 14 '22 14:10

Michal M