跟我一步一步開發本身的Openfire插件

這篇是簡單插件開發,下篇聊天記錄插件。html

開發環境:前端

System:Windowsjava

WebBrowser:IE6+、Firefox3+web

JavaEE Server:tomcat5.0.2.八、tomcat6apache

IDE:eclipse、MyEclipse 8瀏覽器

開發依賴庫:tomcat

Jdk1.六、jasper-compiler.jar、jasper-runtime.jar、openfire.jar、servlet.jar服務器

Email:hoojo_@126.comapp

Blog:http://blog.csdn.net/IBM_hoojo  eclipse

http://hoojo.cnblogs.com/

在開始以前,若是你不知道怎麼使用openfire,安裝openfire服務器,建議你看這篇文章:

http://www.cnblogs.com/hoojo/archive/2012/05/17/2506769.html  

http://www.cnblogs.com/hoojo/archive/2012/05/13/2498151.html

1、準備工做

一、 下載相關jar包和openfire源碼

Openfire源碼下載:http://www.igniterealtime.org/downloads/download-landing.jsp?file=openfire/openfire_src_3_8_0.tar.gz  

其餘的jar包你能夠去tomcat中的lib目錄找到或者其餘的地方也有(在下面的步驟會提到),這裏就贅述了。

二、 新建一個本身的java project工程,添加的jar包以下:

將jasper-compiler.jar、jasper-runtime.jar、servlet.jar添加到新建的工程中。若是沒有jar先不要急,看下面的步驟:

下載後的openfire源碼目錄是這樣的

clip_image002  

若是你有ant工具能夠用dos命令行的方式,直接運行build目錄中的ant腳本,運行腳本後,你會發現有一個target的目錄。該目錄以下:

clip_image004  

在lib目錄中能夠找到咱們須要的jar文件了,將openfire.jar也添加到你的工程中。

如 果你沒有安裝ant你能夠用MyEclipse,將openfire源碼中的build、documentation、resources目錄複製到一個 Java Project中,而後在MyEclipse中運行src中的build.xml ant腳本就會出現和上面同樣的文件目錄。

建議將你的MyEclipse中的openfire源碼工程目錄設置成這樣的

clip_image006  

其 中,src/plugins/tree是我本身寫的插件,如今暫時能夠無視。而target就是咱們須要的,裏面存放了openfire的配置和須要的 jar包。Work是工做目錄,是一個完整的openfire服務器。若是你尚未下載openfire服務器的話,能夠用這個服務器。

三、 瞭解openfire源碼中的插件

咱們找一個插件目錄看看,主要看看裏面的結構,目錄結構很重要。由於咱們將寫好的插件打成jar包後,打包的jar的目錄有必定規範結構,不能隨便創建其餘目錄。

clip_image008  

這 是一個userservice的插件,在src/java中是咱們的插件源代碼;web目錄中則是前端的頁面,其中web-custom.xml是配置當 前插件UserServiceServlet配置;changelog.html是修改日誌;logo_small.gif是插件圖 標;plugin.xml是咱們配置插件的文件,這個很重要(在這裏先提示下);

2、開發簡單插件

工程如今的目錄機構以下

clip_image010

一、 創建本身的插件類,SamplePlugin.java,裏面簡單的寫點內容。

package com.hoo.server.plugin;
 
import java.io.File;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
 
