模型听众钩

背景

Model Listener hook 是一种 Liferay 插件,它监听模型上的事件并执行响应代码。模型侦听器钩子类似于自定义 Struts Action 钩子,因为它们响应门户中采取的操作。但是,当 Struts 操作响应用户采取的操作时,模型侦听器会响应(在之前或之后)涉及 Liferay 模型的事件。

差异

以下是 Struts Actions v。模型监听器的一些示例,用于比较。

  • Struts Action
    • 用户登录
    • 帐户创建
    • 扩展会话
    • 移动文件夹
  • 模型听众
    • 创建文件夹后
    • 更新用户信息时
    • 删除书签后
    • 在进行角色关联之前

学习 Liferay 架构的最佳资源是通过他们的源代码。他们所有的源文件都位于 GitHub 上,并通过查看他们的 JavaDocs。你可以在 JavaDocs 上看到所有核心门户模型以及 GitHub 上的所有 Struts Actions

在本教程中,我们将开发一个模型监听器,在首次创建帐户后向用户发送电子邮件。为此,我们将编写一个名为 UserModelListener 的类,它将扩展 Liferay 的 BaseModelListener 。我们将简要介绍钩子创建,并将涵盖对以下配置文件的必要修改

  • portal.properties

  • Liferay 的 -hook.xml

入门

要开始开发 Model Listener 钩子,必须首先启动 Liferay IDE 或 Liferay Developer Studio 应用程序。

Liferay IDE 和 Liferay Developer Studio 都是定制的 Eclipse 开发环境。它们非常相似,一套方向应该足够两种环境。

在开发环境中执行以下步骤。

  1. 在左上角,单击“ 文件”
  2. 将鼠标悬停在 New 上
  3. 单击 Liferay 插件项目

你将产生这个窗口。

https://i.stack.imgur.com/KvumU.jpg

请输入如上所示的信息

  • 项目名称: User-Model-Listener
  • 选择使用默认位置
  • 构建类型: Ant
  • 插件类型: 钩子

确保你的项目位于 Liferays Plugins SDK Hook 目录中。你需要相应地选择 SDK运行时

Package Explorer 透视图中,你将看到以下目录结构。

https://i.stack.imgur.com/vJvaf.jpg

听众发展

现在你已经创建了钩子,你将需要创建自定义 UserModelListener 类。该类将扩展 Liferay 的 BaseModelListener 类。

Liferay 的 BaseModelListener 类是一个实现 ModelListener 接口的抽象类。你不希望直接实现 ModelListener 接口,因为它将要求你覆盖其所有方法。

ModelListener 接口通过 BaseModelListener 抽象类为你提供了以下方法。

  • onAfterAddAssociation
  • onAfterCreate
  • onAfterRemove
  • onAfterRemoveAssociation
  • onAfterUpdate
  • onBeforeAddAssociation
  • onBeforeCreate
  • onBeforeRemove
  • onBeforeRemoveAssociation
  • onBeforeUpdate

在以下目录中创建 UserModelListener 类。要通过 GUI 创建类,只需执行以下命令即可

  • 单击左上角的文件
  • 将鼠标悬停在 New 上
  • 单击“ 类”
docroot/
     WEB-INF/
           src/

输入以下信息

https://i.stack.imgur.com/FMcSI.jpg

UserModelListener 类中,粘贴以下代码

package com.example.hook;

import com.liferay.mail.service.MailServiceUtil;
import com.liferay.portal.ModelListenerException;
import com.liferay.portal.kernel.mail.MailMessage;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.model.BaseModelListener;
import com.liferay.portal.model.User;

import javax.mail.internet.InternetAddress;

public class UserModelListener extends BaseModelListener<User> {
    private User user = null;

    @Override
    public void onAfterCreate(User user) throws ModelListenerException {
    this.user = user;
    
    if(isValidEmail()) {
        sendEmail("admin@example.com", user.getEmailAddress(), "Welcome!", "Your account is created!");
    } 
    }

    private boolean isValidEmail() {
    return Validator.isNotNull(user.getEmailAddress()) && Validator.isAddress(user.getEmailAddress());
    }
    
