搭建开发环境
				
						
				
				安装
				 jdk1.4.2,jikes1.22,ant1.6.5
     
				以安装在
				c
				盘为例
				
						
     
				设置环境变量:
				
						
     ANT_HOME  =C:\apache-ant-1.6.5 
     JAVA_HOME =C:\jdk1.5
     JIKES_HOME=C:\jikes1.22
     
				设置
				path
				变量
				,
				增加下面信息
				
						
     %ANT_HOME%\bin;%JAVA_HOME%\bin;%JIKES_HOME%\bin;
     
				部分情况
				,classpath
				变量会干扰环境,可以删除。但我机器上没删除
				classpath
				都可以正常运作。
				
						
     
				设置完环境变量后,最好重新启动机器,保证设置生效。
				
						
				
				安装
				 Myeclipse
				并建立
				portal
				工程
				
						
				
				准备好
				myecipse
				软件、
				iferay-portal-src-4.1.0.zip
     (1)
				安装
				myeclipse
				。
				
						
     (2)
				在
				e
				盘建立
				E:\cmproject
				目录,将
				liferay-portal-src-4.1.0.zip
				解压到
				e:\cmproject\portal
				目录下
				,
     (3)
				进入
				myeclipse
				,设置
				file-->switchworkspace 
				输入
				E:\cmproject
				,
				ok
				确认
				
						
     (4)File -->New-->project-->java project 
				输入项目名称为
				portal,
				其他默认,
				finish
				结束
				
						
      
				如果一切顺利,则在
				myeclipse
				左侧边
				Navigator
				上看到
				portal
				的整个目录结构
				
						
				
				建立
				ext
				工程(扩展环境)
				
						
    (1)
				在
				myeclipse
				下,切换到
				resource
				视图模式,展开
				portal
				工程目录,我们可看到一个
				release.properties
				文件,
				
						
				
				实际上我们要建一个它的扩展配置文件,
				
						
    
				文件名为
				release.${username}.properties
				。
				 ${username}
				是计算机当前用户名,比如
				administrator,apple
				等等
				.
				在计算机开始菜单运行
				cmd
				出来的
				
						
c:\document and setting\username>
				。
				
						
      
				为什么非得计算机当前用户名,因为
				portal
				用了
				ant
				作
				deploy
				,里面有个
				xml
				配置文件使用了系统环境变量。懒得
				
						
				
				去修改配置文件,就照它要求做。
				
						
      
				我文件名是
				release.avidis.properties
				,文件内容只一行:
				
						
      lp.ext.dir=e:/cmproject/ext 
      
				即扩展工程放置路径。
				
						
    (2)
				打开
				myeclipse
				里面
				ant
				视图(
				window-->
show view --> ant) , 
				在
				ant
				视图中,点击添加,选择
				e:/cmproject/portal
				目录下
				build.xml
      
				顺序执行
				clean ,start ,build-ext 
				成功的话,在
				e:/cmproject/ext
				目录下产生一系列的文件和目录。
				
						
      
				有时候在执行过程中会失败,报错。主要是
				portal
				工程本身没有
				compile
				完整。将
				portal
				重新
				build
				(
				project--build
automatily
				)选择上,注意,
				
						
				
				让
				build
				完成后,再执行
				clean ,start ,build-ext
				完成标志是
				myeclipse 
				右下角进度条完成
				100%
				。
				
						
    (3)
				将
				 liferay-portal-tomcat-jdk5-4.1.0.zip
				解压到
				 e:/cmproject/ext/server/tomcat
				下
				,
				在
				e:/cmproject/ext
				目录下我们可以看到
				app.server.properties
				文件,
				
						
      
				同样我们也要建立一个扩展配置文件
				 app.server.${username}.properties
				,文件内容两行:
				
						
     lp.ext.dir=e:/cmproject/ext
  app.server.type=tomcat
  (4) 
				同样建立一个
				java
