liferay中portlet action的处理流程

本文用一个实例来说明liferay中portlet action的处理流程.

在liferay的演示网站上随便输入用户名/密码提交后,就可以如下的一个url.
 http://demo.liferay.net/c/portal/layout?p_l_id=PUB.1001.1
  &p_p_id=58
  &p_p_action=1
  &p_p_state=normal
  &p_p_mode=view
  &p_p_col_id=column-1
  &p_p_col_pos=0
  &p_p_col_count=1
  &_58_struts_action=%2Flogin%2Fview
  &_58_cmd=update
  &#p_58

在liferay中,是用struts来做FrontController的,
 〈action path="/portal/layout" type="com.liferay.portal.action.LayoutAction"〉
   〈forward name="portal.layout" path="portal.layout" /〉
 〈/action〉

LayoutAction

 LayoutAction.execute(ActionMapping mapping, ActionForm form,
 HttpServletRequest req, HttpServletResponse res)
  throws Exception {

   String plid = ParamUtil.getString(req, "p_l_id");
   String action = ParamUtil.getString(req, "p_p_action");

   if (Validator.isNotNull(plid)) {
      try {
         if (action.equals("1")) { // 处理action请求.
            _processActionRequest(req, res);

            ActionResponseImpl actionResponseImpl =
                  (ActionResponseImpl)req.getAttribute(WebKeys.JAVAX_PORTLET_RESPONSE);
            String redirectLocation = actionResponseImpl.getRedirectLocation();

            if (Validator.isNotNull(redirectLocation)) {
               res.sendRedirect(redirectLocation);
               return null;
            }

            if (LiferayWindowState.isExclusive(req)) {
               return null;
            }
         }
         else if (action.equals("0")) { // 处理render请求.
            _processRenderRequest(req, res);
         }
         return mapping.findForward("portal.layout");
      } catch (Exception e) {
         req.setAttribute(PageContext.EXCEPTION, e);
         return mapping.findForward(Constants.COMMON_ERROR);
      } finally {
         // 清理工作。
      }
   } else {
      try {
         _forwardLayout(req);
         return mapping.findForward(Constants.COMMON_FORWARD);
      } catch (Exception e) {
         req.setAttribute(PageContext.EXCEPTION, e);
         return mapping.findForward(Constants.COMMON_ERROR);
      }
   }
 }

 Layout._processPortletRequest(
    HttpServletRequest req, HttpServletResponse res, boolean action)
      throws Exception {

      HttpSession ses = req.getSession();

      // 查找portlet.
      String companyId = PortalUtil.getCompanyId(req);
      User user = PortalUtil.getUser(req);
      Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
      String portletId = ParamUtil.getString(req, "p_p_id");

      Portlet portlet = PortletLocalServiceUtil.getPortletById(
   companyId, portletId);

      ServletContext ctx = (ServletContext)req.getAttribute(WebKeys.CTX);

      CachePortlet cachePortlet = PortletInstanceFactory.create(portlet, ctx);

      if (user != null) {
         CachePortlet.clearResponse(ses, layout.getPrimaryKey(), portletId);
      }

      PortletPreferencesPK prefsPK =
         PortletPreferencesFactory.getPortletPreferencesPK(req, portletId);

      PortletPreferences prefs =
         PortletPreferencesLocalServiceUtil.getPreferences(companyId, prefsPK);

      // portlet配置及上下文.
      PortletConfig portletConfig = PortletConfigFactory.create(portlet, ctx);
      PortletContext portletCtx = portletConfig.getPortletContext();

      // window状态.
      WindowState windowState = new WindowState(ParamUtil.getString(req, "p_p_state"));
      // portlet模式.
      PortletMode portletMode = new PortletMode(ParamUtil.getString(req, "p_p_mode"));

      if (action) {  // 处理action.
         ActionRequestImpl actionRequestImpl = ActionRequestFactory.create(
            req, portlet, cachePortlet, portletCtx, windowState,
            portletMode, prefs, layout.getPlid());

         ActionResponseImpl actionResponseImpl =
            ActionResponseFactory.create(
               actionRequestImpl, res, portletId, user, layout,
               windowState, portletMode);

         actionRequestImpl.defineObjects(portletConfig, actionResponseImpl);

         cachePortlet.processAction(actionRequestImpl, actionResponseImpl);

         RenderParametersPool.put(req, layout.getPlid(), portletId,
            actionResponseImpl.getRenderParameters());
      } else { // 处理render.
         PortalUtil.updateWindowState(portletId, user, layout, windowState, req);
         PortalUtil.updatePortletMode(portletId, user, layout, portletMode);
      }
   }
   CachePortlet对普通Portlet进行了包装,加入了cache处理,

