事前準備工作:
1. Import liferay portal的開發環境到My Eclipse IDE
歩驟:File->Import, Existing projects into Workspace, 指向D:\liferay
2. 把相關會使用到的jar檔,待新的Struts portlet專案建立後逐一included。
ext/modules portal-impl.jar
ext/lib/global portal-kernel.jar
ext/lib/global portal-service.jar
ext/lib/global portlet.jar
ext/lib/global portlet-container.jar
客制Struts Portlet開發:
首先My Eclipse IDE開啟一個”QueryDataPortlet”的Web Project,而後更改web root folder為docroot
整理目錄結構,將QueryDataPortlet/src目錄移動到docroot/WEB-INF,如下圖所示:
並且於QueryDataPortlet/docroot中增加css、js、html三個目錄,Copy js/test.js、css/test.css、icon.png到QueryDataPortlet/docroot的js與css等對映目錄。
滑鼠右擊QueryDataPortlet專案,選取Properties->Source項目,按Add Folder重新設定新的Source folder為QueryDataPortlet/docroot/WEB-INF/src,並移除mssing path。
於docroot/WEB-INF內建立liferay的四大設定檔:
liferay-display.xml
<?xml version="1.0"?>
<!DOCTYPE display PUBLIC "-//Liferay//DTD Display 5.2.0//EN" "http://www.liferay.com/dtd/liferay-display_5_2_0.dtd">
<display>
<category name="category.sample">
<portlet id="queryData" />
</category>
</display>
liferay-portlet.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 5.2.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_5_2_0.dtd">
<liferay-portlet-app>
<portlet>
<portlet-name>queryData</portlet-name>
<icon>/icon.png</icon>
<struts-path>query_data</struts-path>
<use-default-template>true</use-default-template>
<restore-current-view>true</restore-current-view>
<instanceable>true</instanceable>
<private-request-attributes>false</private-request-attributes>
<header-portlet-css>/css/test.css</header-portlet-css>
<footer-portlet-javascript>/js/test.js</footer-portlet-javascript>
</portlet>
<role-mapper>
<role-name>administrator</role-name>
<role-link>Administrator</role-link>
</role-mapper>
<role-mapper>
<role-name>guest</role-name>
<role-link>Guest</role-link>
</role-mapper>
<role-mapper>
<role-name>power-user</role-name>
<role-link>Power User</role-link>
</role-mapper>
<role-mapper>
<role-name>user</role-name>
<role-link>User</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_2_0.xsd" version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
<portlet>
<portlet-name>queryData</portlet-name>
<display-name>Query data portlet</display-name>
<portlet-class>com.liferay.sampleStruts.SampleStrutsPortlet</portlet-class>
<init-param>
<name>view-action</name>
<value>/query_data/view</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<portlet-info>
<title>Query data from DB.</title>
<short-title>qry_2</short-title>
<keywords>qry_3</keywords>
</portlet-info>
<security-role-ref>
<role-name>administrator</role-name>
</security-role-ref>
<security-role-ref>
<role-name>guest</role-name>
</security-role-ref>
<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-app>
liferay-plugin-package.properties
name=queryData
module-group-id=liferay
module-incremental-version=1
tags=sample
short-description=This plugin shows how to use Liferay's Struts Bridge.
change-log=
page-url=http://www.liferay.com
author=Liferay, Inc.
licenses=MIT
portal-dependency-jars=
portal.dependency.tlds=struts-tiles.tld
於docroot/WEB-INF內建立Struts的struts-config.xml與tiles-defs.xml檔案:
struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<action-mappings>
<action path="/query_data/view" forward="portlet.query_data.view" />
</action-mappings>
<message-resources parameter="com.coretronic.struts.ApplicationResources" />
<plug-in className="org.apache.struts.tiles.TilesPlugin">
<set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
<set-property property="moduleAware" value="true" />
<set-property property="definitions-parser-validate" value="true" />
</plug-in>
</struts-config>
tiles-defs.xml
<?xml version="1.0"?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd">
<tiles-definitions>
<definition name="portlet.query_data.view" path="/portlet/query_data/view.jsp" />
</tiles-definitions>
於docroot/WEB-INF內修改web.xml:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>PortletActionServlet</servlet-name>
<servlet-class>com.liferay.portal.struts.PortletActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>PortletActionServlet</servlet-name>
<url-pattern>/portlet_action/*</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>http://struts.apache.org/tags-tiles</taglib-uri>
<taglib-location>/WEB-INF/tld/struts-tiles.tld</taglib-location>
</taglib>
</web-app>
於docroot/ META-INF內建立context.xml:
context.xml
<Context>
<Loader loaderClass="com.liferay.support.tomcat.loader.PortalClassLoader"/>
<Resource name="jdbc/Eptest" auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@192.168.1.182:1521:eptest" username="ehr"
password="ehr" maxActive="20" />
</Context>
於docroot/WEB-INF內建立src/com/liferay/sampleStruts目錄與SampleStrutsPortlet.java:
SampleStrutsPortlet.java
package com.liferay.sampleStruts;
import com.liferay.portlet.StrutsPortlet;
import java.io.IOException;
import javax.portlet.PortletException;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
/**
* <a href="JSPPortlet.java.html"><b><i>View Source</i></b></a>
*
* @author Brian Wing Shun Chan
*
*/
public class SampleStrutsPortlet extends StrutsPortlet {
public void doView(RenderRequest req, RenderResponse res)
throws IOException, PortletException {
super.doView(req, res);
}
}
於docroot/html內建立portlet/query_data目錄與init.jsp、view.jsp:
Init.jsp
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ page import="com.liferay.portal.kernel.dao.search.*" %>
<%@ page import="com.liferay.portal.kernel.util.CalendarFactoryUtil" %>
<%@ page import="com.liferay.portal.kernel.util.Constants" %>
<%@ page import="com.liferay.portal.kernel.util.ContentTypes" %>
<%@ page import="com.liferay.portal.kernel.util.DateFormats" %>
<%@ page import="com.liferay.portal.kernel.util.GetterUtil" %>
<%@ page import="com.liferay.portal.kernel.util.HtmlUtil" %>
<%@ page import="com.liferay.portal.kernel.util.ListUtil" %>
<%@ page import="com.liferay.portal.kernel.util.ParamUtil" %>
<%@ page import="com.liferay.portal.kernel.util.StringPool" %>
<%@ page import="com.liferay.portal.kernel.util.StringUtil" %>
<%@ page import="com.liferay.portal.kernel.util.Validator" %>
<%@ page import="com.liferay.portal.kernel.util.WebKeys" %>
<%@ page import="com.liferay.portal.util.PortalUtil" %>
<%@ page import="javax.portlet.PortletRequest" %>
<%@ page import="javax.portlet.PortletSession" %>
<%@ page import="javax.portlet.PortletMode" %>
<%@ page import="javax.portlet.PortletURL" %>
<%@ page import="javax.portlet.WindowState" %>
<%@ page import="java.util.*" %>
<%@ page import="com.xxxcompany.struts.*" %>
<%@ page import="com.xxxcompany.util.*" %>
<portlet:defineObjects />
view.jsp
<%@ include file="init.jsp" %>
<%
PortletURL portletURL = renderResponse.createRenderURL();
portletURL.setWindowState(WindowState.NORMAL);
portletURL.setParameter("view_action", "/query_data/view");
List<String> headerNames = new ArrayList<String>();
headerNames.add("RC_ID");
headerNames.add("RC_NAME");
headerNames.add("REGION");
headerNames.add("PARENT_RC_ID");
headerNames.add(StringPool.BLANK);
List tValues = TestDB.getData();
SearchContainer searchContainer = new SearchContainer(renderRequest, null, null, "cur1", SearchContainer.DEFAULT_DELTA, portletURL, headerNames, "there are no records.");
List results = ListUtil.subList(tValues, searchContainer.getStart(), searchContainer.getEnd());
int total = tValues.size();
searchContainer.setTotal(total);
searchContainer.setResults(results);
List resultRows = searchContainer.getResultRows();
for (int i = 0; i < results.size(); i++) {
TestBean testBean = (TestBean)results.get(i);
ResultRow row = new ResultRow(testBean, testBean.getA(), i);
row.addText(testBean.getA());
row.addText(testBean.getB());
row.addText(testBean.getC());
row.addText(testBean.getD());
row.addText(StringPool.BLANK);
// Add result row
resultRows.add(row);
}
%>
<liferay-ui:search-iterator paginate="false" searchContainer="<%= searchContainer %>" />
<liferay-ui:search-paginator searchContainer="<%= searchContainer %>" />
於docroot/WEB-INF內建立src/com/coretronic/struts/TestBean.java與src/com/coretronic/util/TestDB.java:
TestBean.java
package com.coretronic.struts;
public class TestBean {
private String a;
private String b;
private String c;
private String d;
public TestBean(){
}
public TestBean(String s1,String s2,String s3,String s4){
this.a = s1;
this.b = s2;
this.c = s3;
this.d = s4;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
public String getD() {
return d;
}
public void setD(String d) {
this.d = d;
}
}
TestDB.java
package com.coretronic.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.coretronic.struts.TestBean;
public class TestDB {
public static List getData(){
DBConnection conTool = null;
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
List list = new ArrayList();
try{
conTool = new DBConnection();
con = conTool.getDB("java:comp/env/jdbc/Eptest");
ps = con.prepareStatement("select * from tbl_gris_rc");
rs = ps.executeQuery();
while(rs.next()){
TestBean tb = new TestBean();
tb.setA(rs.getBigDecimal("RC_ID").toString());
tb.setB(rs.getString("RC_NAME"));
tb.setC(rs.getString("REGION"));
tb.setD(rs.getBigDecimal("PARENT_RC_ID").toString());
list.add(tb);
System.out.println(rs.getString("RC_NAME"));
}
}catch(Exception ex){
ex.printStackTrace();
System.out.println("Exception for TestDB: "+ex.getMessage());
}finally{
try{
if(rs != null) rs.close();
if(ps != null) ps.close();
if(conTool != null) conTool.closeConnection();
}catch(Exception exSql){
}
}
return list;
}
}
使用Ant生成新專案的build.xml與.war檔:
2. 修改剛才產生的build.xml,加入紅標字體的區塊於檔案中
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="docroot/WEB-INF/classes" source="${source}" target="${target}">
<src path="docroot/WEB-INF/src"/>
<classpath refid="QueryDataPortlet.classpath"/>
</javac>
<jar destfile="${ant.project.name}.war">
<zipfileset dir="docroot/">
<include name="**/*.*" />
<exclude name="**/*.war" />
</zipfileset>
</jar>
</target>
3. 滑鼠右擊上述build.xml,選擇Run As->Ant Build,接著產生QueryDataPortlet.war
Deploy QueryDataPortlet專案,打開 IE8.0輸入http://localhost:8080開啟liferay portal,以Bruno (Admin)管理者帳號登入,選擇Add Application->Sample->”Query Data from DB.” ->add項目,將它附加到liferay portal。