一、實例
這裡我們采用portal裡面代碼規范生成機制。對於持久化層和服務層的類都可以自動產生。
我們的portlet功能很簡單就是從數據庫裡面一個表中獲取數據,並在頁面上顯示。
建立業務數據表
在數據庫裡面新建一個表users,字段userid(varcher),username(varcher),password(varcher).並往表中插入幾個條數據。
建立代碼模板配置文件
(1)建立service.xml文件
在ext\ext-impl\src\com\ext\portlet 新建一個目錄users,在目錄下建立一個service.xml文件
文件內容為:
<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.1.0//EN" "http://www.liferay.com/dtd/liferay-service-
builder_5_1_0.dtd">
<service-builder package-path="com.ext.portlet.users">
<namespace>Users</namespace>
<entity name="UsersEntry" local-service="false" remote-service="true" persistence-
class="com.ext.portlet.users.service.persistence.UsersEntryPersistenceImpl">
<!-- PK fields -->
<column name="userid" type="String" primary="true" />
<!-- Audit fields -->
<column name="username" type="String" />
<column name="password" type="String" />
<!-- Order -->
<order by="asc">
<order-column name="username" case-sensitive="false" />
</order>
</entity>
<exceptions>
<exception>UsersEntry</exception>
</exceptions>
</service-builder>
<!--package-path是指我們即將建立portlet的上級目錄-->
<!-- portlet name就是我們新建文件夾名稱users,short-name沒有作研究不太清楚使用途徑-->
<!--entity name 是和我們即將建立的和數據庫表a_user一一對應實體的類名,可以和數據庫表名不同,
<!--但為方便起見一般和表名保持一致-->
(2)修改ant文件,增加ant任務
建好service.xml文件後,我們在ext-impl目錄下打開build-perent.xml 在
<target name="build-service">
…….
</target>
下面添加任務
<target name="build-service-portlet-users">
<antcall target="build-service">
<param name="service.file" value="src/com/ext/portlet/users/service.xml" />
</antcall>
</target>
然後在myexlipse的ant視圖裡面打開ext-impl目錄下的build.xml執行build-service-portlet-user任務。
我們發現在ext-impl\src\com\ext\portlet\users , ext-service\src\com\ext\portlet\users
下面多了幾個目錄和文件。這是都是系統自動產生的hibernate的實體類和持久化類。
如果我們再細心些也可發現在ext-impl\src\META-INF目錄下配置文件都多些內容。
系統已經自動將對應的實體類、持久化類、工具類等配置為相應的javabean、util、service等。
無疑節省了很多時間,而且減少我們人工配置的錯誤。
打開ext-impl\src\META-INF\ext-hbm.xml,把<class name="com.ext.portlet.users.model.impl.UsersEntryImpl" table="UsersEntry">改為<class name="com.ext.portlet.users.model.impl.UsersEntryImpl" table="Users">
業務實現編碼
現在我們要實現一個查詢功能,將數據庫中表名users中所有記錄的username查詢出來,並顯示在前台。
打開\ext-service\src\com\ext\portlet\users\service下UsersEntryService文件,建立一個名為getAllUsers的抽象方法;
public List getAllUsers() throws SystemException;
在\ext-impl\src\com\ext\portlet\users\service\impl\UsersEntryServiceImpl.java中實現它.
public List getAllUsers() throws SystemException {
return UsersEntryUtil.findAll();
}
同樣spring的service層 也是通過輔助類作為對外唯一入口,所以在UsersEntryServiceUtil裡面增加一
個方法getAllUsers作為service層的方法getAllUsers的入口。
public static List getAllUsers() throws SystemException{
return _service.getAllUsers();
}
需要注意的是service層接口對應具體實現是由工廠類指定。他們捆綁關系可以查看spring配置文件信息。
在執行ant 的build-service-portlet-usertest任務已經完成了。
在\src\com\ext\portlet\users\action目錄下建立一個ViewUserAction.java文件,完成響應客戶端請求。
package com.ext.portlet.users.action;
import com.ext.portlet.users.model.UsersEntryModel;
import com.ext.portlet.users.service.UsersEntryServiceUtil;
import com.liferay.portal.struts.PortletAction;
import java.util.ArrayList;
import java.util.List;
import javax.portlet.PortletConfig;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.WindowState;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
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.users.view");
} else {
List users = UsersEntryServiceUtil.getAllUsers();
List usernames = new ArrayList();
for (int i = 0; i < users.size(); i++) {
usernames.add(((UsersEntryModel) users.get(i)).getUsername());
}
req.setAttribute("users", usernames);
req.setAttribute("count", ""+users.size());
return mapping.findForward("portlet.ext.users.view_users");
}
}
}
裡面大概功能是如果porlet的窗口狀態時普通,則定向到一個叫portlet.ext.myuser.view的目標上。
如果窗口狀態是最大化,那麼就從調用userLocalServiceUtil,從數據庫裡面獲取所有人員信息。
Portlet的生成
建立自己的portlet。在\ext-impl\src\com\ext\portlet\users下面新建文件UsersPortlet.java
package com.ext.portlet.users;
import com.liferay.portlet.StrutsPortlet;
import java.io.IOException;
import javax.portlet.PortletException;
import javax.portlet.PortletPreferences;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
public class UsersPortlet extends StrutsPortlet {
public void doView(
RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
PortletPreferences prefs = renderRequest.getPreferences();
System.out.println(prefs.getValue("test", ""));
super.doView(renderRequest, renderResponse);
}
}
該portlet重載了doview方法。如果自己portlet對view和edit有自己特性,那麼只要重載doview和doedit就可以了。
現在portlet的內容是空的,我們用jsp頁面來展示用戶名稱方式來填充portlet裡面內容。
在 \ext-web\docroot\html\portlet\ext目錄下建立目錄users,並在users目錄下建立init.jsp文件
<%@ include file="/html/common/init.jsp" %>
<portlet:defineObjects />
<% PortletPreferences prefs = renderRequest.getPreferences(); %>
建立view.jsp文件:
<%@ include file="/html/portlet/ext/users/init.jsp" %>
<a href="<portlet:renderURL windowState="<%= WindowState.MAXIMIZED.toString() %>" />">
MyUser
<%= prefs.getValue("user", "") %>
</a>
該jsp內容是顯示默認的初始用戶名。具體值從初始化配置參數裡獲取。
建立view_users.jsp
<%@ include file="/html/portlet/ext/users/init.jsp" %>
<% List reports = (List)request.getAttribute("users");%>
<% String count = (String)request.getAttribute("count");%>
size : <%=count %>.<br/>
<%
for (int i = 0; i < reports.size(); i++) {
String reportName = (String)reports.get(i);
%>
<%= reportName %><br>
<%
}
%>
該jsp頁面目的是展示所有從數據庫裡面取出來的用戶名。
Ok,完成以上工作後,我們整個portlet編碼工作已經宣告結束,接下來的是配置portlet參數工作。
Portlet的配置:
是portlet配置信息文件存放\ext-web\docroot\WEB-INF目錄下,在portlet-ext.xml文件裡面添加
<portlet>
<portlet-name>EXT_Users</portlet-name>
<display-name>Users</display-name>
<portlet-class>com.ext.portlet.users.UsersPortlet</portlet-class>
<init-param>
<name>view-action</name>
<value>/ext/users/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>test</name>
<value></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/users</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/users/view_users" type="com.ext.portlet.users.action.ViewUsersAction">
<forward name="portlet.ext.users.view" path="portlet.ext.users.view" />
<forward name="portlet.ext.users.view_users" path="portlet.ext.users.view_users" />
</action>
就是說,當前台提交一個actionUrl為/ext/users/view_users請求的時候,由ViewUsersAction負責處理這個
action操作。後面2個forward指的是在ViewUsersAction定向返回請求目標頁面。
…………
return mapping.findForward("portlet.ext.users.view");
………
return mapping.findForward("portlet.ext.users.view_users");
findForward的值為避免與其他findForward值沖突,一般將包名也帶上,保證不會重名。
在tiles-defs.xml文件裡面添加內容:
<definition name="portlet.ext.users.view" extends="portlet">
<put name="portlet_content" value="/portlet/ext/users/view.jsp" />
</definition>
<definition name="portlet.ext.users.view_users"
extends="portlet">
<put name="portlet_content"
value="/portlet/ext/users/view_users.jsp" />
</definition>
該name的值即隨同struct-config.xml配置信息裡面forward參數path值對應的,指向真正的目標頁面。
最後我們在\ext-impl\src\content目錄下Language-ext.properties文件裡面增加內容:
javax.portlet.title.EXT_Users=Users
view-users=View Users
即portlet顯示出來時候,在portlet上面標題信息。
我所遇到的問題以及解決方式:
1、報 字段 出錯, password_ 應該在數據庫中是 password
修改配置文件ext-impl/src META-INF ext-hbm.xml
Model不知道要不要改,我也改了一下。