CachePortlet

 CachePortlet.processAction(ActionRequest req, ActionResponse res)
  throws IOException, PortletException {
       _invoke(req, res, true);
    }

 CachePortlet._invoke(
      PortletRequest req, PortletResponse res, boolean action)
         throws IOException, PortletException {

      Map properties = null;

      if (_portletConfig.isWARFile()) { // 如果Portlet是外部war整合方式的,则转发请求.
         String path = StringPool.SLASH + _portletConfig.getPortletName() + "/invoke";

         RequestDispatcher rd = _portletCtx.getServletContext().getRequestDispatcher(path);

         HttpServletRequest httpReq = null;
         HttpServletResponse httpRes = null;

         ActionRequestImpl actionReqImpl = null;
         ActionResponseImpl actionResImpl = null;
     
         RenderRequestImpl renderReqImpl = null;
         RenderResponseImpl renderResImpl = null;

         if (action) {
            actionReqImpl = (ActionRequestImpl)req;
            actionResImpl = (ActionResponseImpl)res;

            httpReq = actionReqImpl.getHttpServletRequest();
            httpRes = actionResImpl.getHttpServletResponse();
         } else {
            renderReqImpl = (RenderRequestImpl)req;
            renderResImpl = (RenderResponseImpl)res;

            httpReq = renderReqImpl.getHttpServletRequest();
            httpRes = renderResImpl.getHttpServletResponse();
         }

         httpReq.setAttribute(WebKeys.JAVAX_PORTLET_PORTLET, _portlet);

         try {
            rd.include(httpReq, httpRes);
         } catch (ServletException se) {
            // 重新抛出异常.
         }

         if (action) {
            properties = actionResImpl.getProperties();
         } else {
            properties = renderResImpl.getProperties();
         }
      } else { // Portlet是liferay内部整合方式的,直接交由_portlet处理。
         if (action) {
            ActionRequestImpl actionReqImpl = (ActionRequestImpl)req;
            ActionResponseImpl actionResImpl = (ActionResponseImpl)res;

            _portlet.processAction(actionReqImpl, actionResImpl);

            properties = actionResImpl.getProperties();
         } else {
            RenderRequestImpl renderReqImpl = (RenderRequestImpl)req;
            RenderResponseImpl renderResImpl = (RenderResponseImpl)res;

            _portlet.render(renderReqImpl, renderResImpl);

            properties = renderResImpl.getProperties();
         }
      }

      if ((properties != null) && (properties.size() > 0)) {
         if (_expCache != null) {
            String[] expCache = (String[])properties.get(RenderResponse.EXPIRATION_CACHE);
            if ((expCache != null) && (expCache.length > 0) && (expCache[0] != null)) {
               _expCache = new Integer(GetterUtil.getInteger(expCache[0]));
            }
         }
      }
   }
   在这里,Login portlet是liferay内部整合方式的,
   通过portlet.xml文件和它的portletId,找到它的实现类是StrutsPortlet.

