论坛首页 Java企业应用论坛

整合Liferay Portal和GWT

浏览 8423 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-02-24  

Portal 是一种非常棒的web2.0技术,它基于JSR168 Java Portlet规范, 用户可以根据自己的喜好加载所需的Portlet。它提供给用户非常个性化的用户体验。
GWT 是一种由Google公司所开发的基于Java的Web框架技术,用于开发全Ajax应用程序。

如何让这两种诱人的技术整合在一起就是我所感兴趣的,同样也是这篇文章所要探讨的主题。现有的主流Portal平台技术有Liferay, Jboss Portal, JetSpeed-2,exo等,而这篇文章将会着重介绍如何使用Liferay Portal来整合GWT。

首先你必须要安装好GWT,你可以在Google Code网站上下载到GWT的最新版本http://code.google.com/webtoolkit/
本例子里使用的是gwt-windows-1.4.60版本。直到我发布Blog文章时GWT的最新版本为gwt-windows-1.4.61。我看过了ChangeLog其实只是更改了一些在Mac下的bugs,并没有太大的改动。所以我暂时没有更新。

其次就是要安装Portal平台了,之前已经说过主流的Portal平台技术有Liferay, Jboss Portal, JetSpeed-2, exo。其实每一个Portal都可以和GWT整合,我最初做的整合的Example就是在JBoss Portal上(说实话在所有的Portal平台中我最喜欢的就是JBoss Portal),之后在每个平台上都成功的整合了。因为考虑到国内大多数Portal开发者都习惯使用Liferay,所以在这里就探讨一下 Liferay于GWT的整合方式。 Liferay Portal是一个基于MIT License的免费的开源Portal项目,你可以在Liferay的官方网站上下载到http://www.liferay.com/。最新的版本是在2008年2月份才发布的Liferay Portal 4.4.0。我也是更新到了这个最新版本的Tomcat5.5.20绑定版。

接下来我就根据我制作的一个简单的时钟的Example,来说明整合实现的方式(例子可以在文章底部下载到)


项目结构
整合Portal与GWT的Example

 

 

GWT客户端的实现方式:

 

package mqj.web.coral.client;

import mqj.web.coral.client.rpc.CoralService;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * @author maqujun
 * 
 */
public class Coral implements EntryPoint {
        /** Timer is a serialized object of GWT */
	private Timer timer;
	private Label label = new Label("Wait...");

        /**
	 * GWT Locat Time and set to the GWT label.
	 * @author maqujun
	 */
	private class CallBack implements AsyncCallback {
		public void onFailure(Throwable caught) {
			timer.cancel();
			Window.alert(caught.getMessage());
		}

		public void onSuccess(Object result) {
			label.setText(((Time) result).getTime());
		}
	}

	private CallBack callBack = new CallBack();

        /**
	 * Running a Timer to collect time from GWT Server.
	 */
	public void onModuleLoad() {
		RootPanel.get("uid").add(label);

		timer = new Timer() {
			public void run() {
				CoralService.App.getInstance().getTime(callBack);
			}
		};
		timer.scheduleRepeating(1000);
	}
}

 

gwt.xml配置文件的代码

 

<module>
	<inherits name='com.google.gwt.user.User' />
	<entry-point class='mqj.web.coral.client.Coral' />
	<servlet path="/CoralService" class="mqj.web.coral.server.CoralServiceImpl" />
</module>
 

Coral.html文件代码

 

<html>
<head>
<title>Coral</title>
</head>
<body>
<script language='javascript' src='mqj.web.coral.Coral.nocache.js'></script>
<div id='uid'></div>
</body>
</html>
 

 

 

GWT服务器端的实现代码

 

package mqj.web.coral.server;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import java.text.DateFormat;
import java.util.Date;

import mqj.web.coral.client.Time;
import mqj.web.coral.client.rpc.CoralService;

/**
 * Server side of GWT time project.
 * @author maqujun
 * 
 */
public class CoralServiceImpl extends RemoteServiceServlet implements
		CoralService {
	/**
	 * Collect time.
	 */
	public Time getTime() {
		String out = DateFormat.getDateTimeInstance(DateFormat.SHORT,
				DateFormat.FULL).format(new Date());
		return new Time(out);
	}
}

 

GWT Portlet的实现代码

package mqj.web.coral;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletSecurityException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author maqujun
 * 
 */
