壹佰网|ERP100 - 企业信息化知识门户

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2447|回复: 1

liferay门户系统整合ajax

[复制链接]
发表于 2010/6/2 15:37:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。如果您注册时有任何问题请联系客服QQ: 83569622  。

您需要 登录 才可以下载或查看,没有帐号?注册

x

1,了解portlet render请求处理流程

前边已经有文章对此作了介绍但我们认然将我们要说的内容放在这里

portlet  render请求和portlet action请求的差别是什么呢

1  portlet action 请求会调用portlet.processAction 处理你的任务, 然后再调用res.sendRedirect(String path)。(不论你是否显式调用)

如果你没有直接调用那么他就会调用默认的 portlet render url 。这是它有发出了render请求

2 在调用porlet render 后,liferay 门户同样请求到 com.liferay.portal.action.LayoutAction

     String action = ParamUtil.getString(req, "p_p_action"); 这里的action =0 就是 porlet render请求

     if (action.equals("0")) {

                     _processRenderRequest(req, res); //这里作了些啥工作呢?

     }

    这里其实只是对当前portlet 的state 和mode作了简单的调整 并没有做其他工作

   return mapping.findForward("portal.layout");

   然后他就直接刷新了整个portal ,也就是对整个门户系统的所有portlet都作了render 调用(很恐怖呀!!!)

  你现在知道它为何比较慢了

3 这时我们再细微的对liferay的页面整合做初步的了解

   portal.layout 其实直接请求了/html/portal/layout.jsp

   <c:choose>

    <c:when test='<%= Validator.isNull(ParamUtil.getString(request, "p_p_id")) %>'>

        <liferay-util:include page="<%= Constants.TEXT_HTML_DIR + PortalUtil.getLayoutViewPage(layout) %>" />

    </c:when>

    <ctherwise>

        <liferay-util:include page='<%= Constants.TEXT_HTML_DIR + "/portal/layout/view/portlet.jsp" %>' />

    </c:otherwise>

  </c:choose>

  我们通过了解发现p_p_id 是记录请求portlet id的  。当我们操作的是portal的时候 p_p_id is null

其他情况我们都会调用 /portal/layout/view/portlet.jsp页面


boolean layoutMaximized = layoutTypePortlet.hasStateMax();

if (!layoutMaximized) {

    String content = LayoutTemplateLocalUtil.getContent(layoutTypePortlet.getLayoutTemplateId(), false, theme.getThemeId());

    RuntimePortletUtil.processTemplate(application, pageContext, request, response, content);

}

else {

    String content = null;

    if (themeDisplay.isStateExclusive()) {

        content = LayoutTemplateLocalUtil.getContent("exclusive", true, theme.getThemeId());

    }

    else {

        content = LayoutTemplateLocalUtil.getContent("max", true, theme.getThemeId());

    }

    RuntimePortletUtil.processTemplate(application, pageContext, request, response, StringUtil.split(layoutTypePortlet.getStateMax())[0], content);

}

