转文:liferay portlet之间的通信

7月没写什么玩意,转文过了充数!!!

Liferay Portlet之间的通信

关键字: liferay portlet之间的通信


本文来自:http://tyler-zhou.javaeye.com/blog/506707

 

从我做Liferay到现在,这个问题一直都存在着,直到最近我才算是 找到了一个可靠的方案,能够满足各种需求,从我最开始做到现在一共用到了四种方案,从低到高,我们一个一个的讲。


一、通过URL传值
    这个是我在项目中第一次遇到这样的问题,找出的一个方案,原理就是A把B需要的参数加在自已生成的URL后面,然后再把整个页面view一次,B根据取得 的参数再做相应的处理,取URL参数代码如下:

Java代码
  1. public  class  CurrentURLUtil {  
  2.   
  3. public  static  Log log = LogFactory.getLog(CurrentURLUtil.class );  
  4.   
  5. public  static  int  contain(String currentURL, String param) {  
  6.     return  currentURL.indexOf(param);  
  7. }  
  8.   
  9. public  static  String getString(String currentURL, String param) {  
  10.   
  11.     try  {  
  12.         int  paramIndex = contain(currentURL, param);  
  13.   
  14.         if  (paramIndex == -1 ) {  
  15.             // log.warn("CurrentURL don't contain the parameter that name   
  16.             // is:"+param+",and method will return a blank");   
  17.             return  "" ;  
  18.         } else  {  
  19.             int  afaterParamSperatorIndex = currentURL.indexOf("&" , paramIndex+1 );  
  20.   
  21.             if  (afaterParamSperatorIndex == -1 ) {  
  22.                 return  currentURL.substring(paramIndex + param.length() + 1 );  
  23.             } else   
  24.                 return  currentURL.substring(paramIndex + param.length() + 1 ,  
  25.                         afaterParamSperatorIndex);  
  26.         }  
  27.     } catch  (RuntimeException e) {  
  28.         // TODO Auto-generated catch block   
  29.         return  "" ;  
  30.     }  
  31. }  
  32.   
  33.   
  34. public  static  String getString(String currentURL, String param, String defaultStr) {  
  35.       
  36.     String value = getString(currentURL, param);  
  37.       
  38.     if (Validator.isNull(value))  
  39.         return  defaultStr;  
  40.     else   
  41.         return  value;  
  42.       
  43. }  
  44.   
  45. public  static  long  getLong(String currentURL, String param) {  
  46.     String value = getString(currentURL, param);  
  47.     if  (null  == value || value.trim().equals("" )) {  
  48.         return  0 ;  
  49.     } else  if (Validator.isNumber(value))  
  50.         return  Long.parseLong(value);  
  51.     else   
  52.         return  0 ;  
  53. }  
	public class CurrentURLUtil {

	public static Log log = LogFactory.getLog(CurrentURLUtil.class);

	public static int contain(String currentURL, String param) {
		return currentURL.indexOf(param);
	}

	public static String getString(String currentURL, String param) {

		try {
			int paramIndex = contain(currentURL, param);

			if (paramIndex == -1) {
				// log.warn("CurrentURL don't contain the parameter that name
				// is:"+param+",and method will return a blank");
				return "";
			} else {
				int afaterParamSperatorIndex = currentURL.indexOf("&", paramIndex+1);

				if (afaterParamSperatorIndex == -1) {
					return currentURL.substring(paramIndex + param.length() + 1);
				} else
					return currentURL.substring(paramIndex + param.length() + 1,
							afaterParamSperatorIndex);
			}
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			return "";
		}
	}
	

	public static String getString(String currentURL, String param, String defaultStr) {
		
		String value = getString(currentURL, param);
		
		if(Validator.isNull(value))
			return defaultStr;
		else
			return value;
		
	}

	public static long getLong(String currentURL, String param) {
		String value = getString(currentURL, param);
		if (null == value || value.trim().equals("")) {
			return 0;
		} else if(Validator.isNumber(value))
			return Long.parseLong(value);
		else
			return 0;
	}

}
 

    这种方法有比较多的缺陷,比如传的参数只能是string,如果是map,list,大数据就不可行了,另外还有一个问题,安全性不高,你无法预料到这个 页面上有多少portlet,每个portlet会有多少操作,而每个操作都会产生一个url,会不会出现相同key?出错的机率较高。

、通过session传值
    这种方式和第一种方式原理都是相同的,只不过要安全一些。A触发一个action,在action里面把自已要处理的工作做完了后,把B需要的东西放在 session里面,B在render里面去取这些东西,然后来完成自已的工作,或者就在JSP里面完成这些工作。但是这样就出现了一个问题,你无法知道 A先处理完还是B先处理完,解决的这个问题的方法有两个,一个是让B在处理之间等待一段时间,这个时间A一定能把工作完成,另外一个方法是用锁的方式来解 决,建一个static map<SessionId, Boolean>,A负责开锁,B负责锁上,两个千万不能搞错,当锁为空或false时,B就去等侍,直到锁打开。但是一定要记得在B处理完成后把 锁销毁。这种方式,我也只在项目中用过一次。

三、通过模拟B的PortletURL
    后面两种方式也是我最近半年来才学会的,应该是安全的。先上一段代码是模拟B的PortletURL的关键

Java代码
  1. private  static  long  _getPlidFromPortletId(HttpServletRequest request, long  groupId,   
  2.             boolean  isPrivate, String portletId, Entry<String, String>... entry) {  
  3.           
  4.         long  plid = 0 ;  
  5.         if  (entry == null ) {  
  6.             plid = PortalUtil.getPlidFromPortletId(groupId, isPrivate, portletId);  
  7.             if (Validator.isNull(plid))  
  8.                 plid = Long.valueOf(0 );  
  9.         } else  {  
  10.             try  {  
  11.                 List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(groupId, isPrivate, LayoutConstants.TYPE_PORTLET);  
  12.                 for  (Layout layout : layouts) {  
  13.                     LayoutTypePortlet layoutTypePortlet =  
  14.                         (LayoutTypePortlet)layout.getLayoutType();  
  15.   
  16.                     if  (layoutTypePortlet.hasPortletId(portletId)) {  
  17.                         if  (PortalUtil.getScopeGroupId(layout, portletId) == groupId) {  
  18.                             plid = layout.getPlid();  
  19.                               
  20.                             List<PortletPreferences> list = PortletPreferencesLocalServiceUtil  
  21.                                 .getPortletPreferences(plid, portletId);  
  22.                             if  (Validator.isNotNull(list)) {  
  23.                                 for  (PortletPreferences pre : list) {  
  24.                                       
  25.                                     int  i = 0 ;  
  26.                                     if  (entry.length < 1 ){  
  27.                                         plid = pre.getPlid();  
  28. //                                      _plidCache.put(key, plid);   
  29.                                         return  plid;  
  30.                                     }  
  31.                                       
  32.                                     javax.portlet.PortletPreferences jpre = PortletPreferencesSerializer  
  33.                                             .fromXML(PortalUtil.getCompanyId(request), pre  
  34.                                                     .getOwnerId(), pre.getOwnerType(), plid,  
  35.                                                     portletId, pre.getPreferences());  
  36.                                     for  (; i < entry.length; i++) {  
  37.                                         Entry en = entry[i];  
  38.                                         if  (!jpre.getValue(en.getKey().toString(),  
  39.                                                 StringPool.BLANK).equals(  
  40.                                                 en.getValue().toString()))  
  41.                                             break ;  
  42.                                     }  
  43.                                     if  (i == entry.length){  
  44.                                         plid = pre.getPlid();  
  45. //                                      _plidCache.put(key, plid);   
  46.                                         return  plid;  
  47.                                     }  
  48.                                 }  
  49.                             }  
  50.                         }  
  51.                     }  
  52.                 }  
  53.             } catch  (SystemException e) {  
  54.                 // TODO Auto-generated catch block   
  55.                 e.printStackTrace();  
  56.             }  
  57.         }  
  58.         return  plid;  
  59.     }  
  60.   
  61.     public  static  PortletURL getPortletURL(long  groupId, String portletId,  
  62.             HttpServletRequest request, Entry<String, String>... entry) {  
  63.   
  64.         long  plid = _getPlidFromPortletId(request, groupId, false , portletId, entry);  
  65.         return  new  PortletURLImpl(request, portletId, plid,  
  66.                 PortletRequest.RENDER_PHASE);  
  67.     }  
  68.       
  69.     public  static  PortletURL getPortletURL(long  groupId, long  plid, String portletId,  
  70.             HttpServletRequest request, Entry<String, String>... entry) {  
  71.         return  new  PortletURLImpl(request, portletId, plid,  
  72.                 PortletRequest.RENDER_PHASE);  
  73.     }  
private static long _getPlidFromPortletId(HttpServletRequest request, long groupId, 
			boolean isPrivate, String portletId, Entry<String, String>... entry) {
		
		long plid = 0;
		if (entry == null) {
			plid = PortalUtil.getPlidFromPortletId(groupId, isPrivate, portletId);
			if(Validator.isNull(plid))
				plid = Long.valueOf(0);
		} else {
			try {
				List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(groupId, isPrivate, LayoutConstants.TYPE_PORTLET);
				for (Layout layout : layouts) {
					LayoutTypePortlet layoutTypePortlet =
						(LayoutTypePortlet)layout.getLayoutType();

					if (layoutTypePortlet.hasPortletId(portletId)) {
						if (PortalUtil.getScopeGroupId(layout, portletId) == groupId) {
							plid = layout.getPlid();
							
							List<PortletPreferences> list = PortletPreferencesLocalServiceUtil
								.getPortletPreferences(plid, portletId);
							if (Validator.isNotNull(list)) {
								for (PortletPreferences pre : list) {
									
									int i = 0;
									if (entry.length < 1){
										plid = pre.getPlid();
//										_plidCache.put(key, plid);
										return plid;
									}
									
									javax.portlet.PortletPreferences jpre = PortletPreferencesSerializer
											.fromXML(PortalUtil.getCompanyId(request), pre
													.getOwnerId(), pre.getOwnerType(), plid,
													portletId, pre.getPreferences());
									for (; i < entry.length; i++) {
										Entry en = entry[i];
										if (!jpre.getValue(en.getKey().toString(),
												StringPool.BLANK).equals(
												en.getValue().toString()))
											break;
									}
									if (i == entry.length){
										plid = pre.getPlid();
//										_plidCache.put(key, plid);
										return plid;
									}
								}
							}
						}
					}
				}
			} catch (SystemException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return plid;
	}

	public static PortletURL getPortletURL(long groupId, String portletId,
			HttpServletRequest request, Entry<String, String>... entry) {

		long plid = _getPlidFromPortletId(request, groupId, false, portletId, entry);
		return new PortletURLImpl(request, portletId, plid,
				PortletRequest.RENDER_PHASE);
	}
	
	public static PortletURL getPortletURL(long groupId, long plid, String portletId,
			HttpServletRequest request, Entry<String, String>... entry) {
		return new PortletURLImpl(request, portletId, plid,
				PortletRequest.RENDER_PHASE);
	}

      根据上面代码能看出,最关键是要取得plid,如果你两个需要通信的portlet在一个页面上,那就省了大事了,不然你就要去调用 _getPlidFromPortletId这个,最后一个参数是为了匹配这个portlet的configartion信息,因为一个网站有十几个页 面,可能其中三个页面会有这一个portlet,增加这个参数能提高准确性,但是影响性能。PortletURL得到了,那后面的事就好办了,如果你是A 只是为了传信息本身不做任何处理,把参数放到PortletURL里,然后用<a href="<%=PortletURL.toString()%>">就可以了,如果A要做完自已的工作再传,那就以Action里 面做完自已的工作,然后sendRedirect到PortletURL.toString()就可以了。这种方式应该是比较安全可靠的,并且我在几个项 目中都已经实施过了。注意 :此方案仅能支持B属性<instanceable>false</instanceable>的portlet

四、通过jQuery.ajax异步通信

    这个是最新的一个方案,目前正在进行的项目我用了这个方案,其基本思想是:A后台通知B去工作,然后A前台让B显示工作结果,这个方案比较酷。具体实现 如下:


    1.A通过jQuery.ajax去请求B的jsonAction(参照前面Liferay异步提交文章)


    2.然后根据返回结果让B显示处理结果(参照前面Liferay异步刷新文章中的第二种类型)


    注:如果你A也要处理工作,那就让A先处理然后根据结果再调用B的jsonAction,最后让A和B都分别显示各自的工作结果。当然你也可以把A和B 要做的工作都放在一个jsonAction里面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值