美文网首页
IM即时聊天系统-Openfire爬坑之路三 插件1

IM即时聊天系统-Openfire爬坑之路三 插件1

作者: 渝潼不肖生 | 来源:发表于2020-04-24 18:04 被阅读0次

    插件结构

    myplugin /
     |-pom.xml <-Maven项目的插件描述/配置文件(允许您定义Maven使用的POM(项目对象模型)。
     |-plugin.xml <-插件定义文件
     |-readme.html <-插件的可选自述文件,它将显示给最终用户
     |-changelog.html <-插件的可选changelog文件,它将显示给最终用户
     |-logo_small.gif <-与插件关联的可选小(16x16)图标(也可以是.png文件)
     |-logo_large.gif <-与插件关联的可选大(32x32)图标(也可以是.png文件)
     |-src   
        |-classes / <-插件所需的资源(即属性文件)
        |-database/ <-插件所需的可选数据库架构文件
        |-i18n / <-可选的i18n文件,以允许插件国际化。
        |-lib / <-插件需要的库(JAR文件)
        |-java / <-这是包含插件应用程序(.java文件)源的目录,位于软件包中
        |-web <-管理控制台集成的资源(如果有)
            |-WEB-INF /
                |-web.xml <-包含编译的JSP条目的生成的web.xml
                |-web-custom.xml <-自定义servlet的可选用户定义的web.xml
            |-images/
    

    plugin.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <plugin>
        <!-- 插件主类 -->
        <class>org.example.ExamplePlugin</class>
    
        <!--插件信息-->
        <name>Example Plugin</name>
        <description>This is an example plugin.</description>
        <author>阿伦</author>
        <version>1.0</version>
        <date>07/01/2006</date>
        <url>http://www.baidu.com</url>
        <minServerVersion>3.0.0</minServerVersion>
        <licenseType>gpl</licenseType>
    
        <!-- 管理控制台条目 -->
        <adminconsole>
            <!-- 控制台内容 -->
        </adminconsole>
    </plugin>
    
    • name -- 插件的名称。
    • description -- 插件的描述。
    • author -- 插件的作者。
    • version -- 插件的版本。
    • date -- 插件发布的日期。日期必须采用MM / dd / yyyy格式,例如07/01/2006。
    • url -- 其中提供了有关插件的其他信息。
    • minServerVersion -- 运行插件所需的Openfire的最低版本(受Openfire 2.1.2和更高版本支持)。如果服务器版本小于要求的值,则不会启动插件。
    • beforeToServerVersion -- 可以运行此插件的服务器版本,但不包括此版本。
    • minJavaVersion --插件需要运行的最低Java规范版本。
    • databaseKey -- 如果插件需要它自己的数据库表,则应使用架构键名称(通常与插件名称相同)来设置databaseKey元素。然后,应将每个受支持数据库的数据库模式文件放置在 插件的数据库目录中。例如,给定键“ foo”,模式文件将被称为“ foo_mysql.sql”,“ foo_oracle.sql”等。我们建议您为表加上“ of”(openfire)前缀,以避免与其他应用程序发生冲突安装在同一数据库中。脚本应使用键在ofVersion表中进行输入,以便可以跟踪架构版本信息,例如:
    INSERT INTO ofVersion (name, version) VALUES ('foo', 0);
    
    • databaseVersion -- 数据库模式版本(如果定义了数据库模式)。具有数据库模式的新插件应从版本0开始。如果插件的未来版本需要对该模式进行更新,则可以通过在数据库/升级目录中为每个版本号创建子目录来定义这些更新。例如,目录 database / upgrade / 1database / upgrade / 2将包含诸如“ foo_mysql.sql”和“ foo_oracle.sql”之类的脚本,这些脚本包含每个版本的相关数据库更改。每个脚本应更新ofVersion表中的版本信息,例如:
    UPDATE ofVersion set version=1 where name='foo';
    
    • parentPlugin -- 父插件的名称(对于“ foo.jar”插件,命名为“ foo”)。当插件具有父插件时,将使用父插件的类加载器,而不是创建新的类加载器。这使插件可以更紧密地协同工作。没有父插件,子插件将无法运行。
    • licenseType -- 指示插件受其管辖的许可协议。有效值为:

    “commercial”:该插件是根据商业许可协议发布的。
    “gpl”:该插件是根据GNU公共许可证(GPL)发布的。
    “apache”:该插件根据Apache许可发布。
    “internal”:该插件仅供组织内部使用,不会重新分发。
    “other”:该插件是根据许可协议发行的,该许可协议不属于其他类别之一。许可协议应该是插件自述文件中的详细信息。
    如果未设置许可证类型,则假定为其他。

    插件中可以存在几个其他文件,以向最终用户提供其他信息(所有信息都放置在主插件目录中):

    • readme.html -- 插件的可选自述文件,将显示给最终用户。
    • changelog.html -- 插件的可选changelog文件,将显示给最终用户。
    • logo_small.png -- 与插件关联的可选小(16x16)图标。它也可以是.gif文件。
    • logo_large.png -- 与插件关联的可选大(32x32)图标。它也可以是.gif文件。

    实现 Plugin接口

    插件实现Openfire APIPlugin 接口,并且必须具有默认(无参数)构造函数。Plugin接口具有用于初始化和销毁​​插件的方法。

    package org.example;
    import org.jivesoftware.openfire.container.Plugin;
    import org.jivesoftware.openfire.container.PluginManager;
    import java.io.File;
    /**
     *实例
     */
    public class ExamplePlugin implements Plugin {
        //初始插件回调
        public void initializePlugin(PluginManager manager, File pluginDirectory) {
            // 这里写你的代码
        }
      //销毁插件回调
        public void destroyPlugin() {
            // 这里写你的代码
        }
    }
    

    修改管理控制台

    插件可以将标签,部分和页面添加到管理控制台。步骤:

    • 必须将<adminconsole />部分添加到 plugin.xml文件中。
    • 必须编译JSP文件并将其放入插件的类路径中。一个web.xml中含有编译JSP的servlet项文件必须放到插件目录 web/。注意: Openfire构建脚本可以帮助编译JSP和创建web.xml。这在下面详细说明。
    • JSP页面所需的任何图片都必须位于web / images / 目录中。仅支持GIF和PNG图像。

    plugin.xml的<adminconsole />部分定义了管理控制台框架中的其他选项卡,部分和条目。一个示例 plugin.xml文件可能如下所示:
    plugin.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <plugin>
        <!-- Main plugin class -->
        <class>org.example.ExamplePlugin</class>
        <!-- Admin console entries -->
        <adminconsole>
            <tab id="mytab" name="Example" url="my-plugin-admin.jsp" description="Click to manage...">
                <sidebar id="mysidebar" name="My Plugin">
                   <item id="my-plugin" name="My Plugin Admin"
                       url="my-plugin-admin.jsp"
                       description="Click to administer settings for my plugin"
                       order="4" />
                   <item id="my-plugin" name="My Plugin Overview"
                       url="my-plugin-overview.jsp"
                       description="Click to have an Overview of Plugin usage"
                       order="2" />
                </sidebar>
            </tab>
        </adminconsole>
    </plugin>
    

    在此示例中,我们定义了一个新选项卡“ Example”,一个侧栏部分“ My Plugin”和两个页面:“ My Plugin Admin”和“ My Plugin Overview”。我们已经分别将my-plugin-admin.jsp和my-plugin-overview.jsp注册 为页面。
    默认情况下,选项卡,侧边栏和页面将按照定义顺序显示。但是,您可以通过向每个元素添加“ order”属性来定义显式排序。它的数值定义顺序。如果未指定任何顺序,则默认值为0。在上面的示例中,使用此构造对项目​​进行排序。在管理控制台中,“My Plugin Overview”页面将在“My Plugin Admin”页面之前显示,因为其“order”值较低。如果两个项目都未定义'order'属性,则两个页面的显示都将被反转(因为它曾经用来对以XML定义页面的顺序进行排序)。
    您可以使用自己的<adminconsole>定义中的现有id属性值来覆盖现有的tabs, sections和items 。

    管理控制台最佳做法

    通过插件更改Openfire管理控制台时,需要考虑几种最佳做法。一般主题是插件应无缝集成:

    • 尽可能将其集成到现有的选项卡和侧边栏部分中,而不是自己创建。仅为非常重要的新功能创建新选项卡。
    • 标签,侧边栏和项目名称中请勿使用“插件”一词。例如,与其具有名为“ Gateway Plugin”的项目,不如将其称为“ Gateway Settings”。
    • 尝试在您的自定义插件页面中匹配现有管理控制台的用户界面。
    • 无需创建管理控制台条目即可显示插件元数据。相反,让Openfire通知用户有关已安装哪些插件的信息并提供插件管理。

    编写管理控制台页面

    Openfire使用Sitemesh 框架在管理控制台中装饰页面。如下图所示,将全局定义的装饰器应用于每个页面以呈现最终输出:

    Sitemesh

    创建适用于Sitemesh的页面很容易。只需创建有效的HTML页面,然后使用元标记将指令发送到Sitemesh。呈现输出时,Sitemesh将使用您提供的说明来呈现装饰器以及HTML页面正文中的任何内容。可以使用以下元标记:

    • pageID -- 页面的ID,必须与上述管理控制台XML中的条目匹配。必须指定pageID或subPageID 。
    • subPageID -- 子页面的ID,必须与上述管理控制台XML中的条目匹配。子页面用于与父页面ID相关的管理操作。例如,编辑或删除特定组。必须指定pageID或subPageID 。
    • extraParams(可选)--应该传递给页面的额外参数。例如,在要删除组的页面上,它可能是该组的ID。参数必须经过URL编码。
    • decorator(可选)-- 覆盖用于页面的Sitemesh装饰器。可以使用名为none的装饰器,该装饰器将在没有装饰器的情况下简单地呈现页面。
       <html>
           <head>
               <title>My Plugin Page</title>
               <meta name="pageID" content="myPluginPage"/>
           </head>
           <body>
                Body here!
           </body>
       </html>
    

    在插件中使用i18n

    可以将您的插件翻译成多种语言(i18n)。为此,请使用以下过程:

    • 在插件的根目录中创建一个“ i18n”目录。
    • 使用%[plugin_name]%_i18n "_" language ".properties"命名约定添加每个资源文件,其中[plugin_name]是插件目录的名称。有关资源束的更多信息,请参见 翻译指南
    • 将JSP文件中的字符串转换为引用国际化密钥。例如:
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
     ...
    <fmt:message key="some.key.name" />
    
    • 使用LocaleUtils类将Java文件中的字符串国际化:
    org.jivesoftware.util.LocaleUtils.getLocalizedString("some.key.name", "[plugin_name]");
    

    使用$ {var}格式将plugin.xml文件中的字符串国际化:

    <sidebar id="gateways" name="${plugin.sidebar.name}" description="${plugin.sidebar.description}">
    <description>${plugin.description}</description>
    

    使用Openfire构建脚本
    Openfire构建脚本将帮助您构建和开发插件。它以以下格式查找插件开发目录:
    插件结构

    myplugin/
     |- plugin.xml      <- Plugin definition file
     |- readme.html     <- Optional readme file for plugin
     |- changelog.html  <- Optional changelog file for plugin
     |- logo_small.gif  <- Optional small (16x16) icon associated with the plugin (can also be a .png file)
     |- logo_large.gif  <- Optional large (32x32) icon associated with the plugin (can also be a .png file)
     |- classes/        <- Resources your plugin needs (i.e., a properties file)
     |- lib/            <- Libraries your plugin needs
     |- src/
         |- database    <- Optional database scripts for your plugin
         |- java        <- Java source code for your plugin
         |   |- com
         |       |- mycompany
         |           |- *.java
         |- web
             |- *.jsp      <- JSPs your plugin uses for the admin console
             |- images/    <- Any images your JSP pages need (optional)
             |- WEB-INF
                 |- web.xml    <- Optional file where custom servlets can be registered
    

    构建脚本将编译源文件和JSP,并创建有效的插件结构和JAR文件。将您的插件目录放在 源发行版的src / plugins目录中,然后使用ant插件来构建您的插件。

    您的插件在编译过程中需要的所有JAR文件都应放在lib目录中。在构建过程中,还将这些JAR文件复制到插件的生成的lib目录中。

    如果创建src / web / WEB-INF / web.xml文件,则在插件启动时将初始化在此注册的所有servlet。从web.xml文件中仅接受servlet注册和servlet映射。注意:此功能是通过将您的自定义web.xml文件合并到JSP编译过程生成的web.xml文件中来实现的。
    ***********=============现在推荐用maven构建,下一章介绍===========************

    实施您的插件

    插件具有对Openfire API的完全访问权限。这为插件可以完成的工作提供了极大的灵活性。但是,有几个最常见的集成点:

    1. 将插件注册为Component。组件接收所有发往特定子域的数据包。例如, test_component.example.com。因此,发送到 joe_component.example.com 的数据包将被传递到该组件。请注意,定义为组件的子域与子域的DNS条目无关。套接字级别的所有XMPP路由都使用主服务器域(在上面的示例中为example.com)完成;子域仅用于XMPP服务器中的路由。

    2. 将插件注册为IQHandler。IQ处理程序以特定的元素名称和名称空间响应IQ数据包。以下代码段演示了如何注册IQHandler:

      IQHandler myHandler = new MyIQHander();
      IQRouter iqRouter = XMPPServer.getInstance().getIQRouter();
      iqRouter.addHandler(myHandler);
    
    
    1. 将插件注册为 PacketInterceptor以接收通过系统发送的所有数据包,并有选择地拒绝它们。例如,拦截器可以拒绝所有包含敏感词的邮件或将其标记为由管理员查看。

    2. 您可以使用JiveGlobals.getProperty(String)和JiveGlobals.setProperty(String,String)方法将持久性插件设置存储为Openfire属性。通过实现org.jivesoftware.util.PropertyEventListener方法,使插件成为属性侦听器,以侦听对其属性的更改 。您可以使用PropertyEventDispatcher.addListener(PropertyEventListener)方法将插件注册为侦听器。确保在插件的destroyPlugin()方法中将插件注册为侦听器。

    Openfire管理员标签

    Openfire提供了可以使用的有用的JSP标签。要在JSP页面上启用它们,只需在JSP页面

    <%@ taglib uri="admin" prefix="admin" %> 
    

    顶部添加标签,包括:

    <admin:ASN1DER value="${ASN.1 DER certificate as a byte[]}"/>
    <!-- (自Openfire 4.0.0起)将在HTML表中显示ASN.1 DER编码的证书。-->
    
    <admin:FlashMessage/>
    <!--(自Openfire 4.5.0起)将在呈现的页面上最多显示三个经过适当装饰的会话属性。
    这些会话属性的密钥是由定义 FlashMessageTag.SUCCESS_MESSAGE_KEY,
    WARNING_MESSAGE_KEY和 ERROR_MESSAGE_KEY。这允许在页面之间
    导航时向用户显示消息。-->
    

    CSRF保护

    管理员页面容易受到CSRF攻击。Openfire提供了一些工具来帮助插件作者在其管理页面上防御这些攻击。启用CSRF保护:

    1. 将plugin.xml设置minServerVersion为4.5.0或更高版本,因为这是添加支持时的状态。
    2. 将plugin.xml csrfProtectionEnabled设置true为启用插件的CSRF保护。这将;
      • 防范CSRF攻击,除了 GET请求,所有对管理页面的请求
      • 使用键“ csrf”设置servlet请求属性
    3. 确保GET请求不会修改任何设置或更改任何数据,因为未为GET请求启用此保护
    4. 确保在管理页面中提交的任何表单都有一个名为csrf的字段,该字段的值由请求属性“ csrf”定义-例如:
    <input name="csrf" value="<c:out value="${csrf}"/>" type="hidden">
    

    如果检测到CSRF攻击,将使用FlashMessageTag.ERROR_MESSAGE_KEY设置了session属性以指示问题的状态(使用简单的HTTP GET请求)重新加载管理页面-因此建议<admin:FlashMessage/>在JSP页面的顶部包含。
    注意 :使用<c:out>标签或等效标签确保所有输出正确转义仍然很重要 。

    插件常见问题

    我可以将插件部署为目录而不是JAR吗?
    不,所有插件都必须部署为JAR或WAR文件。当插件不存在JAR或WAR时,Openfire会假定该文件已被删除,并且用户希望销毁该插件,因此它也会删除该目录。

    相关文章

      网友评论

          本文标题:IM即时聊天系统-Openfire爬坑之路三 插件1

          本文链接:https://www.haomeiwen.com/subject/tbnfwhtx.html