StrutsPortlet

 StrutsPortlet.processAction(ActionRequest req, ActionResponse res)
      throws IOException, PortletException {

   String path = req.getParameter("struts_action"); // 这里为/login/view
   if (Validator.isNotNull(path)) {
      // Call processAction of com.liferay.portal.struts.PortletAction
      PermissionChecker checker = PermissionThreadLocal.getPermissionChecker();
      try {
         checker.setValues(req);
         // Process action
         PortletRequestProcessor processor = _getPortletRequestProcessor(req);
         processor.process(req, res, path);
      } catch (ServletException se) {
         throw new PortletException(se);
      } finally {
         checker.resetValues();
      }
   }
   if (copyRequestParameters) {
      PortalUtil.copyRequestParameters(req, res);
   }
 }

 // /login/view定义.
  〈action path="/login/view" type="com.liferay.portlet.login.action.ViewAction"〉
     〈forward name="portlet.login.view" path="portlet.login.view" /〉
  〈/action〉

PortletRequestProcessor

 PortletRequestProcessor.process(ActionRequest req, ActionResponse res, String path)
  throws IOException, ServletException {

   ActionRequestImpl reqImpl = (ActionRequestImpl)req;
   ActionResponseImpl resImpl = (ActionResponseImpl)res;

   HttpServletRequest httpReq = reqImpl.getHttpServletRequest();
   HttpServletResponse httpRes = resImpl.getHttpServletResponse();

   ActionMapping mapping = processMapping(httpReq, httpRes, path);

   if (mapping == null) {
      return;
   }

   // processRoles处理,略...

   ActionForm form = processActionForm(httpReq, httpRes, mapping);

   processPopulate(httpReq, httpRes, form, mapping);

   if (!processValidateAction(httpReq, httpRes, form, mapping)) {
      return;
   }

   // 构建ViewAction.
   PortletAction action =
      (PortletAction)processActionCreate(httpReq, httpRes, mapping);

   if (action == null) {
      return;
   }

   PortletConfigImpl portletConfig =
      (PortletConfigImpl)req.getAttribute(WebKeys.JAVAX_PORTLET_CONFIG);

   // 处理action.
   try {
      action.processAction(mapping, form, portletConfig, req, res);
   }
   catch (Exception e) {
      String exceptionId = WebKeys.PORTLET_STRUTS_EXCEPTION +
         StringPool.PERIOD + portletConfig.getPortletId();

      req.setAttribute(exceptionId, e);
   }

   // 处理forward, 略...

ViewAction

 ViewAction.processAction(
   ActionMapping mapping, ActionForm form, PortletConfig config,
   ActionRequest req, ActionResponse res) throws Exception {

   String cmd = req.getParameter(Constants.CMD); // update

   ThemeDisplay themeDisplay =
      (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);

   if (req.getRemoteUser() != null) { // 已经登录,直接redirect.
      res.sendRedirect(themeDisplay.getPathMain());
   }
   else if (Validator.isNotNull(cmd)) {
      try {
         _login(themeDisplay, req, res);  // 登录处理.
      } catch (Exception e) {
         // 异常处理.
      }
   }
 }

 ViewAction._login(
   ThemeDisplay themeDisplay, ActionRequest req, ActionResponse res)
      throws Exception {

      ActionRequestImpl reqImpl = (ActionRequestImpl)req;
      ActionResponseImpl resImpl = (ActionResponseImpl)res;

      HttpServletRequest httpReq = reqImpl.getHttpServletRequest();
      HttpServletResponse httpRes = resImpl.getHttpServletResponse();

      String login = ParamUtil.getString(req, "login");
      String password = ParamUtil.getString(req, "password");
      boolean rememberMe = ParamUtil.getBoolean(req, "rememberMe");

      LoginAction.login(httpReq, httpRes, login, password, rememberMe);

      res.sendRedirect(themeDisplay.getPathMain() + "/portal/protected");
  }

  LoginAction.login的处理这里就不说明了,请查看源码,

以上就是liferay中portlet的action处理流程了。

有关在liferay中以外部war方式整合的portlet的处理流程,请关注我的后续文章。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值