    private void sendEmail(String from, String to, String subject, String body) {
    try {
        MailServiceUtil.sendEmail(new MailMessage(new InternetAddress(from), new InternetAddress(to), subject, body, false));
    } catch (Exception e) {
        System.err.print("E-Mail spawned by User Model Listener failed to " + user.getFullName() + " with message " + e.getMessage());
    }
    }
}

属性配置

为了配置我们的自定义侦听器和我们的模型之间的关联,我们需要进行一些最终调整。首先,在以下目录中创建一个新的 portal.properties 文件

docroot/
     WEB-INF/
           src/
            + portal.properties

只需要将一行添加到文件中。

value.object.listener.com.liferay.portal.model.User = com.example.hook.UserModelListener

我们可以通过说,对于任何模型监听器我们创建关联属性值必须采用的形式来概括

value.object.listener.fully.qualified.model.name = fully.qualified.listener.name

换句话说,如果我们编写了一个 CustomerDLFolderModelListener 类,打包在 com.example.code 中,对于 DLFolder 模型,我们将具有以下属性

value.object.listener.com.liferay.portal.model.DLFolder = com.example.code.CustomerDLFolderModelListener 

最后,找到 liferay-hook.xml 文件。在“ 源” 视图中,编写以下内容。

<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd">

<hook>
    <portal-properties>portal.properties</portal-properties>
</hook>

说明

  1. 第一行是可选的序言,它指定文档版本和(在某些情况下)字符集。
  2. 第 2 行是正式的 DocType 定义 (DTD),它明确定义了哪些元素和属性是有效的
  3. 第 3 行和第 5 行由父 Hook 元素 (此 DTD 支持的有效元素之一)组成
  4. 第 4 行覆盖并扩展 $ {liferay.home}中portal.properties 文件 ****

要查看此 XML 文件中可以使用的其他元素,你可以在 DocType 定义中引用 URL。这是带有 DTD 的所有 XMLSGML 文件的标准。带有 DTDLiferay XML 文件的另一个例子是 service.xml (Liferay 的基于 HibernateORM 实现 )。 **** **** **** **** **** **** ****

构建和部署

构建和部署钩子是一个简单的过程。Liferay 插件开发支持构建和依赖自动化

  • 蚂蚁
  • 常春藤
  • Maven 的
  • 摇篮

在我们的示例中,我们使用 Ant 进行构建自动化该的 build.xml 文件包含构建命令(被称为目标蚂蚁 )。要构建钩子,只需执行以下命令即可。

  1. 找到你的 build.xml 文件
  2. 在 IDE 中,将 build.xml 文件拖到 Ant 透视图中
  3. 展开文件并运行所有目标

https://i.stack.imgur.com/xzDde.jpg

在控制台视图中,你应该看到类似于以下内容的内容

Buildfile: C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\build.xml
all:
clean:
   [delete] Deleting directory C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\docroot\WEB-INF\classes
clean-portal-dependencies:
compile:
merge:
compile-import-shared:
    [mkdir] Created dir: C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\docroot\WEB-INF\classes
     [copy] Copying 5 files to C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\docroot\WEB-INF\lib
compile-java:
     [copy] Copied 3 empty directories to 3 empty directories under C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\docroot\WEB-INF\classes
    [javac] Compiling 1 source file to C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\docroot\WEB-INF\classes
merge:
war:
clean-portal-dependencies:
      [zip] Building zip: C:\liferay-plugins-sdk-6.2-ee-sp11\dist\User-Listener-Hook-hook-6.2.10.1.war
deploy:
     [copy] Copying 1 file to C:\liferay-portal-6.2-ee-sp11\deploy
BUILD SUCCESSFUL
Total time: 7 seconds

成功构建 Hook 后,现在可以启动门户并进行部署。要启动服务器并部署 Hook,请找到 Server 透视图。

  1. 右键单击你的服务器,然后单击添加或删除
  2. Available 选项下找到 User-Listener-Hook ****
  3. 高亮显示后点击添加按钮,然后单击 OK
  4. 单击 Server 透视图中的 Play 按钮 ****

StackOverflow 文档

如果你有任何问题,意见,疑虑等,请告知我们。非常感谢所有建设性的反馈!