project
				。工程名为
				ext.
				在
				myeclipse
				的
				Navigator
				里面可以看到
				ext
				工程的目录结构。
				
						
				
				配置
				ext
				工程
				tomcat
				服务器设置
				
						
  (1) 
				打开
				 window
--> preference -->myeclipse--> application servers 
				将其他应用服务器
				disabble
				掉,
				
						
				
				找到
				tomcat5
				,将
				tomcat home diretory 
				指向
				D:\cmproject\ext\servers\tomcat
				,展开
				tomcat5
				,
				jdk
				选择我们配置好的
				jdk1.5
 Jdk
				选项下面
				 optional
jave vm argument
				输入如下内容:
				
						
  -Xms256m
  -Xmx512m
  -Djava.security.auth.login.config=d:/cmproject/ext/servers/tomcat/conf/jaas.config
  (2) 
				将
				E:\cmproject\ext\servers\tomcat\conf\Catalina\localhost
				目录下的
				ROOT.xml
				文件内容修改为:
				
						
  <Context path="" docBase="ROOT"
debug="0" reloadable="true"
          
crossContext="true">
           
           <Resource
name="jdbc/LiferayPool" auth="Container"
              
type="javax.sql.DataSource" maxActive="100"
maxIdle="30"
              
maxWait="10000" username="liferay"
password="liferay"
              
driverClassName="com.mysql.jdbc.Driver"
              
url="jdbc:mysql://192.168.1.101/lportal">
           </Resource>
           
           <Resource
name="mail/MailSession" auth="Container"
              
type="javax.mail.Session" mail.transport.protocol="smtp"
              
mail.smtp.host="localhost" />
           
           <Realm
className="org.apache.catalina.realm.JAASRealm"
              
appName="PortalRealm"
              
userClassNames="com.liferay.portal.security.jaas.PortalPrincipal"
              
roleClassNames="com.liferay.portal.security.jaas.PortalRole"
              
debug="99" useContextClassLoader="false" />
       </Context> 
				建立
				ext
				工程数据库
				  
(1) 
				在服务器上
				192.168.1.101
				安装建
				mysql
				数据库服务。
				
						
(2) 
				在
				192.168.1.101
				数据库上执行了
				E:\cmproject\ext\sql\create
				下的
				create-mysql.sql
    (3)
				在
				mysql
				数据库上建立用户名为
				liferay
				,
				password =liferay,
				并将
				databse
				为
				lportal
				的所有权限授予
				liferay
				。
				
						
				
				(
				lportal
				是
				create-mysql
				脚本自动建立的)
				
						
(4)  
				解压
				mysql-connector-java-3.1.12.zip
				,
				
						
				
				将
				mysql-connector-java-3.1.12-bin.jar
				拷贝到
				e:\cmproject\ext\servers\tomcat\common\lib
				下。使
				mysql
				的
				jdbc
				启动程序正常可用。
		
		
				以上所有步骤顺利完成后,启动
				myeclipse
				里面
				tomcat
				服务,启动正常的话,在浏览器里输入
				
						http://localhost:8080
						
				
				可以看到
				portal
				系统了。
				
						
     
 portlet
				工程开发简单说明
				
						
    
				我们看到无论是
				portal
				和
				ext
				工程,目录都很繁杂,其实我们只要关注
				2
				个目录就够了。
				portal
				里面的
				portal-ejb
				和
				portal-web
				。
				Portal-ejb
				是
				portal
				工程已经实现的所有
				portlet
				的
				java
				代码和部分资源文件
				.portal-web
				目录是放置
				
						
				
				网页文件和
				portal
				的配置文件。
				
						
  ext
				工程对应目录是
				ext-ejb,
				和
				ext-web
				。
				portal-ejb
				是放置我们自己开发的
				portlet
				的
				java
				代码。
				ext-web
				是自己开
				
						
				
				发
				portlet
				对应的网页文件和配置文件。
				
						
   
				下面我们来新建一个自己
				portlet
				。
				
						
   
				这里我们采用
				portal
				里面代码规范生成机制。对于持久化层和服务层的类都可以自动产生。我们的
				portlet
				功能很
				
						
				
				简单就是从数据库里面一个表中获取数据,并在页面上显示。
				
						
				
				建立业务数据表
				
						
				
				在数据库里面新建一个表
				a_user,
				字段
				userid,username,password.
				并往表中插入几个条数据。
				
						
				
				建立代码模板配置文件
				
						
				
				(
				1
				)建立
				service.xml
				文件
				
						
				
				在
				ext-ejb/src/com/ext/portlet
				新建一个目录
				myuser,
				在目录下建立一个
				service.xml
				文件
				
						
   
				文件内容为:
				
						
<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 4.0.0//EN"
"http://www.liferay.com/dtd/liferay-service-builder_4_0_0.dtd">
<service-builder root-dir=".."
package-path="com.ext.portlet">
 <portlet name="Reports" short-name="Reports" />
 <entity name="ReportsEntry" local-service="false"
remote-service="true" 
persistence-class="com.ext.portlet.reports.service.persistence.ReportsEntryPersistence">
		
		
				  <!-- PK fields -->
		
		
				  <column name="entryId"
type="String" primary="true" />
		
		
				  <!-- Audit fields -->
		
		
				  <column name="companyId"
type="String" />
  <column name="userId" type="String" />
  <column name="userName" type="String" />
  <column name="createDate" type="Date" />
  <column name="modifiedDate" type="Date"
/>
		
		
				  <!-- Other fields -->
		
		
				  <column name="name"
type="String" />
		
		
				  <!-- Order -->
		
		
				  <order by="asc">
   <order-column name="name"
case-sensitive="false" />
  </order>
		
		
				  <!-- Finder methods -->
		
		
				  <finder name="CompanyId"
return-type="Collection">
   <finder-column name="companyId" />
  </finder>
  <finder name="UserId"
return-type="Collection">
   <finder-column name="userId" />
  </finder>
		
		
				  <!-- References -->
		
		
				  <reference
package-path="com.liferay.portal" entity="User" />
 </entity>
 <exceptions>
  <exception>EntryName</exception>
 </exceptions>
</service-builder> 
    
<!--package-path
				是指我们即将建立
				portlet
				的上级目录
				-->
<!-- portlet name
				就是我们新建文件夹名称
				myuser
				,
				short-name
				没有作研究不太清楚使用途径
				-->
<!--entity name 
				是和我们即将建立的和数据库表
				a_user
				一一对应实体的类名
				,
				可以和数据库表名不同,
				
						
				
				但为方便起见一般和表名保持一致
				-->
(2)
				修改
				ant
				文件,增加
				ant
				任务
				
						
				
				建好
				service.xml
				文件后,我们在
				ext-ejb
				目录下打开
				build-perent.xml 
				在
				
						
<target name="build-service">
…….
</target>
				下面添加任务
				
						
<target name="build-service-portlet-usertest">
 <antcall target="build-service">
 <param name="service.file" 
 value="src/com/ext/portlet/myuser/service.xml" />
 </antcall>
</target>
				然后在
				myexlipse
				的
				ant
				视图里面打开
				ext-ejb
				目录下的
				build.xml
				执行
				build-service-portlet-usertest
				任务。
				
						
				
				我们发现在
				ext-ejb/src/com/ext/portlet/myuser
				下面多了几个目录和文件。这是都是系统自动产生的
				
						
ebernate
				的实体类和持久化类。如果我们再细心些也可发现在
				ext-ejb\classes\META-INF
				目录下配置文件
				
						
				
				都多些内容。系统已经自动将对应的实体类、持久化类、工具类等配置为相应的
				javabean
				、
				ejb
				、
				webservice
				等
				
						
				
				。无疑节省了很多时间,而且减少我们人工配置的错误。
		
		
				业务实现编码
				
						
 
				现在我们要实现一个查询功能,将数据库中表名
				a_user
				中所有记录的
				username
				查询出来,并显示在前台。
				
						
 
				打开
				myuser/service/Persistence
				下
				a_userPersistence.java
				文件,建立一个方法名为
				findAllUsername
				:
		
		
				public List findAllUsername () throws SystemException {
        Session session = null;
        try {
            session =
openSession();
            StringBuffer
query = new StringBuffer();
           
query.append("FROM com.ext.portlet.myuser.model.a_user ");
            Query q =
session.createQuery(query.toString());
           
q.setCacheable(true);
            return
q.list();
        } catch (HibernateException he) {
            throw new
SystemException(he);
        } finally {
           
closeSession(session);
        }
}
		
		
				返回表
				a_user
				所有记录,并以
				list
				方式存储。题外话,一般系统已经自动产生了主要字段的查询方法,
				
						
				
				我们可以直接拿来用或者稍作改动都可以使用。
				
						
				
				按一般惯例,
				a_userPersistence
				一般是不暴露给外面类,我们都是通过它的一个持久化辅助类来调用。
				
						
				
				打开
				a_userUtil.java,
				同样在里面增加方法
				findAllUsername 
 public static java.util.List findAllUsername ()
        throws com.liferay.portal.SystemException
{
        return
getPersistence().findAllUsername ();
}
				然后我们在
				spring
				的
				service
				层同样增加一个方法。
				Service
				层的接口
				a_userLocalService
				里面增加一个函数
				
						
public List getAllUsers() throws SystemException;
				在
				Service
				层接口
				a_userLocalService
				的实现
				a_userLocalServiceImpl.java
				增加对应方法,并调用持久层辅
				
						
				
				助类
				userUtil
				方法
				findAllUsername
  public List getAllUsers() throws SystemException {
   return a_userUtil. findAllUsername ();
 }
				同样
				spring
				的
				service
				层
				也是通过辅助类作为对外唯一入口,所以在
				a_userLocalServiceUtil
				里面增加一
				
						
				
				个方法
				findAllUsername
				作为
				service
				层的方法
				findAllUsername
				的入口。
				
						
public static List getAllUsers() throws SystemException{
  
  try{
   a_userLocalService service =
a_userLocalServiceFactory.getService();
   return service.getAllUsers();
  }catch (SystemException se) {
   throw se;
  }
  catch (Exception e) {
   throw new com.liferay.portal.SystemException(e);
  }
  
 }
				需要注意的是
				service
				层接口对应具体实现是由工厂类指定。他们捆绑关系可以查看
				spring
				配置文件信息。
				
						
				
				在执行
				ant 
				的
				build-service-portlet-usertest
				任务已经完成了。
				
						
				
				在
				myuser/action
				目录下建立一个
				ViewUserAction.java
				文件,完成响应客户端请求。
				
						
public class ViewUsersAction extends PortletAction {
		
		
				 public ActionForward render(
   ActionMapping mapping, ActionForm form, PortletConfig config,
   RenderRequest req, RenderResponse res)
  throws Exception {
		
		
				  if
(req.getWindowState().equals(WindowState.NORMAL)) {
   return mapping.findForward("portlet.ext.myuser.view");
  }
  else {
   
   List users = a_userLocalServiceUtil.getAllUsers();
   List usernames = new ArrayList();
   for (int i=0;i<users.size();i++){
    usernames.add( ((a_user) users.get(i)).getUsername());
   }
   req.setAttribute("users", usernames);
		
		
				 return
mapping.findForward("portlet.ext.myuser.view_users");
  }
 }
}
				里面大概功能是如果
				porlet
				的窗口状态时普通,则定向到一个叫
				portlet.ext.myuser.view
				的目标上。
				
						
				
				如果窗口状态是最大化,那么就从调用
				userLocalServiceUtil,
				从数据库里面获取所有人员信息。
				
						
