`
hereson2
  • 浏览: 462101 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Liferay代码分析与扩展——用户服务

阅读更多
<meta content="text/html; charset=utf-8" http-equiv="CONTENT-TYPE"> <meta name="GENERATOR" content="OpenOffice.org 2.4 (Linux)"> <style type="text/css"> </style>

Liferay代码分析与扩展——用户服务

转载请保留作者信息:

作者:88250

Blog:http:/blog.csdn.net/DL88250

MSN & Gmail & QQ:DL88250@gmail.com

目录

摘要 1

环境 1

导入工程 1

用户服务分析 3

用户服务扩展 3

问题描述 4

解决方案分析 4

Solution 1 4

Solution 2 4

最终方案 4

步骤 4

总结 8



摘要

看了几天Liferay了,由于要和其他系统进行整合,所以分析了一下Liferay的用户服务代码。从其用户服务代码可以看出一些Liferay的主要设计思想,为将来分析他的架构设计做下准备。

环境



导入工程

Liferay5.1.1是用NetBeans建立的Ant工程,源代码包解压后可以在NetBeans中直接打开。其工程视图如下:




先简要介绍一下源代码目录(不包含test目录)。
  • portal-impl

    包含了所有的服务实现代码,例如基本的用户管理、邮件服务、内容管理(CMS,JSR170)

  • portal-service

    包含了portal-impl的所有服务接口

  • portal-kernel

    包含了Portal/Portlet规范实现(JSR 168/268),以及基本的框架管理(Struts、Spring), 还有部署、配置、搜索、WebService、持久化的基本实现

  • support-glassfish/tomcat

    对gsf/tomcat容器的支持实现

  • util-bridges

    对一些框架/语言编写Portlet的支持。当前我们可以使用如下语言/框架来编写Portlet:

  1. Bean Scripting Framework (BSF)

  2. Groovy

  3. Javascript

  4. JSF

  5. JSP

  6. PHP

  7. Python

  8. Ruby

  9. Struts

  10. Web Accessibility Initiative (WAI)

  • util-java/taglib

    Liferay使用的基本Utilities以及标签库实现

用户服务分析

目前,Liferay项目是用Struts1.2.x + Spring 2.0作为基本框架编写的。其架构设计思路清晰明了,是难得的学习设计的示例。下面,进入本文的主题——用户服务分析。

在目录portal-service下展开源包com.liferay.portal.service,可以看到一系列****Service的接口。我们找出与用户相关的,可以得出如下类依赖关系图:



从最上层的两个接口看来,Liferay在用户服务设计方面与EJB3.x的思路是一致的,分为了Local接口与Remote接口,从代码的注释也可以得到这一点。在liferay的当前版本中(5.1.1),在图右边的Remote接口中都将服务适当处理后委托给了图左边的Local实现。其他关键的地方请参考图中的说明部分。



用户服务扩展

这里与其说是“扩展”,不如说是“修改”。

在门户与其他系统进行整合的时候,第一个困难的问题就是用户管理的问题。这里说的用户管理可以简单分为两类管理:身份认证、帐号管理。关于身份认证的问题可以使用CAS(Central Authentication Service)来实现与可系统之间的SSO(Single Sign-On/Out),可以参考这里、还有这里。帐号管理就是当前最头疼的,具体问题描述如下:

问题描述

举个例子:如果Admin在门户Liferay中建立了一个帐号,其余系统也应该建立用户帐号;如果用户在门户中修改了密码,该用户在其余系统中的帐号密码也应该作相应修改,相反则不成立。

解决方案分析

结合先前的用户服务分析类关系图,可以得出如下两个方案:

Solution 1

继承UserLocalServiceImpl类,添加我们需要的功能。

优点:以后Liferay更新了代码,对我们需要的功能不会造成影响,基本不存在代码合并的代价。

缺点:要修改Spring的配置文件,将对UserLocalServiceImpl Bean的引用改为我们的实现Bean配置。

Solution 2

直接修改UserLocalServiceImpl类代码,将所需功能委托给我们的实现。

优点:不需要修改Spring配置文件。

缺点:以后Liferay更新了代码,有一定的代码合并代价。

最终方案

综上,权衡下来。我觉得使用Solution 2。因为我认为目前修改代码对以后升级的合并代价小于修改配置文件的代价。所以,与其说是“扩展”,不如说是“修改” : )



步骤

以添加用户为例:

打开com.liferay.portal.service.impl.UserLocalServiceImpl类,找到addUser方法,在此方法最后加入我们的实现委托:

  1. // unusing spring DI, now, just for simple.
  2. // by 88250, Aug 29, 2008
  3. new SubsystemUserServiceImpl().registerUser(firstName, lastName,
  4. emailAddress, screenName, password1);

这里没有使用Spring的DI,只是为了简便一点,不用修改配置文件。以后可能会使用Spring DI。

下面就是我们所需服务的实现:

  1. /*
  2.  * To change this template, choose Tools | Templates
  3.  * and open the template in the editor.
  4.  */
  5. package com.jinfonet.developer.portal.service.impl;
  6. import com.liferay.portal.PortalException;
  7. import com.liferay.portal.security.pwd.PwdEncryptor;
  8. import java.io.IOException;
  9. import java.sql.Connection;
  10. import java.sql.DriverManager;
  11. import java.sql.ResultSet;
  12. import java.sql.SQLException;
  13. import java.sql.Statement;
  14. import java.util.logging.Level;
  15. import java.util.logging.Logger;
  16. import org.apache.commons.httpclient.HttpClient;
  17. import org.apache.commons.httpclient.HttpException;
  18. import org.apache.commons.httpclient.NameValuePair;
  19. import org.apache.commons.httpclient.methods.PostMethod;
  20. import org.apache.commons.logging.Log;
  21. import org.apache.commons.logging.LogFactory;
  22. /**
  23.  * Subsystem user service utility. Currently, this class is mainly for
  24.  * update coherence of user accounts existed in some subsystems(scarab, svn,
  25.  * etc.).
  26.  * @author 88250 <DL88250@gmail.com>
  27.  * @version 1.0.0.2, Sep 2, 2008
  28.  */
  29. public class SubsystemUserServiceImpl {
  30.     // TODO places all properties in a configuration file, no hard-coding
  31.     private final String driver = "com.mysql.jdbc.Driver";
  32.     private final String dbURL = "jdbc:mysql://192.168.128.122:3306/scarab";
  33.     private final String dbUserName = "root";
  34.     private final String dbUserPwd = "sa";
  35.     private Connection con = null;
  36.     private static Log log = LogFactory.getLog(SubsystemUserServiceImpl.class);
  37.     private final String REGISTER_URL = "http://daniel-desktop:9090/scarab/issues/template/AutoRegister";
  38.     /**
  39.      * Default constructor.
  40.      * @throws com.liferay.portal.PortalException
  41.      */
  42.     public SubsystemUserServiceImpl() throws PortalException {
  43.         try {
  44.             Class.forName(driver);
  45.         } catch (ClassNotFoundException ex) {
  46.             log.error(ex);
  47.             throw new PortalException(ex);
  48.         }
  49.     }
  50.     /**
  51.      * Changes user's password in all subsystems.
  52.      * @param userName user name 
  53.      * @param newPwd the new password(clear text)
  54.      * @throws PortalException 
  55.      */
  56.     public void changePassword(String userName, String newPwd) throws PortalException {
  57.         updatePassword(userName, newPwd);
  58.     }
  59.     /**
  60.      * Registers a new user in all subsystems.
  61.      * @param firstName first name
  62.      * @param lastName last name
  63.      * @param emailAddress email adress
  64.      * @param screenName user name
  65.      * @param password user password
  66.      * @throws PortalException 
  67.      */
  68.     public void registerUser(String firstName, String lastName, String emailAddress,
  69.             String screenName, String password) throws PortalException {
  70.         addUser(firstName, lastName, emailAddress, screenName, password);
  71.     }
  72.     private void addUser(String firstName, String lastName, String emailAddress,
  73.             String screenName, String password) throws PortalException {
  74.         HttpClient httpClient = new HttpClient();
  75.         PostMethod registerMethod = new PostMethod(REGISTER_URL);
  76.         NameValuePair[] data = {
  77.             new NameValuePair("firstName", firstName),
  78.             new NameValuePair("lastName", lastName),
  79.             new NameValuePair("email", emailAddress),
  80.             new NameValuePair("userName", screenName),
  81.             new NameValuePair("password", password),
  82.         };
  83.         registerMethod.setRequestBody(data);
  84.         try {
  85.             int status = httpClient.executeMethod(registerMethod);
  86.             log.info("Autoregister for subsystem Scarab successfully!");
  87.         } catch (IOException ex) {
  88.             Logger.getLogger(SubsystemUserServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
  89.             log.error("Autoregister for subsystem Scarab faild!", ex);
  90.             registerMethod.releaseConnection();
  91.         }
  92.     }
  93.     private void updatePassword(String userName, String newPwd) throws PortalException {
  94.         String newPwdCipherText = PwdEncryptor.encrypt(newPwd); // SHA crypt algorithm
  95.         try {
  96.             con = DriverManager.getConnection(dbURL, dbUserName, dbUserPwd);
  97.             Statement smt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
  98.                     ResultSet.CONCUR_UPDATABLE);
  99.             smt.executeUpdate("UPDATE TURBINE_USER SET PASSWORD_VALUE = '" + newPwdCipherText +
  100.                     "' WHERE LOGIN_NAME = '" + userName + "'");
  101.             smt.close();
  102.             con.close();
  103.         } catch (SQLException ex) {
  104.             log.error("Scarab Database modify failed: ", ex);
  105.             throw new PortalException(ex);
  106.         }
  107.     }
  108. }

总结

Liferay是一个设计很优秀的Portal,他有很多设计思路、代码实现是我们值得学习、借鉴的地方。关于用户服务这一块我们就分析到此,在后续的篇章中我将给大家带来更精彩的Liferay代码分析,定制出适合我们自己的门户系统!请大家继续关注我的Blog哦:http://blog.csdn.net/DL88250

: )



分享到:
评论

相关推荐

    Liferay开发持久化层和服务层演示Demo代码

    通过分析“Liferay开发持久化层和服务层演示Demo代码”这一主题,我们将理解Liferay Service Builder如何帮助开发者高效地管理数据库操作,并创建自定义服务。 首先,Liferay是一个开放源代码的企业级门户平台,它...

    liferay-portlet-development

    《Liferay Portlet 开发——全面指南》:深入解析与实战技巧 本书旨在为开发者提供一份详尽的Liferay Portlet开发指南,涵盖从基础知识到实际应用的全面内容。Liferay是一款开源的企业级门户平台,它支持高度定制化...

    LifeRay 6.1GA2开发手册-英文

    除了基础的应用程序开发外,LifeRay还允许用户通过扩展和定制的方式来满足更复杂的业务需求。这部分内容涵盖了如何通过编写插件和修改配置文件等方式来实现对LifeRay平台的功能增强。 **2.3 选择最佳工具** 本节...

    liferay-administration-guide

    2. **易于集成**:Liferay门户提供强大的插件市场(Liferay Plugins Catalog),方便开发者进行二次开发和扩展。 3. **支持的技术**: - 支持多种编程语言,如Java等。 #### 四、初始设置 ##### 1. Liferay的...

    liferay-developer-guide-6.0

    - **Ext plugins(扩展插件)**:这是Liferay的一种高级扩展机制,通过创建扩展插件,开发者可以在不影响Liferay核心代码的情况下添加新功能。 - **The Web Application Integrator (WAI)(Web应用程序集成器)**:...

    wicket_liferay_porlet_sample

    Liferay是一款开源的企业级内容管理和数字体验平台,它允许开发者创建可部署在门户上的portlet,以提供定制化的用户界面和服务。Wicket是一个Java Web应用程序框架,以其组件模型和强大的状态管理而知名。 【描述】...

    基于JAVA的源代码搜索引擎架构实现.pdf

    本文介绍了一种基于JAVA实现的源代码搜索引擎——Hicode的设计与实现方法。该系统旨在为用户提供一种高效查找特定编程语言源代码的方法。 #### 关键技术与组件 ##### Lucene引擎 Hicode采用了Apache Lucene作为其...

    liferay-solutions:生命线解决方案

    描述中的“生命线解决方案”可能指的是通过JavaScript来解决Liferay中的特定问题或挑战,比如提高页面性能、实现复杂的用户界面、增强可访问性或者集成第三方服务。生命线解决方案的目标是确保Liferay系统的稳定性和...

    Portlet-Specification(2).rar_portlet

    Portlet API是JavaServer Pages (JSP) 和Java Servlet技术的扩展,旨在解决多应用集成和用户界面定制的问题。 文档"Portlet Specification(2).doc"很可能涵盖了以下关键知识点: 1. **Portlet生命周期**:Portlet...

    struts2.jar包(struts2.1.8.jar包)一号文件(太大总共分三次)

    这个框架在Java社区中广泛使用,因为它简化了开发流程,提高了代码的可维护性和可测试性。 标题中的"struts2.1.8.jar包"指的是Struts2框架的特定版本——2.1.8。每个版本的Struts2都可能包含一些新特性、改进和安全...

Global site tag (gtag.js) - Google Analytics