Terry.Li-彬

虚其心,可解天下之问;专其心,可治天下之学;静其心,可悟天下之理;恒其心,可成天下之业。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  143 随笔 :: 344 文章 :: 130 评论 :: 0 Trackbacks

搭建开发环境
安装 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 会写信息到数据库中。

 

posted on 2009-05-20 13:24 礼物 阅读(656) 评论(0)  编辑  收藏 所属分类: Liferay