Portlet
				的生成
				
						
				
				建立自己的
				portlet
				。在
				myuser
				下面新建文件
				UsersPortlet.java 
public class UsersPortlet extends StrutsPortlet {
 public void doView(RenderRequest req, RenderResponse res)
  throws IOException, PortletException {
		
		
				  PortletPreferences prefs =
req.getPreferences();
		
		
				  System.out.println(prefs.getValue("user",
""));
		
		
				  super.doView(req, res);
 }
}
				该
				portlet
				重载了
				doview
				方法。如果自己
				portlet
				对
				view
				和
				edit
				有自己特性,那么只要重载
				doview
				和
				doedit
				就可以了。
				
						
				
				现在
				portlet
				的内容是空的,我们用
				jsp
				页面来展示用户名称方式来填充
				portlet
				里面内容。
				
						
				
				在
				
ext-web/docroot/html/portlet/ext
				目录下建立目录
				myuser,
				并在
				myuser
				目录下建立
				init.jsp
				文件
		
		
				<%@ include file="/html/common/init.jsp" %>
		
		
				<portlet:defineObjects />
		
		
				<% PortletPreferences prefs =
renderRequest.getPreferences();
		
		
				建立
				view.jsp
				文件:
		
		
				<%@ include
file="/html/portlet/ext/myuser/init.jsp" %>
<a href="<portlet:renderURL 
windowState="<%= WindowState.MAXIMIZED.toString() %>"
/>">
MyUser 
 <%= prefs.getValue("user", "") %>
</a>
				该
				jsp
				内容是显示默认的初始用户名。具体值从初始化配置参数里获取。
		
		
				建立
				view_users.jsp
<%@ include file="/html/portlet/ext/myuser/init.jsp" %>
<% List reports = (List)request.getAttribute("users");%>
		
		
				<%
for (int i = 0; i < reports.size(); i++) {
 String reportName = (String)reports.get(i);
%>
		
		
				 <%= reportName %><br>
		
		
				<%
}
%>
				该
				jsp
				页面目的是展示所有从数据库里面取出来的用户名。
		
		
				Ok
				,完成以上工作后,我们整个
				portlet
				编码工作已经宣告结束,接下来的是配置
				portlet
				参数工作。
				
						
Portlet
				的配置
		
		
				是
				portlet
				配置信息文件存放
				Ext-web/web-inf
				目录下,在
				port-ext.xml
				文件里面添加
		
		
				<portlet>
  <portlet-name>EXT_users</portlet-name>
  <display-name>myusers</display-name>
  <portlet-class>com.ext.portlet.myuser.UsersPortlet</portlet-class>
  <init-param>
   <name>view-action</name>
   <value>/ext/myuser/view_users</value>
  </init-param>
  <expiration-cache>0</expiration-cache>
  <supports>
   <mime-type>text/html</mime-type>
  </supports>
 <resource-bundle>com.liferay.portlet.StrutsResourceBundle</resource-bundle>
  <portlet-preferences>
   <preference>
    <name>user</name>
    <value>jack</value>
   </preference>
  </portlet-preferences>
  <security-role-ref>
   <role-name>power-user</role-name>
  </security-role-ref>
  <security-role-ref>
   <role-name>user</role-name>
  </security-role-ref>
 </portlet>
		
		
				<portlet-name>
				必须唯一,不得已有
				portlet
				名字冲突。
				<display-name>
				也必须唯一。
				
						
<portlet-class>
				指向我们的建立
				portlet
				类。
				
						
 <name>view-action</name>
				里面值是指
				view
				这个
				action
				对应的
				actionurl
				。
				<portlet-preferences>
				里面参数值是提供给这个
				portlet
				使用的参数初始值。这里配置是指
				portlet
				里面使用到参数名
				user
				的值是
				jack
				。
				
						
				
				如
				portlet
				不需要初始值参数,则该项不需要配置。
		
		
				在
				liferay-portlet-ext.xml
				文件里面添加
				
						
