Tuesday, January 18, 2011

Liferay MVC with JSPPortlet

JSPPortlet can be used to quickly develop a Liferay SDK plugin type portlet or even as I demonstrated before migrate one of the existing native portlets to the more agile plugin environment.

My example for the update password portlet was actually still using the original Struts action (UpdatePasswordAction.java).

When further customization is needed we face a problem: Parameters sent to one portlet cannot be retrieved from a second portlet. This is simply correct for a JSR-168 specification implementation. You could go around this issue using JSR-286 public render parameters but there is an alternative which in this case is actually cleaner: Use JSPPortlet MVC capabilities to migrate the extension environment struts portlet java code to a plugin environment implementation.

So let us change then the portlet to show a results page (view) when the passwordis changed instead of keeping the form (edit).

I have committed the code to SVN but for the sake of clarity here are the changes I have made to the Mavenized SDK Plugin Update Password Portlet:
  1. Use two JSPs (view and edit)
  2. Make UpdatePasswordJSPPortlet inherit from the typical com.sample.jsp.portlet.JSPPortlet. The code should be self-explanatory
    package com.sample.jsp.portlet;
    import java.io.IOException;
    import javax.portlet.ActionRequest;
    import javax.portlet.ActionResponse;
    import javax.portlet.PortletException;
    import javax.portlet.PortletSession;
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;
    import javax.servlet.http.HttpServletRequest;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import com.liferay.portal.NoSuchUserException;
    import com.liferay.portal.UserPasswordException;
    import com.liferay.portal.kernel.servlet.SessionErrors;
    import com.liferay.portal.kernel.util.ParamUtil;
    import com.liferay.portal.kernel.util.Validator;
    import com.liferay.portal.security.auth.PrincipalException;
    import com.liferay.portal.service.UserServiceUtil;
    import com.liferay.portal.util.PortalUtil;
    public class UpdatePasswordJSPPortlet extends JSPPortlet {
        private static final String CMD = "cmd";
        public void doDispatch(
                RenderRequest renderRequest, RenderResponse renderResponse)
                throws IOException, PortletException {
            HttpServletRequest request = PortalUtil.getHttpServletRequest(renderRequest);
            HttpServletRequest originalRequest = PortalUtil.getOriginalServletRequest(request);
            String cmd = originalRequest.getParameter(CMD);
            if(Validator.isNull(cmd)) {
                include(editJSP, renderRequest, renderResponse);
            } else {
                if(SessionErrors.isEmpty(request)) {
                    include(viewJSP, renderRequest, renderResponse);
                    include(editJSP, renderRequest, renderResponse);
        public void processAction(ActionRequest actionRequest,
            ActionResponse actionResponse) throws IOException, PortletException {
            String cmd = ParamUtil.getString(actionRequest, CMD);
            if (Validator.isNull(cmd)) {
                    actionResponse.setRenderParameter("error", "cmd is null");
            HttpServletRequest request = PortalUtil.getHttpServletRequest(actionRequest);
            try {
                    updatePassword(actionRequest, actionResponse);
            catch (Exception e) {
                    if (e instanceof UserPasswordException) {
                            SessionErrors.add(request, e.getClass().getName(), e);
                    else if (e instanceof NoSuchUserException ||
                                     e instanceof PrincipalException) {
                            SessionErrors.add(request, e.getClass().getName());
                    else {
                            PortalUtil.sendError(e, actionRequest, actionResponse);
        private void updatePassword(ActionRequest request, ActionResponse response)
                throws Exception {
            PortletSession session = request.getPortletSession();
            long userId = PortalUtil.getUserId(request);
            String password1 = ParamUtil.getString(request, "password1");
            String password2 = ParamUtil.getString(request, "password2");
            boolean passwordReset = false;
            UserServiceUtil.updatePassword(userId, password1, password2,
            session.setAttribute("USER_PASSWORD", password1);
        private static final Log log = LogFactory.getLog(UpdatePasswordJSPPortlet.class);

No comments: