使用Spring+hibernate完成liferay portlet plugin开发
??? 本文使用spring集成hibernate完成一个liferay portlet的开发,做为plugin的方式部署到liferay容器当中。提供源代码下载。
??? 版本约束:
????????? Spring 3.0 及以上
??????????Hiberante 3.5
????????? Liferay 6.0及以上
?? 构建基制:
????????? Ant
????????? Maven
?
?? 知识点描述:
?
?????????使用Hiberante+jndi的方式,否则使用Hiberante+jdbc的话,在liferay当中部署不成功,然后再集成Spring,最前端使用GenericPortlet。
?
?
?? 开发配置:
???????? web.xml
?
<?xml version="1.0"?><web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"version="2.4"><display-name>AntBee Portlet</display-name><context-param><param-name>log4jConfigLocation</param-name><param-value>/WEB-INF/classes/log4j.properties</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener></web-app>
?Spring的配置文件:applicationContext.xml,放在\WEB-INF\applicationContext.xml
?
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd "><aop:aspectj-autoproxy /><context:component-scan base-package="com.antbee.portlet" /><jee:jndi-lookup jndi-name="java:comp/env/jdbc/myportalDB"id="dataSource" /><bean id="sessionFactory"ref="dataSource"/><property name="annotatedClasses"><list><value>com.antbee.portlet.domain.MonitorItem</value><value>com.antbee.portlet.domain.SearchResult4Db</value></list></property></bean><tx:annotation-driven transaction-manager="txManager" /><bean id="txManager"ref="sessionFactory" /></bean><bean id="loggingAspect" /></beans>
??? 针对Liferay Portlet的几个配置文件:portlet.xml,放在目录:WEB-INF\portlet.xml
<?xml version="1.0" encoding="UTF-8"?><portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"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>resultForNews</portlet-name><portlet-class>com.antbee.portlet.base.SearchResultPortlet</portlet-class><expiration-cache>1000</expiration-cache><cache-scope>private</cache-scope><supports><mime-type>text/html</mime-type><portlet-mode>view</portlet-mode></supports><resource-bundle>content.Language-ext</resource-bundle><portlet-info><title>安特比软件-Portlet演示</title></portlet-info></portlet></portlet-app>
?接上面,同样是portlet的配置文件:liferay-display.xml,放在目录WEB-INF\liferay-display.xml
<?xml version="1.0"?><!DOCTYPE display PUBLIC "-//Liferay//DTD Display 6.0.0//EN" "http://www.liferay.com/dtd/liferay-display_6_0_0.dtd"> <display> <category name="antbee.portlet.function"> <portlet id="resultForNews" /> </category> </display>
?
?接上面,同样是portlet的配置文件:liferay-portlet.xml,放在目录WEB-INF\liferay-portlet.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 6.0.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_6_0_0.dtd"><liferay-portlet-app><portlet><portlet-name>resultForNews</portlet-name><instanceable>true</instanceable><remoteable>true</remoteable><header-portlet-css>/css/bookCatalog.css</header-portlet-css><header-portlet-javascript>/js/bookCatalog.js</header-portlet-javascript></portlet></liferay-portlet-app>
?前端继承的GenericPortlet的SearchResultPortlet.java
package com.antbee.portlet.base;import java.io.IOException;import java.util.Enumeration;import java.util.List;import java.util.Map;import javax.portlet.GenericPortlet;import javax.portlet.PortalContext;import javax.portlet.PortletException;import javax.portlet.PortletMode;import javax.portlet.PortletRequest;import javax.portlet.RenderMode;import javax.portlet.RenderRequest;import javax.portlet.RenderResponse;import javax.portlet.WindowState;import org.apache.log4j.Logger;import org.springframework.context.ApplicationContext;import org.springframework.web.portlet.context.PortletApplicationContextUtils;import com.antbee.portlet.service.SearchResultService;import com.antbee.portlet.utils.Constants;/** * * @author Weiya * */public class SearchResultPortlet extends GenericPortlet {private Logger logger = Logger.getLogger(SearchResultPortlet.class);private static SearchResultService searchResultService;public void init() {searchResultService = getSearchResultService();}public SearchResultService getSearchResultService() {ApplicationContext springCtx = PortletApplicationContextUtils.getWebApplicationContext(getPortletContext());return (SearchResultService)springCtx.getBean("searchResultService");}@RenderMode(name = "VIEW")public void showSearchResult(RenderRequest request, RenderResponse response)throws IOException, PortletException {logger.info("Inside showSearchResult method");PortalContext context = request.getPortalContext();printSupportedPortletModes(context);printSupportedWindowStates(context);Map userAttributeMap = (Map) request.getAttribute(PortletRequest.USER_INFO);String firstName = "";String lastName = "";if (userAttributeMap != null) {firstName = (String) userAttributeMap.get("user.name.given");lastName = (String) userAttributeMap.get("user.name.family");// --set firstName and lastName in request so that JSP can pick// --from the requestrequest.setAttribute("firstName", firstName);request.setAttribute("lastName", lastName);}String jspPage = "home.jsp";// Got DataList results = searchResultService.getKeyWordByMonitorItem(3);request.setAttribute("results", results);getPortletContext().getRequestDispatcher(response.encodeURL(Constants.PATH_TO_JSP_FUNCTION_PAGE + jspPage)).include(request, response);}//-- Print supported portlet modes by the portal serverprivate void printSupportedPortletModes(PortalContext context) {// -- supported portlet modes by the portal serverEnumeration<PortletMode> portletModes = context.getSupportedPortletModes();while (portletModes.hasMoreElements()) {PortletMode mode = portletModes.nextElement();logger.info("Support portlet mode " + mode.toString());}}//-- prints support window states by the portal serverprivate void printSupportedWindowStates(PortalContext context) {// -- supported window states by the portal serverEnumeration<WindowState> windowStates = context.getSupportedWindowStates();while (windowStates.hasMoreElements()) {WindowState windowState = windowStates.nextElement();logger.info("Support window state " + windowState.toString());}}}?还有构建脚本:build.xml
<?xml version="1.0"?><!-- define the project --><project name="antbeePortlet" default="build" basedir="."><!-- define project properties --><property name="compiler" value="modern" /><property name="fork" value="no" /><property name="verbose" value="no" /><property name="debug" value="on" /><property name="optimize" value="on" /><property name="deprecation" value="on" /><property name="target" value="1.5" /><property name="source" value="1.5" /><property file="build.properties" /><property environment="env" /><!-- define properties to refer to directories in the project --><property name="webinf.dir" value="WEB-INF" /><property name="webinf.lib.dir" value="WEB-INF/lib" /><property name="lib.dir" value="lib" /><property name="src.dir" value="src" /><property name="test.dir" value="test" /><property name="build.dir" value="build" /><property name="webinf.classes.dir" value="${webinf.dir}/classes" /><property name="webinf.classes.content.dir" value="${webinf.dir}/classes/content" /><property name="web.xml" value="${webinf.dir}/web.xml" /><fileset id="webapp.libs" dir="${webinf.lib.dir}"><include name="*.jar" /></fileset><fileset id="libs" dir="${lib.dir}"><include name="*.jar" /></fileset><path id="class.path"><pathelement path="${webinf.classes.dir}" /><fileset refid="webapp.libs" /><fileset refid="libs" /></path><pathconvert pathsep=":" property="class.path" refid="class.path" /><fileset id="war.files" dir="."><include name="${webinf.dir}/**" /><exclude name="${webinf.dir}/Language-ext*.properties" /><exclude name="${webinf.dir}/ValidationMessages.properties" /><include name="images/**" /><include name="css/**" /><include name="js/**" /><exclude name="${web.xml}" /></fileset><!-- compile target to compile the sources --><target name="compile"><mkdir dir="${webinf.classes.dir}" /><!-- Content directory contains Liferay resource bundle--><mkdir dir="${webinf.classes.content.dir}" /><javac srcdir="${src.dir}:${test.dir}" destdir="${webinf.classes.dir}" fork="${fork}" verbose="${verbose}" deprecation="${deprecation}" debug="${debug}" optimize="${optimize}" compiler="${compiler}" target="${target}" source="${source}"><classpath refid="class.path" /></javac><copy todir="${webinf.classes.dir}" preservelastmodified="true"><fileset dir="${src.dir}"><include name="**/*.properties" /><include name="**/*.xml" /></fileset></copy><copy todir="${webinf.classes.content.dir}"><fileset dir="${webinf.dir}"><include name="Language-ext*.properties" /></fileset></copy></target><!-- target to create the project WAR file --><target name="build" depends="clean,compile"><mkdir dir="${build.dir}" /><war destfile="${build.dir}/antbeePortlet.war" webxml="${web.xml}"><fileset refid="war.files" /></war><copy todir="${liferay.portal.home}/deploy"><fileset dir="${build.dir}"><include name="**/*.war" /></fileset></copy></target><!-- target to clean up all files created by various tasks --><target name="clean"><delete quiet="true" includeemptydirs="true"><fileset dir="${webinf.classes.dir}" includes="**/*" /><fileset dir="${build.dir}" /><fileset dir="${work.dir}" /></delete></target></project>?
另外一个是SVN的构建脚本pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>antbee</groupId><artifactId>antbeePortlet</artifactId><packaging>war</packaging><version>1.0</version><repositories><repository><id>JBoss Repository</id><url>http://repository.jboss.com/maven2</url></repository></repositories><build><sourceDirectory>${project.basedir}/src</sourceDirectory><outputDirectory>${project.basedir}/target/classes</outputDirectory><resources><resource><targetPath>content</targetPath><directory>WEB-INF</directory><includes><include>Language-ext.properties</include></includes></resource></resources><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.0.2</version><configuration><source>1.5</source><target>1.5</target></configuration></plugin><plugin><artifactId>maven-war-plugin</artifactId><version>2.1-alpha-2</version><configuration><webResources><resource><directory>css</directory><targetPath>css</targetPath></resource><resource><directory>js</directory><targetPath>js</targetPath></resource><resource><directory>images</directory><targetPath>images</targetPath></resource><resource><directory>WEB-INF/jsp/</directory><targetPath>WEB-INF/jsp</targetPath></resource><resource><directory>WEB-INF</directory><targetPath>WEB-INF</targetPath><includes><include>**/*.xml</include></includes><excludes><exclude>Language-ext.properties</exclude></excludes></resource></webResources><webXml>${project.basedir}/WEB-INF/web.xml</webXml></configuration></plugin></plugins></pluginManagement></build><dependencies><dependency><groupId>javax.portlet</groupId><artifactId>portlet-api</artifactId><version>2.0</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.1.1</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.14</version></dependency><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1.1</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.2.1</version></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.4</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>3.5.0-Final</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-annotations</artifactId><version>3.5.0-Final</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-asm</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc-portlet</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.6.8</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.6.8</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>3.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>3.0.0.RELEASE</version><scope>test</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.4</version><scope>provided</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.5.6</version></dependency><dependency><groupId>org.hibernate.javax.persistence</groupId><artifactId>hibernate-jpa-2.0-api</artifactId><version>1.0.0.Final</version></dependency><dependency><groupId>javassist</groupId><artifactId>javassist</artifactId><version>3.9.0.GA</version></dependency></dependencies></project>?哈哈。如果完成项目后,可以通过:
?? ANT脚本: ant clean build
??MAVEN脚本:mvn clean install构建项目
?
? 在部署到liferay时,要创建jndi的连接方式,如下是我的创建过程和脚本:(目标是TOMCAT服务器)
?Add <Resource> element in server.xml, inside <GlobalNamingResources> element.
<GlobalNamingResources> .. <Resource name="jdbc/myportalDB" auth="Container" type="javax.sql.DataSource" username="root" password="root" driverClassName="com.mysql.jdbc.Driver" factory="org.apache.commons.dbcp.BasicDataSourceFactory" url="jdbc:mysql://localhost/myportaldb?useUnicode=true&" maxActive="5" maxIdle="2"/> .. </GlobalNamingResources>
?Add <ResourceLink> element in context.xml file, inside <Context> element.
<Context>....<ResourceLink name="jdbc/myportalDB" global="jdbc/myportalDB" type="javax.sql.DataSource"/> .... </Context>
?重新启动,enjoy it!
?
?
不买关子,提供代码让大家下载,如果有什么不明白的,请留言。(eclipse项目,可以直接导入)
下载代码当中去掉了jar,如下是抓图:
