胡长城(银狐999)BLOG

专注SOA,MDA,EAI,BPM,工作流,J2EE;个人主页http://www.javafox.org

胡长城ID:james999
538142次访问,排名70好友0人,关注者39
J2EE,Workflow,BPM,EAI,SOA,工作流
james999的文章
原创 184 篇
翻译 0 篇
转载 2 篇
评论 608 篇
银狐999的公告
个人主要工作流文档可从 javafox live网络硬盘下载

最近评论
oopliu:我把照片的地址输入浏览器,看到老大的娃的照片了。不果,现在娃以及都快1岁了。迟到的祝福。
fredyin:oracle task service会最终到“user name”,如果仅此而已的话还是有问题的,比如说‘A’用户从策划部上调到集团公司了,从主任升迁到副社长了,原来是策划部主任审批的,同步后就变成集团公司的副社长做的了;这种情况自然是不对的,还有其它情况等等;
当然从技术角度是可以实现的,我提出这个问题的重点是我们是否要这样实现,有没有必要这样做,或者我们是否有其它更好的方法实……
LMXEQ5:向CSDN学习
h_154537334:建议阅读这篇文章
http://blog.csdn.net/zhangking/archive/2008/06/18/2562480.aspx
james999:to fredyin:对oracle bpel还没有研究那么深,毕竟我研究只是因为“竞争对手”的原因,时间也不较短。—— 不过,从我目前的了解来看,oracle task service会最终到“user name”,也就是,组织的变更对已经运行流程实例,不会动态更新。如果处理人不存在,oracle bpel会直接按照task complete来处理。
文章分类
收藏
    相册
    50 Relational Blogs
    J2EE与ERP禅话
    Peter's Blog
    俠盜躶奔漢
    切尔斯基(RSS)
    动物园的猪
    胡奇
    赵斌BLog
    阿飞外传
    55 Workflow Preacher
    Ekkart Kindler
    Michael zur Muehlen
    Wil van der Aalst
    存档
    订阅我的博客
    XML聚合  FeedSky

    原创 Liferay Portal额外研究(5):对多分发命令Action的支持(方案一)收藏

    新一篇: Liferay Portal额外研究(6):Portlet附件上传处理的点滴 | 旧一篇: Liferay Portal额外研究(4):修改用户登录后的默认布局和内容


    作者:胡长城(银狐999)
    时间:2006年9月3日晚

         Liferay默认提供的基于Struts Action扩展的PortletAction是不支持多分发命令的,也就是我们一般常用的DispatchAction。但在我们日常基于Struts处理的操作中,已经大量的沿用了DispatchAction处理方式,采用“cmd=queryall”诸如此类的方式。
        本文就来给大家讲解如何通过扩展,让Liferay实现对多分发命令Action的支持。
     
        首先让我们来看看Liferay是如何处理的:
         portlet.xml中,我们一般会配置如下:
    <portlet-class>com.liferay.portlet.StrutsPortlet</portlet-class>
    <init-param>
        
    <name>view-action</name>
        
    <value>/ext/reports/view_reports</value>
    </init-param>
     
           这样Liferay面对一个Portlet请求的时候,会根据请求model来执行Portlet的doView或doEdit方式。当执行doView的时候就会请求其view-action所配置的Action URL所代表的Action来处理。
          其处理流程大致是:Portlet类——〉RequestProcessor——〉StrutsAction处理类
     
         我们可以通过两种扩展方案来实现对多分发的支持:
         方案(一):扩展Liferay的StrutsPortlet类,并写一个DispatchPortletAction类,这样不用扩展RequestProcessor实现。
         方案(二):扩展RequestProcessor与,并写一个DispatchPortletAction类,这样可以直接使用Liferay所提供的StrutsPortlet类。对于RequestProcessor的扩展,在通过portal.properties文件中通过配置“struts.portlet.request.processor”属性来设置。
     
        接下来就两种方案做分别的详细讲解(本篇先讲方案一):
     
    方案(一)
     
    首先让我们写一个DispatchPortletAction类,此类可以通过扩展Liferay本身的PortletAction实现,也可以通过扩展Struts本身的DispatchAction实现。本人是选择后一种方式,这样扩展的代码量较少,都不要自己写execute方式,直接使用基类的即可。
    对于DispatchPortletAction主要扩展dispatchMethod和getMethodName方法。注意在getMechodName方法中,还追加了从request.getAttribute(parameter)获取方法名称,并注意unspecified方法,这个是在没有指明访问方法的时候默认执行的,所以开发人员在后续写自己的Action一定要实现这个。

    public class DispatchPortletAction extends DispatchAction {
        
    protected ActionForward dispatchMethod(ActionMapping mapping,
                ActionForm form, HttpServletRequest request,
                HttpServletResponse response, String name) 
    throws Exception {

            PortletConfig portletConfig 
    = (PortletConfig) request
                    .getAttribute(WebKeys.JAVAX_PORTLET_CONFIG);

            RenderRequest renderRequest 
    = (RenderRequest) request
                    .getAttribute(WebKeys.JAVAX_PORTLET_REQUEST);

            RenderResponse renderResponse 
    = (RenderResponse) request
                    .getAttribute(WebKeys.JAVAX_PORTLET_RESPONSE);

            
    if (name == null{
                
    return this.unspecified(mapping, form, portletConfig,
                        renderRequest, renderResponse);
            }


            Method method 
    = null;
            
    try {
                method 
    = getMethod(name);

            }
     catch (NoSuchMethodException e) {
                String message 
    = messages.getMessage("dispatch.method",
                        mapping.getPath(), name);
                log.error(message, e);

                String userMsg 
    = messages.getMessage("dispatch.method.user",
                        mapping.getPath());
                
    throw new NoSuchMethodException(userMsg);
            }


            ActionForward forward 
    = null;
            
    try {
                Object args[] 
    = { mapping, form, portletConfig, renderRequest,
                        renderResponse }
    ;
                forward 
    = (ActionForward) method.invoke(this, args);

            }
     catch (ClassCastException e) {
                String message 
    = messages.getMessage("dispatch.return",
                        mapping.getPath(), name);
                log.error(message, e);
                
    throw e;

            }
     catch (IllegalAccessException e) {
                String message 
    = messages.getMessage("dispatch.error",
                        mapping.getPath(), name);
                log.error(message, e);
                
    throw e;

            }
     catch (InvocationTargetException e) {
                Throwable t 
    = e.getTargetException();
                
    if (t instanceof Exception) {
                    
    throw ((Exception) t);
                }
     else {
                    String message 
    = messages.getMessage("dispatch.error",
                            mapping.getPath(), name);
                    log.error(message, e);
                    
    throw new ServletException(t);
                }

            }

            
    return (forward);
        }


        
    protected String getMethodName(ActionMapping mapping, ActionForm form,
                HttpServletRequest request, HttpServletResponse response,
                String parameter) 
    throws Exception {

            String methodName 
    = request.getParameter(parameter);
            
    if (methodName == null || methodName.length() == 0{
                 methodName 
    =
     (String) request.getAttribute(parameter);
            }

            
    return methodName;
        }


        
    public ActionForward unspecified(ActionMapping mapping, ActionForm form,
                PortletConfig config, RenderRequest req, RenderResponse res)
                
    throws Exception {
            
    return null;
        }

        
    private static Log log = LogFactory.getLog(DispatchPortletAction.class);
        
    protected Class[] types = { ActionMapping.class, ActionForm.class,
                PortletConfig.
    class, RenderRequest.class, RenderResponse.class }
    ;
    }


            这样后续多分发Action在书写的时候,只需要定义不同的方法即可,但是方法的参数需要依照如下规范,如下一个queryAll的方法:
    public ActionForward queryAll(ActionMapping mapping, ActionForm form,
                PortletConfig config, RenderRequest req, RenderResponse res)
                
    throws Exception {
        
    //业务处理
    //返回ActionForward即可
    }

     
             在那些portlet配置文件的view-action属性中,是不能够增加参数的,比如你不能够采用 /ext/reports/view_reports?cmd=queryAll这种方式。所以我们需要在扩展的Portlet中做一些拦截。
    可能有人会说,我不需要在初始的view-action中增加参数。事实上这个的确不是强制,如果不追加参数,则会访问unspecified方法。但是对于Portlet的显示,其Normal和Max页面显示,都会请求默认的view-action。所以我们需要在Portlet类实现上扩展,于是扩展了一个DispachStrutsPortlet,如下:


    public
     class DispachStrutsPortlet extends StrutsPortlet {

          
    public void doView(RenderRequest req, RenderResponse res)
                                                                       
    throws IOException, PortletException {
                   
    //注意我的命令参数是cmdx,而不是通常的cmd。
                    String cmd = req.getParameter("cmdx");
                    
    if(cmd==null || cmd.length()==0){
                           
    if (req.getWindowState().equals(WindowState. MAXIMIZED)) {
                            req.setAttribute(
    "cmdx","queryAll");
                    }
                    
    super.doView(req, res);
            }
    }
     
    如上面的实现,则表示,如果Portlet是Normal页面状态请求的时候,则在view-action的时候,则仅访问默认的unspecified方法;如果是Max页面状态,则执行queryAll方法。
     
    有一个需要注意的地方,由于“cmd”参数已经被Liferay使用,所以我们需要用另外的变量来表示方法。这里我采用的是“cmdx”。

    发表于 @ 2006年09月03日 22:16:00|评论(loading...)|编辑

    新一篇: Liferay Portal额外研究(6):Portlet附件上传处理的点滴 | 旧一篇: Liferay Portal额外研究(4):修改用户登录后的默认布局和内容

    评论

    #自定义个性化主页 发表于2006-09-04 11:08:00  IP: 222.67.41.*
    最流行的上网方式:
    自定义个人门户(www.googsc.com),
    定制RSS,
    定制收藏网址,
    定制播客,
    个性化服务随便你定制
    #银狐999 发表于2006-09-05 14:16:00  IP: 124.42.18.*
    自我更正本文中的两个严重错误:

    更正一:在此文中,我比较倾向于直接基于Struts DispatchAction扩展,这是错误的,应该尽量基于PortletAction,虽然这样会让扩展增加一些Struts DispatchAction本已有的代码,但是这才是符合Portlet Action处理思想的。并且在Liferay的内部处理中,对于actionurl处理的情况下,是强制必须基于PortletAction扩展的。
    更正二:在此文中,多分发处理的样例代码只侧重对Render的多分发,其实这是不完善的,也容易造成误导。在Porttal的Portlet请求处理,是分为:Action和Render两个阶段的。其实真正的多业务处理更应该在Action阶段来完成,Render则主要负责对push位置和页面数据进行渲染。
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 银狐999