从这里我们可以看到 LayoutTemplateLocalUtil.getContent ,RuntimePortletUtil.processTemplate


   {

        // 读取模板内容,模板由liferay-layout-templates.xml文件定义.

        String content = LayoutTemplateLocalUtil.getContent(

        layoutTypePortlet.getLayoutTemplateId(), false, theme.getThemeId());


        // 处理模板

        portlet.layoutconfiguration.util.RuntimePortletUtil.processTemplate(

       application, pageContext, request, response, content);

         // 注入模板处理程序

         TemplateProcessor processor = new TemplateProcessor(ctx, req, res, portletId);

         VelocityContext context = new VelocityContext();

         context.put("processor", processor);  

         // 处理模板

         Velocity.evaluate(context, pageContext.getOut(),

          RuntimePortletUtil.class.getName(), content);             这里的信息来自 http://billy.javaeye.com/blog/35822

   portlet.layoutconfiguration.util.RuntimePortletUtil 这里是

public static void processTemplate(

            ServletContext ctx, PageContext pageContext, HttpServletRequest req,

            HttpServletResponse res, String portletId, String content)

        throws Exception {

        if (Validator.isNull(content)) {

            return;

        }

        //处理模板

        TemplateProcessor processor =

            new TemplateProcessor(ctx, req, res, portletId);

        VelocityContext vc = new VelocityContext();

        //注入模板

        vc.put("processor", processor);

        VelocityVariables.insertVariables(vc, ctx, req, pageContext);

        StringWriter sw = new StringWriter();

        try {

            //处理模板

            Velocity.evaluate(

                vc, sw, RuntimePortletUtil.class.getName(), content);

        }

        catch (Exception e) {

            _log.error(StackTraceUtil.getStackTrace(e));

            throw e;

        }


        String output = sw.toString();

        //获取 column信息

        Map columnsMap = processor.getColumnsMap();

        Iterator itr = columnsMap.entrySet().iterator();

        while (itr.hasNext()) {

            Map.Entry entry = (Map.Entry)itr.next();

            String key = (String)entry.getKey();

            String value = (String)entry.getValue();


            output = StringUtil.replace(output, key, value);

        }

         //这是新的带有portlet 具体位置的模板 output


        //取得当前页的portlet

        Map portletsMap = processor.getPortletsMap();

        itr = portletsMap.entrySet().iterator();

        while (itr.hasNext()) {

            Map.Entry entry = (Map.Entry)itr.next();

            Portlet portlet = (Portlet)entry.getKey();

            Object[] value = (Object[])entry.getValue();

            String rootPortletId = (String)value[0];

            String instanceId = (String)value[1];

            String queryString = (String)value[2];

            String columnId = (String)value[3];

            Integer columnPos = (Integer)value[4];

            Integer columnCount = (Integer)value[5];

            StringBuffer sb = new StringBuffer();

            //处理单独的一个portlet信息

            RuntimePortletUtil.processPortlet(

                sb, ctx, req, res, null, null, rootPortletId, instanceId,

                queryString, columnId, columnPos, columnCount);


            output = StringUtil.replace(

                output, "[$TEMPLATE_PORTLET_" + portlet.getPortletId() + "$]",

                sb.toString());

        }

       //产生最后的页面

        pageContext.getOut().print(output);

    }


   在 处理RuntimePortletUtil.processPortlet时

   public static void processPortlet(

            StringBuffer sb, ServletContext ctx, HttpServletRequest req,

            HttpServletResponse res, RenderRequest renderRequest,

            RenderResponse renderResponse, String portletId, String instanceId,

            String queryString, String columnId, Integer columnPos,

            Integer columnCount, String path)

        throws Exception {

       //。。。portlet的一些初始化信息

        try {

           //对portlet发出render请求

            PortalUtil.renderPortlet(

                sb, ctx, req, res, portlet, queryString, columnId, columnPos,

                columnCount, path);

        }

        finally {

            portletDisplay.copyFrom(portletDisplayClone);

            try {

                PortletDisplayFactory.recycle(portletDisplayClone);

            }

            catch (Exception e) {

                _log.error(e);

            }

            _defineObjects(

                req, portletConfig, renderRequest, renderResponse);

        }

    }

   Render portlet 请求的页面 PortalUtil.renderPortlet(

   public static void renderPortlet(

            StringBuffer sb, ServletContext ctx, HttpServletRequest req,

            HttpServletResponse res, Portlet portlet, String queryString,

            String columnId, Integer columnPos, Integer columnCount,

            String path)

        throws IOException, ServletException {

         //...初始话porlet的一些参数

        //其实path就一直为null

        if (path == null) {

            path = "/html/portal/render_portlet.jsp"; //其实render_portlet.jsp是请求portlet的具体实施者

        }

        //根据上边的参数 我们可以获得portlet的页面片段

        RequestDispatcher rd = ctx.getRequestDispatcher(path);

        if (sb != null) {

            StringServletResponse stringServletRes =

                new StringServletResponse(res);

            rd.include(req, stringServletRes);

            //将页面片段返回去用于拼整个页面

            sb.append(stringServletRes.getString());

        }

        else {

            // LEP-766 情况

        }

    }

我们终于找到 render_portlet.jsp

在这里我们看的了我们需要的信息


//对porlet实施render 请求

cachePortlet.render(renderRequestImpl, renderResponseImpl);

4,那么如何实现ajax请求呢   

   改造整个liferay门户系统的工程实现ajax看上去有点大,但在portlet的局部实现ajax,是我现在的目标。

就是说我在我的portlet里的view或edit里的连接或按钮,可以使用脚本请求服务器然后返回我一个页面片段让我刷新我的portlet的内容。这个要求,我想本不过分。但是如果不改造liferay的话,我们是没法实现的。因为我们在页面处理上需要门户系统的一些信息

比如  <portlet:namespace />

  那么我现就开始改造了

  com.liferay.portal.action.LayoutAction


public class LayoutAction extends Action {

    public ActionForward 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");

        //在请求是增加参数 使用Ajax技术

        String ajaxs=ParamUtil.getString(req, "p_p_ajax");

        boolean ajax=ajaxs==null?falseajaxs.equals("true")?true:false);

        if (Validator.isNotNull(plid)) {

            try {

                if (action.equals("1")) {

                  //action 部分

                  。。。

                }

                else if (action.equals("0")) {

                     _processRenderRequest(req, res);

                    //Ajax页面直接返回

                    _log.debug("ajax -----------flag"+ajax);

                    if (ajax)

                    {

                        //res.getWriter().

                        return null;

                    }

                }


                return mapping.findForward("portal.layout");

            }

            catch (Exception e) {

                req.setAttribute(PageContext.EXCEPTION, e);

                return mapping.findForward(Constants.COMMON_ERROR);

            }

            finally {

                try {

                    if (action.equals("1")) {

                        ActionRequestImpl actionRequestImpl =

                            (ActionRequestImpl)req.getAttribute(

                                WebKeys.JAVAX_PORTLET_REQUEST);

                        ActionRequestFactory.recycle(actionRequestImpl);

                    }

                }

                catch (Exception e) {

                    _log.error(e);

                }

                try {

                    if (action.equals("1")) {

                        ActionResponseImpl actionResponseImpl =

                            (ActionResponseImpl)req.getAttribute(

                                WebKeys.JAVAX_PORTLET_RESPONSE);

                        ActionResponseFactory.recycle(actionResponseImpl);

                    }

                }

                catch (Exception e) {

                    _log.error(e);

                }

                //如果是ajax也需要关闭

                try{

                    if (ajax)

                    {

                        RenderRequestImpl renderRequestImpl =

                            (RenderRequestImpl)req.getAttribute(

                                WebKeys.JAVAX_PORTLET_REQUEST);

                        RenderRequestFactory.recycle(renderRequestImpl);


                    }

                }catch(Exception e){

                    _log.error(e);

                }

                try{

                    RenderResponseImpl renderResponseImpl =

                        (RenderResponseImpl)req.getAttribute(

                            WebKeys.JAVAX_PORTLET_RESPONSE);

                    RenderResponseFactory.recycle(renderResponseImpl);

                }

                catch(Exception e)

                {_log.error(e);


                }



            }

        }

        else {

            try {

                _forwardLayout(req);

                return mapping.findForward(Constants.COMMON_FORWARD);

            }

            catch (Exception e) {

                req.setAttribute(PageContext.EXCEPTION, e);

                return mapping.findForward(Constants.COMMON_ERROR);

            }

        }

    }

    private Portlet _processPortletRequest(

            HttpServletRequest req, HttpServletResponse res, boolean action)

        throws Exception {

        //同样需要判断

        String ajax=ParamUtil.getString(req, "p_p_ajax");


       。。。

        if (action) {

                 。。。//action 部分

        }

        else {

            PortalUtil.updateWindowState(

                portletId, user, layout, windowState, req);

            PortalUtil.updatePortletMode(portletId, user, layout, portletMode);

            //从这里开始

            _log.debug("ajax------------2");

            //ajax的情况就是这样

            if (ajax!=null&&ajax.equals("true"))

            {

                _log.debug("ajax------------2"+ajax);

                //调用catchePortlet.render

                String queryString = (String)req.getAttribute(WebKeys.RENDER_PORTLET_QUERY_STRING);

              //创建 renderRequestImpl

                RenderRequestImpl renderRequestImpl = RenderRequestFactory.create(req, portlet, cachePortlet, portletCtx, windowState, portletMode, prefs, layout.getPlid());

                if (Validator.isNotNull(queryString)) {

                    DynamicServletRequest dynamicReq = (DynamicServletRequest)renderRequestImpl.getHttpServletRequest();

                    String[] params = StringUtil.split(queryString, StringPool.AMPERSAND);

                    for (int i = 0; i < params.length; i++) {

                        String[] kvp = StringUtil.split(params, StringPool.EQUAL);

                        dynamicReq.setParameter(kvp[0], kvp[1]);

                    }

                }

                StringServletResponse stringServletRes = new StringServletResponse(res);

               //创建renderResponseImpl

                RenderResponseImpl renderResponseImpl = RenderResponseFactory.create(renderRequestImpl, stringServletRes, portletId,companyId,layout.getPlid());

                renderRequestImpl.defineObjects(portletConfig, renderResponseImpl);

               //发出请求

                cachePortlet.render(renderRequestImpl, renderResponseImpl);

                SessionMessages.clear(renderRequestImpl);

                SessionErrors.clear(renderRequestImpl);

            //    _log.error("sxinfo----------ajax"+stringServletRes.getString());

                //返回请求的页面片段

                res.getWriter().print(stringServletRes.getString());            

//到这里结束

            }   

        }

        return portlet;

    }

}

发表于 2012/8/31 11:15:36 | 显示全部楼层
强啊,受益了

QQ|Archiver|小黑屋|手机版|壹佰网 ERP100 ( 京ICP备19053597号-2 )

Copyright © 2005-2012 北京海之大网络技术有限责任公司 服务器托管由互联互通
手机:13911575376
网站技术点击发送消息给对方83569622   广告&合作 点击发送消息给对方27675401   点击发送消息给对方634043306   咨询及人才点击发送消息给对方138011526

GMT+8, 2025/11/30 02:59 , Processed in 0.017610 second(s), 15 queries , File On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表