/**
 * <b>function:</b> openfire server plugin sample
 * @author hoojo
 * @createDate 2013-2-28 下午05:48:22
 * @file SamplePlugin.java
 * @package com.hoo.server.plugin
 * @project OpenfirePlugin
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
public class SamplePlugin implements Plugin {
 
    private XMPPServer server;

    @Override
    public void initializePlugin(PluginManager manager, File pluginDirectory) {
        server = XMPPServer.getInstance();
        System.out.println("初始化…… 安裝插件!");
        System.out.println(server.getServerInfo());
    }
 
    @Override
    public void destroyPlugin() {
        System.out.println("服務器中止,銷燬插件!");
    }
}

比較簡單,若是你將插件安裝在openfire服務器上的時候,啓動服務器一個能夠看到初始化的內容,關閉服務器能夠看到銷燬的內容。

二、 配置插件

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<!-- Main plugin class  這裏是最重要滴,就是你的插件的全路徑-->
<class>com.hoo.server.plugin.SamplePlugin</class>
 
<!-- Plugin meta-data -->
<name>SimplePlugin</name>
<description>This is the my sample plugin.</description>
<author>hoojo</author>
 
<version>1.0</version>
<date>28/02/2013</date>
<url>http://localhost:9090/openfire/plugins.jsp</url>
<minServerVersion>3.4.1</minServerVersion>
<licenseType>gpl</licenseType>
 
<adminconsole>
    </adminconsole>
</plugin>

注意上面的class的配置,那個配置是最爲重要的,配置的是插件的全路徑;name是插件的名稱,安裝後的插件名稱;author是插件做者;lincenseType是協議;adminconsole是配置插件關聯的頁面的;稍後再講!

三、 可部署的插件包jar的目錄結構

這個很重要,目錄結構將決定你插件 發佈的成敗。

在編寫命令以前,咱們能夠看看openfire服務器中已經安裝的插件的jar包的目錄結構,到時候咱們也要打包成那樣的結構才行的。必須打包成這樣的目錄結構,不然哼哼……後果很嚴重的!聲明!

在我機器中的openfire服務器中,插件目錄在C:\Program Files\openfire\plugins,裏面有一個search.jar插件。提示:當你將一個能夠安裝的jar安裝在openfire後,會被 openfire解壓成目錄結構。就向JavaEE中的war包發佈的應用服務器中的效果同樣的。

打成可部署的插件jar包(至關於發佈的應用服務器的目錄結構)的search.jar目錄結構以下:

clip_image012

首先看看文件命名,search.jar就是咱們打包的插件的名稱,而國際化的配置文件就是以插件名稱開頭 _118n.properties或插件名稱開頭_118n_language.properties;而lib目錄中的是插件的src目錄的class 打成的jar包;帶有*-jspc.jar是web目錄下的jsp編譯成servlet後的class打成的包文件,都是以插件名稱開頭;WEB- INF/web.xml配置的是*-jspc.jar中的class文件;web/images是圖片文件,須要用到的圖片都放置在這個目錄即 可;plugin.xml文件名固定的,裏面是配置插件的xml內容。

其中,118n國際化文件,它主要是咱們在插件中的jsp和Java程序中的國際化配置。Web目錄存放jsp、圖片、web.xml內容;lib目錄是存放插件的src目錄的java代碼編譯後打包的jar,以及jsp編譯成servlet的class打包後的jar;其餘的文件都是根目錄的;

對照上面插件包的jar,咱們看看實際開發中的目錄結構:

clip_image014

稍提醒下,若是你的插件中包含servlet,那你須要將它配置在web目錄下的WEB-INF/web-custom.xml目錄中;這個在之後會常常用到的,好比你提供一個接口給外部程序調用的狀況下。目錄結構參考:

clip_image016

UserServiceServlet配置在web-custom.xml目錄中。

四、 編寫ant命令,打可部署jar包。若是你不懂ant命令也不要緊,你總知道java的基本經常使用的dos命令。只不過ant就是將dos轉換成一個可重複屢次調用的命令行。

在工程的根目錄中新建一個build目錄,新建

build.xml

<project name="Webapp Precompilation" default="openfire-plugins" basedir=".">
    <property file="build.properties" />

    <!-- java servlet相關文件編譯jar存放位置 -->
    <property name="java.jar.dir" value="${webapp.path}/java-dist"/>
    <!-- jsp servlet編譯後jar存放位置 -->
    <property name="jsp.jar.dir" value="${webapp.path}/jsp-dist/lib"/>

    <!-- 定義java servlet和jsp servlet的jar包名稱 -->
    <property name="java.jar" value="${java.jar.dir}/plugin-${plugin.name}.jar"/>
    <property name="jsp.jar" value="${jsp.jar.dir}/plugin-${plugin.name}-jsp.jar"/>

    <!-- jsp servlet配置到web.xml中 -->
    <property name="plugin.web.xml" value="${webapp.path}/jsp-dist/web.xml"/>

    <!-- 編譯jsp 並生成相關jar、xml文件 -->
    <target name="jspc">

        <taskdef classname="org.apache.jasper.JspC" name="jasper2">
            <classpath id="jspc.classpath">
                <pathelement location="${java.home}/../lib/tools.jar" />
                <fileset dir="${tomcat.home}/bin">
                    <include name="*.jar" />
                </fileset>
                <fileset dir="${tomcat.home}/server/lib">
                    <include name="*.jar" />
                </fileset>
                <fileset dir="${tomcat.home}/common/lib">
                    <include name="*.jar" />
                </fileset>
                <!--
                <fileset dir="D:/Workspace/openfire/build/lib">
                    <include name="**/*.jar" />
                </fileset-->
            </classpath>
        </taskdef>

        <!-- 編譯jsp->servlet class -->
        <jasper2 javaEncoding="UTF-8" validateXml="false"
            uriroot="${plugin.path}/web"
            outputDir="${webapp.path}/jsp-dist/src"
            package="com.hoo.openfire.plugin.${plugin.name}" />

        <!-- 編譯後的servlet class 配置到web.xml文件中 -->
        <jasper2
            validateXml="false"
            uriroot="${plugin.path}/web"
            outputDir="${webapp.path}/jsp-dist/src"
            package="com.hoo.openfire.plugin.${plugin.name}"
            webXml="${plugin.web.xml}"/>
    </target>

    <!-- 編譯jsp 並將其打jar包 -->
    <target name="compile">
 
        <mkdir dir="${webapp.path}/jsp-dist/classes" />
        <mkdir dir="${webapp.path}/jsp-dist/lib" />
        <mkdir dir="${webapp.path}/jsp-dist/src" />

        <javac destdir="${webapp.path}/jsp-dist/classes" optimize="off"
            encoding="UTF-8" debug="on" failonerror="false"
            srcdir="${webapp.path}/jsp-dist/src" excludes="**/*.smap">
            <classpath>
                <pathelement location="${webapp.path}/jsp-dist/classes" />
                <fileset dir="${webapp.path}/jsp-dist/lib">
                    <include name="*.jar" />
                </fileset>
                <pathelement location="${tomcat.home}/common/classes" />
                <fileset dir="${tomcat.home}/common/lib">
                    <include name="*.jar" />
                </fileset>
                <pathelement location="${tomcat.home}/shared/classes" />
                <fileset dir="${tomcat.home}/shared/lib">
                    <include name="*.jar" />
                </fileset>
                <fileset dir="${tomcat.home}/bin">
                    <include name="*.jar" />
                </fileset>
            </classpath>
            <include name="**" />
            <exclude name="tags/**" />
        </javac>

        <jar jarfile="${jsp.jar}" basedir="${webapp.path}/jsp-dist/classes" />
    </target>
 
    <!-- 將java servlet打包成jar -->
    <target name="java-jar">
        <mkdir dir="${java.jar.dir}"/>
        <jar jarfile="${java.jar}">
            <fileset dir="${webapp.path}/bin" includes="**/*.class"/>
        </jar>
    </target>
 
    <!-- 生成可部署的插件包 -->
    <target name="plug-jar">
        <!-- 插件插件包相關lib、 web目錄 -->
        <mkdir dir="${webapp.path}/${plugin.name}/lib"/>
        <mkdir dir="${webapp.path}/${plugin.name}/web/WEB-INF"/>
 
        <!-- 複製jsp servlet的jar和java servlet的相關jar包到插件包的lib目錄下 -->
        <copy file="${java.jar}" todir="${webapp.path}/${plugin.name}/lib"/>
        <copy file="${jsp.jar}" todir="${webapp.path}/${plugin.name}/lib"/>
 
        <!-- 將相關的圖片、幫助文檔、修改日誌等文件複製到插件目錄下 -->
        <copy todir="${webapp.path}/${plugin.name}">
            <fileset dir="${plugin.path}" includes="*.*"/>
        </copy>
        <copy todir="${webapp.path}/${plugin.name}/web">
            <fileset dir="${plugin.path}/web">
                <include name="*"/>
                <include name="**/*.*"/>
                <exclude name="**/*.xml"/>
                <exclude name="**/*.jsp"/>
            </fileset>
        </copy>
        <!-- jsp servlet的web複製到插件目錄下 -->
        <copy file="${plugin.web.xml}" todir="${webapp.path}/${plugin.name}/web/WEB-INF"/>
        <copy todir="${webapp.path}/${plugin.name}/web">
            <fileset dir="${plugin.path}/web" includes="**/*.xml"/>
        </copy>
        <!-- 將國際化相關資源文件複製到插件目錄下
        <copy file="${webapp.path}/bin/i18n" todir="${webapp.path}/${plugin.name}"/>
        -->
        <!-- 產生可部署插件包 -->
        <jar jarfile="${webapp.path}/${plugin.name}.jar">
            <fileset dir="${webapp.path}/${plugin.name}" includes="**/**"/>
        </jar>
    </target>

    <!-- 生成沒有Web資源的可部署插件包 -->
    <target name="java-plug-jar">
        <!-- 插件插件包相關lib、 web目錄 -->
        <mkdir dir="${webapp.path}/${plugin.name}/lib"/>
 
        <!-- 複製java servlet的相關jar包到插件包的lib目錄下 -->
        <copy file="${java.jar}" todir="${webapp.path}/${plugin.name}/lib"/>
 
        <!-- 將相關的圖片、幫助文檔、修改日誌等文件複製到插件目錄下 -->
        <copy todir="${webapp.path}/${plugin.name}">
            <fileset dir="${plugin.path}" includes="*.*"/>
        </copy>

        <!-- 產生可部署插件包 -->
        <jar jarfile="${webapp.path}/${plugin.name}.jar">
            <fileset dir="${webapp.path}/${plugin.name}" includes="**/**"/>
        </jar>
    </target>

    <!-- 清理生成的文件 -->
    <target name="clean">
        <delete file="${webapp.path}/${plugin.name}.jar"/>
        <delete dir="${webapp.path}/${plugin.name}"/>
        <delete dir="${webapp.path}/jsp-dist"/>
        <delete dir="${webapp.path}/java-dist"/>
    </target>

    <target name="all" depends="clean,jspc,compile"/>
 
    <target name="openfire-plugin" depends="jspc,java-jar"/>
 
    <target name="openfire-plugins" depends="all,java-jar,plug-jar"/>

    <target name="openfire-plugin-java" depends="clean,java-jar,java-plug-jar"/>
</project>

build.properties文件內容

#tomcat home
tomcat.home=D:/tomcat-5.0.28/tomcat-5.0.28
webapp.path=D:/Workspace/OpenfirePlugin
 
plugin.name=sample
plugin.path=D\:/Workspace/OpenfirePlugin/src/plugins/sample

注意:這裏我沒有編寫編譯java代碼到class的步驟,我是直接使用MyEclipse自動編譯的bin/class的。若是你沒有用MyEclipse或Eclipse,那麼你須要將src中的Java代碼編譯class。

這裏須要配置tomcat的目錄,我這裏是5.0.28的版本。我用tomcat6有些問題,這裏主要是用tomcat中的lib庫,幫助 咱們編譯jsp。還須要配置你當前工程的所在目錄,也就是工程在Eclipse中的目錄位置。最後你須要配置插件的名稱和插件在工程中的所在目錄,這個是 在打包的時候,須要將其餘的html、image、xml等資源導入的jar內。

由於這裏的插件是不帶jsp的,因此咱們執行clean、java-jar、java-plugin-jar。也就是openfire-plugin-java這個命令便可。執行命令後,你能夠看到工做空間的工程目錄下多了目錄和文件。見圖:

clip_image018

java-dist目錄裏面的就是src/plugin/sample目錄中的java代碼打成的jar包。具體你能夠用zip打開看看。

sample就是咱們的插件目錄,和sample.jar中的內容是如出一轍的。

sample.jar就是將sample目錄打成jar包。

五、 發佈插件

發佈插件有2種方式

第一種:直接將插件放置在openfire服務器的plugins目錄下。個人是在:C:\Program Files\openfire\plugins目錄。重起openfire後你能夠看到控制檯輸出咱們插件中輸出的內容,而且在C:\Program Files\openfire\plugins目錄中能夠看到該目錄下多了一個sample的目錄(openfire能夠自動解壓jar包)。

clip_image020

當你在關閉服務器的瞬間,也會打印銷燬插件的消息。

第二種:在openfire啓動的狀況下,訪問http://localhost:9090/plugin-admin.jsp頁面,點擊頁面下方的upload plugin完成插件上傳操做。

插件按照成功後,訪問http://localhost:9090/plugin-admin.jsp頁面你就能夠看到安裝好的插件了。

clip_image022

至此,不帶jsp頁面的簡單插件就編寫部署成功了。

3、開發帶jsp、PluginServlet的插件

有些插件是單純的繼承Plugin或Handler什麼的,但有些是須要jsp頁面和Servlet的。下面咱們就來開發帶jsp和servlet的插件。

在以前的目錄下添加文件,目錄結構以下:

clip_image024

一、 首先創建一個SampleServlet的文件,內容以下

package com.hoo.server.plugin;
 
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * <b>function:</b> sample servlet
 * @author hoojo
 * @createDate 2013-3-4 下午04:15:20
 * @file SampleServlet.java
 * @package com.hoo.server.plugin
 * @project OpenfirePlugin
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
public class SampleServlet extends HttpServlet {

    private static final long serialVersionUID = -5404916983906926869L;
 
    @Override
    public void init() throws ServletException {
        super.init();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        super.doGet(request, response);

        response.setContentType("text/plain");
        PrintWriter out = response.getWriter();
        System.out.println("請求SampleServlet GET Method");
        out.print("請求SampleServlet GET Method");
        out.flush();
    }
 
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        super.doPost(request, response);

        response.setContentType("text/plain");
        PrintWriter out = response.getWriter();
        System.out.println("請求SampleServlet GET Method");
        out.print("請求SampleServlet POST Method");
        out.flush();
    }
 
    @Override
    public void destroy() {
        super.destroy();
    }
}

二、 在當前插件根目錄添加web目錄,在目錄下創建WEB-INF目錄,添加web-custom.xml文件(文件名應該是固定的)。在裏面配置咱們的servlet。

<?xml version="1.0" encoding="ISO-8859-1"?>
<!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-class>com.hoo.server.plugin.SampleServlet</servlet-class>
        <servlet-name>SampleServlet</servlet-name>
    </servlet>

    <servlet-mapping>
        <servlet-name>SampleServlet</servlet-name>
        <url-pattern>/servlet</url-pattern>
    </servlet-mapping>
</web-app>

當插件發佈後你能夠經過用:http://127.0.0.1:9090/plugins/sample/servlet 就能夠訪問到這個servlet了。但我發現咱們只需用http://127.0.0.1:9090/plugins/sample也是能夠訪問到的。好像openfire會自動找到咱們插件目錄下的servlet配置。

注意:這裏的http://127.0.0.1:9090/plugins/是 固定的,至少plugins是固定的。全部的插件都在plugins目錄下訪問的。若是你想知道爲何,你能夠看看openfire源碼下的 web.xml,具體目錄路徑在/openfire/src/web/WEB-INF/web.xml。裏面有一個PluginServlet是過來 plugin的配置的。

三、 在web目錄下添加jsp文件,文件名是插件名稱-自定義名稱.jsp(建議規範命名)

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>hello world: 你好openfire</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="pageID" content="sample-service"/>
  </head>

  <body>
    <h3>hello world jsp!! <a href="/plugins/sample/servlet">SampleServlet</a></h3>
    <div class="jive-contentBoxHeader">jive-contentBoxHeader</div>
    <div class="jive-contentBox">jive-contentBox</div>

    <div class="jive-table">
        <table cellpadding="0" cellspacing="0" border="0" width="100%">
            <thead>
                <tr>
                    <th>&nbsp;sss</th>
                    <th nowrap>a</th>
                    <th nowrap>b</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td align="center">asdf</td>
                    <td align="center">asdf</td>
                    <td align="center">asdf</td>
                </tr>
                <tr class="jive-even">
                       <td align="center">asdf</td>
                    <td align="center">asdf</td>
                    <td align="center">asdf</td>
                </tr>
                <tr class="jive-odd">
                       <td align="center">asdf</td>
                    <td align="center">asdf</td>
                    <td align="center">asdf</td>
                </tr>
             </tbody>
        </table>
    </div>
  </body>
</html>

其中最重要的一點就是:<meta name="pageID" content="sample-service"/>這個pageID。這裏的是固定的,後面的content對應咱們plugin.xml的內 容(等下看看plguin.xml的配置)。而後能夠適當的看下里面table的 屬性和樣式,由於不少時候會在jsp中顯示內容,且用table佈局的。

四、 改下以前的plugin.xml的配置,配置組件在openfire 管理員控制檯的哪一個地方顯示,以及顯示的頁面。

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
    <!-- Main plugin class  這裏是最重要滴,就是你的插件的全路徑-->
    <class>com.hoo.server.plugin.SamplePlugin</class>
 
    <!-- Plugin meta-data -->
    <name>SimplePlugin</name>
    <description>This is the my sample plugin.</description>
    <author>hoojo</author>
 
    <version>1.0</version>
    <date>28/02/2013</date>
    <url>http://localhost:9090/openfire/plugins.jsp</url>
    <minServerVersion>3.4.1</minServerVersion>
    <licenseType>gpl</licenseType>
 
    <adminconsole>
        <tab id="tab-server">
            <sidebar id="sidebar-server-settings">
                <item id="sample-service" name="Sample Service" url="sample-service.jsp"
                     description="Click is trigger sample plugin" />
            </sidebar>
        </tab>
    </adminconsole>
</plugin>

這裏主要就是adminconsole這裏面的配置。首先tab-server應該是在管理員控制檯頁面的服務器菜單中顯示;sidebar中的的 id配置固定這樣寫便可;item中的id(sample-service)對應的就是上面的sample-service.jsp的<meta name="pageID" content="sample-service"/>的content內容;item的url對應的是咱們寫的jsp頁面;name是插件的菜單 名稱。也就是說在管理員控制檯頁面中的服務器菜單下增長一個sample service的菜單,打開的頁面是sample-service.jsp頁面。

五、 運行ant腳本,打包發佈插件。在上一章節有完整ant腳本的,運行build.xml中的這個openfire-plugins命令便可打包。而後將打好包的sample.jar發佈到openfire的plugins目錄下便可。

打包後的jar插件目錄結構以下:

clip_image026

啓動openfire後,在openfire管理員控制檯頁面的服務器->服務器設置中就能夠看到Sample Service插件了。

clip_image028

點擊Sample Servlet就能夠看到openfire控制檯打印請求的文字信息。

 

ok,至此開發本身的openfire插件基本上就是這樣的,網上這方面的資料不多,我也是官方的插件源碼和網上提供的小部分資料才整出來的。原本在去年(2012)就應該發佈這篇文章的,不料那個時候天天都很忙。加班、上線什麼的,因此這篇文章纔在今日發表。

下篇文章就是開發openfire的聊天記錄插件,到時歡迎你們閱讀。請隨時關注個人動態哦!

若是你以爲本文不錯,請點一下瀏覽器右下角的「頂」。謝謝!^_^

相關文章
相關標籤/搜索