<portlet>
  <portlet-name>EXT_users</portlet-name>
  <struts-path>ext/myuser</struts-path>
  <use-default-template>false</use-default-template>
</portlet>
		
		
				<portlet-name>
				的值必须和
				portlet-ext.xml
				文件里面
				<portlet-name>
				值一致。
		
		
				
						
				
				在
				liferay-display
				。
				Xml
				文件节点
				<category name="category.test">
				下面添加
				
						
<portlet id="EXT_users" /> id
				必须和
				portlet-ext
				里面的
				<portlet-name>
				一致。
		
		
				在
				struts-config.xml
				文件里面添加内容:
				
						
<action path="/ext/myuser/view_users"
        
type="com.ext.portlet.myuser.action.ViewUsersAction">
<forward name="portlet.ext.myuser.view_1" 
  path="portlet.ext.myuser.view" />
<forward name="portlet.ext.myuser.view_users_1" 
path="portlet.ext.myuser.view_users" />
</action>
		
		
				就是说,当前台提交一个
				actionUrl
				为
				/ext/myuser/view_users
				请求的时候,由
				ViewUsersAction
				负责处理这个
				
						
action
				操作。后面
				2
				个
				forward
				指的是在
				ViewUsersAction
				定向返回请求目标页面。
				
						
…………
return mapping.findForward("portlet.ext.myuser.view_1");
		
		
				………
return mapping.findForward("portlet.ext.myuser.view_users_1");
		
		
				findForward
				的值为避免与其他
				findForward
				值冲突,一般将包名也带上,保证不会重名。
		
		
				在
				tiles-defs.xml
				文件里面添加内容:
				
						
<definition name="portlet.ext.myuser.view"
extends="portlet">
 <put name="portlet_content"  value="/portlet/ext/myuser/view.jsp"
/>
</definition>
<definition name="portlet.ext.myuser.view_users"
extends="portlet">
 <put name="portlet_content"
value="/portlet/ext/myuser/view_users.jsp" />
</definition>
		
		
				该
				name
				的值即随同
				struct-config.xml
				配置信息里面
				forward
				参数
				path
				值对应的,指向真正的目标页面。
		
		
				最后我们在
				ext-ejb/classes/content
				目录下
				language-ext.properties
				文件里面增加内容:
				
						
javax.portlet.title.EXT_user=MyUsers
				即
				portlet
				显示出来时候,在
				portlet
				上面标题信息。
		
		
				Portlet
				常见问题
				
						
1. 
				运行提示
				portlet
path 
				找不到,则一般是
				liferay-port-ext
				文件里面
				portlet
				的
				struts–path
				有问题。
				
						
2. 
				启动提示
				jaas.config
				错误,没有在
				tomcat
				的
				jdk
				参数配置
				jaas.config
				文件或配置路径不对
				
						
3. 
				提示
				html/../..
				找不到,一般是
				struts-config
				文件里面
				path
				路径有问题。
				
						
4. 
				有执行和数据库存取数据时候,提示
				“columnname_”
				字段不存在,去修改
				ext-hbm.xml
				文件,
				ant
				执行
				
						
build service
				任务时候,产生
				ext-hbm.xml
				信息有时会不准确,将对应的
				<property
name="columnname" 
column="columnname_ " />
				的
				column
				调整为数据库对应正确的字段名。
				
						
5. 
				大家在清除不用的
				portlet
				时候,请先登录系统,将不用的
				portlet
				关闭,然后再删除或屏蔽对应的代码。
				
						
				
				不然直接删除或屏蔽代码,重新启动后,会提示
				portlet
				找不到。注册后的
				portlet
				会写信息到数据库中。