public class CoralPortlet extends GenericPortlet {
	protected void doView(RenderRequest renderRequest,
			RenderResponse renderResponse) throws PortletException,
			PortletSecurityException, IOException {
		renderResponse.setContentType("text/html");
		PrintWriter writer = renderResponse.getWriter();
		writer.println("<script language='javascript' src='"
				+ renderRequest.getContextPath()
				+ "/mqj.web.coral.Coral.nocache.js'></script>");
		writer.println("Coral's Time:");
		writer.println("<div id='uid'></div>");
		writer.close();
	}

在上面贴出的代码里我标注为红色的代码是要特别注意的地方,这是Portlet可以调用GWT内容的关键。所以GWT控件必须被定义在Div中。

 

Portlet的配置XML

liferay-display.xml

<?xml version="1.0"?>
<display>
	<category name="category.sample">
		<portlet id="gwt_portlet" />
	</category>
</display>

 liferay-portlet.xml

<?xml version="1.0"?>
<liferay-portlet-app>
	<portlet>
		<portlet-name>gwt_portlet</portlet-name>
		<instanceable>true</instanceable>
	</portlet>
	<role-mapper>
		<role-name>administrator</role-name>
		<role-link>Administrator</role-link>
	</role-mapper>
</liferay-portlet-app>

 portlet.xml

<?xml version="1.0"?>

<portlet-app
	xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
	version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">
	<portlet>
		<portlet-name>gwt_portlet</portlet-name>
		<display-name>Coral GWTPortlet</display-name>
		<portlet-class>mqj.web.coral.CoralPortlet</portlet-class>
		<supports>
			<mime-type>text/html</mime-type>
		</supports>
		<portlet-info>
			<title>Sample GWTPortlet</title>
			<short-title>Sample GWTPortlet</short-title>
			<keywords>Sample GWTPortlet</keywords>
		</portlet-info>
		<security-role-ref>
			<role-name>administrator</role-name>
		</security-role-ref>
	</portlet>
</portlet-app>

以及web.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
	<display-name>gwt_portlet</display-name>

	<servlet>
		<servlet-name>CoralService</servlet-name>
		<servlet-class>mqj.web.coral.server.CoralServiceImpl</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>CoralService</servlet-name>
		<url-pattern>/CoralService</url-pattern>
	</servlet-mapping>
</web-app>

 以上的Portal xml和web.xml的配置是这个Portlet能够正常运行在Liferay中最基本的信息。

更多的代码在这里就不贴出来了,有兴趣的朋友可以看一下附件中的源代码。

 

使用Ant打包GWT为war文件,以admin权限登陆Liferay, 使用Portlet plugin加载war文件。然后通过Add Application加载到你的页面中即可运行。

运行的图片是这样的

整合Liferay Portal和GWT的运行结果

 

已知的问题:

这样的整合只能用于普通的GWT Portlet项目的开发,如果你想使用GWT-EXT这样的GWT与EXT整合的实现方式,即你想要实现Portal+GWT+EXT2.0的开发模式时会有问题。我尝试过。问题的关键点在于Div的使用上,等我解决了这个问题后我会把我的解决方案发布出来与大家共享。

 

 

 

 

 

   发表时间:2008-02-25  
越来越多人关注,让我们的group也火起来吧,呵呵
0 请登录后投票
   发表时间:2008-03-03  
附件在哪里
0 请登录后投票
   发表时间:2008-03-04  
不好意思,因为项目被作为Example递交给了公司,该项目就变成了公司的项目了,所以不得不把它从自己Blog里移除 。不过如果你对于GWT和Portal有些初步的了解的话,我之前贴出来的代码足够你完成这个GWT与Portal整合的Example了。
0 请登录后投票
   发表时间:2008-03-04  
Portal在前年也接触了一点,还有protlet的开发,当时记得并不是太火,难道现在慢慢火起来了?
0 请登录后投票
   发表时间:2008-03-05  
rainlife 写道
Portal在前年也接触了一点,还有protlet的开发,当时记得并不是太火,难道现在慢慢火起来了?

没有啊,Portal不算什么火的技术,因为使用的地方不多,说实话一般项目也没有必要用它。用起来给我的感觉就是杀鸡用牛刀,并不是说这个技术有多牛,而是它后台的功能太大。有点本末倒置,导致运行性能不是很理想。
0 请登录后投票
   发表时间:2008-03-12  
有人成功过吗,介绍下经验 我的老是出错
0 请登录后投票
   发表时间:2008-03-12  
不会吧!? 我把几乎所有相关的代码都贴出来了呀!完成这样一个portlet应该没有什么问题。你把错误信息发出来,我帮你看看吧。
0 请登录后投票
   发表时间:2008-06-23  
例子在什么地方?
0 请登录后投票
   发表时间:2008-09-09  
谢谢分享,不过没看到代码贴出来
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics