這篇是簡(jiǎn)單插件開(kāi)發(fā),下篇聊天記錄插件。
開(kāi)發(fā)環(huán)境:
System:Windows
WebBrowser:IE6+、Firefox3+
JavaEE Server:tomcat5.0.2.8、tomcat6
IDE:eclipse、MyEclipse 8
開(kāi)發(fā)依賴(lài)庫:
Jdk1.6、jasper-compiler.jar、jasper-runtime.jar、openfire.jar、servlet.jar
Email:hoojo_@126.com
在開(kāi)始之前,如果你不知道怎么使用openfire,安裝openfire服務(wù)器,建議你看這篇文章:
http://www.cnblogs.com/hoojo/archive/2012/05/17/2506769.html
http://www.cnblogs.com/hoojo/archive/2012/05/13/2498151.html
1、 下載相關(guān)jar包和openfire源碼
Openfire源碼下載:http://www.igniterealtime.org/downloads/download-landing.jsp?file=openfire/openfire_src_3_8_0.tar.gz
其他的jar包你可以去tomcat中的lib目錄找到或者其他的地方也有(在下面的步驟會(huì )提到),這里就贅述了。
2、 新建一個(gè)自己的java project工程,添加的jar包如下:
將jasper-compiler.jar、jasper-runtime.jar、servlet.jar添加到新建的工程中。如果沒(méi)有jar先不要急,看下面的步驟:
下載后的openfire源碼目錄是這樣的
如果你有ant工具可以用dos命令行的方式,直接運行build目錄中的ant腳本,運行腳本后,你會(huì )發(fā)現有一個(gè)target的目錄。該目錄如下:
在lib目錄中可以找到我們需要的jar文件了,將openfire.jar也添加到你的工程中。
如果你沒(méi)有安裝ant你可以用MyEclipse,將openfire源碼中的build、documentation、resources目錄復制到一個(gè)Java Project中,然后在MyEclipse中運行src中的build.xml ant腳本就會(huì )出現和上面一樣的文件目錄。
建議將你的MyEclipse中的openfire源碼工程目錄設置成這樣的
其中,src/plugins/tree是我自己寫(xiě)的插件,現在暫時(shí)可以無(wú)視。而target就是我們需要的,里面存放了openfire的配置和需要的jar包。Work是工作目錄,是一個(gè)完整的openfire服務(wù)器。如果你還沒(méi)有下載openfire服務(wù)器的話(huà),可以用這個(gè)服務(wù)器。
3、 了解openfire源碼中的插件
我們找一個(gè)插件目錄看看,主要看看里面的結構,目錄結構很重要。因為我們將寫(xiě)好的插件打成jar包后,打包的jar的目錄有一定規范結構,不能隨便建立其他目錄。
這是一個(gè)userservice的插件,在src/java中是我們的插件源代碼;web目錄中則是前端的頁(yè)面,其中web-custom.xml是配置當前插件UserServiceServlet配置;changelog.html是修改日志;logo_small.gif是插件圖標;plugin.xml是我們配置插件的文件,這個(gè)很重要(在這里先提示下);
工程現在的目錄機構如下
1、 建立自己的插件類(lèi),SamplePlugin.java,里面簡(jiǎn)單的寫(xiě)點(diǎn)內容。
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;@Overridepublic void initializePlugin(PluginManager manager, File pluginDirectory) {server = XMPPServer.getInstance();System.out.println("初始化…… 安裝插件!");System.out.println(server.getServerInfo());}@Overridepublic void destroyPlugin() {System.out.println("服務(wù)器停止,銷(xiāo)毀插件!");}}比較簡(jiǎn)單,如果你將插件安裝在openfire服務(wù)器上的時(shí)候,啟動(dòng)服務(wù)器一個(gè)可以看到初始化的內容,關(guān)閉服務(wù)器可以看到銷(xiāo)毀的內容。
2、 配置插件
<?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的配置,那個(gè)配置是最為重要的,配置的是插件的全路徑;name是插件的名稱(chēng),安裝后的插件名稱(chēng);author是插件作者;lincenseType是協(xié)議;adminconsole是配置插件關(guān)聯(lián)的頁(yè)面的;稍后再講!
3、 可部署的插件包jar的目錄結構
這個(gè)很重要,目錄結構將決定你插件 發(fā)布的成敗。
在編寫(xiě)命令之前,我們可以看看openfire服務(wù)器中已經(jīng)安裝的插件的jar包的目錄結構,到時(shí)候我們也要打包成那樣的結構才行的。必須打包成這樣的目錄結構,否則哼哼……后果很?chē)乐氐?!聲明?
在我機器中的openfire服務(wù)器中,插件目錄在C:\Program Files\openfire\plugins,里面有一個(gè)search.jar插件。提示:當你將一個(gè)可以安裝的jar安裝在openfire后,會(huì )被openfire解壓成目錄結構。就向JavaEE中的war包發(fā)布的應用服務(wù)器中的效果一樣的。
打成可部署的插件jar包(相當于發(fā)布的應用服務(wù)器的目錄結構)的search.jar目錄結構如下:
首先看看文件命名,search.jar就是我們打包的插件的名稱(chēng),而國際化的配置文件就是以插件名稱(chēng)開(kāi)頭_118n.properties或插件名稱(chēng)開(kāi)頭_118n_language.properties;而lib目錄中的是插件的src目錄的class打成的jar包;帶有*-jspc.jar是web目錄下的jsp編譯成servlet后的class打成的包文件,都是以插件名稱(chēng)開(kāi)頭;WEB-INF/web.xml配置的是*-jspc.jar中的class文件;web/images是圖片文件,需要用到的圖片都放置在這個(gè)目錄即可;plugin.xml文件名固定的,里面是配置插件的xml內容。
其中,118n國際化文件,它主要是我們在插件中的jsp和Java程序中的國際化配置。Web目錄存放jsp、圖片、web.xml內容;lib目錄是存放插件的src目錄的java代碼編譯后打包的jar,以及jsp編譯成servlet的class打包后的jar;其他的文件都是根目錄的;
對照上面插件包的jar,我們看看實(shí)際開(kāi)發(fā)中的目錄結構:
稍提醒下,如果你的插件中包含servlet,那你需要將它配置在web目錄下的WEB-INF/web-custom.xml目錄中;這個(gè)在以后會(huì )經(jīng)常用到的,比如你提供一個(gè)接口給外部程序調用的情況下。目錄結構參考:
UserServiceServlet配置在web-custom.xml目錄中。
4、 編寫(xiě)ant命令,打可部署jar包。如果你不懂a(chǎn)nt命令也沒(méi)關(guān)系,你總知道java的基本常用的dos命令。只不過(guò)ant就是將dos轉換成一個(gè)可重復多次調用的命令行。
在工程的根目錄中新建一個(gè)build目錄,新建
build.xml
<project name="Webapp Precompilation" default="openfire-plugins" basedir="."><property file="build.properties" /><!-- java servlet相關(guān)文件編譯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包名稱(chēng) --><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 并生成相關(guān)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文件中 --><jasper2validateXml="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"><!-- 插件插件包相關(guān)lib、 web目錄 --><mkdir dir="${webapp.path}/${plugin.name}/lib"/><mkdir dir="${webapp.path}/${plugin.name}/web/WEB-INF"/><!-- 復制jsp servlet的jar和java servlet的相關(guān)jar包到插件包的lib目錄下 --><copy file="${java.jar}" todir="${webapp.path}/${plugin.name}/lib"/><copy file="${jsp.jar}" todir="${webapp.path}/${plugin.name}/lib"/><!-- 將相關(guān)的圖片、幫助文檔、修改日志等文件復制到插件目錄下 --><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><!-- 將國際化相關(guān)資源文件復制到插件目錄下<copy file="${webapp.path}/bin/i18n" todir="${webapp.path}/${plugin.name}"/>--><!-- 產(chǎn)生可部署插件包 --><jar jarfile="${webapp.path}/${plugin.name}.jar"><fileset dir="${webapp.path}/${plugin.name}" includes="**/**"/></jar></target><!-- 生成沒(méi)有Web資源的可部署插件包 --><target name="java-plug-jar"><!-- 插件插件包相關(guān)lib、 web目錄 --><mkdir dir="${webapp.path}/${plugin.name}/lib"/><!-- 復制java servlet的相關(guān)jar包到插件包的lib目錄下 --><copy file="${java.jar}" todir="${webapp.path}/${plugin.name}/lib"/><!-- 將相關(guān)的圖片、幫助文檔、修改日志等文件復制到插件目錄下 --><copy todir="${webapp.path}/${plugin.name}"><fileset dir="${plugin.path}" includes="*.*"/></copy><!-- 產(chǎn)生可部署插件包 --><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 hometomcat.home=D:/tomcat-5.0.28/tomcat-5.0.28webapp.path=D:/Workspace/OpenfirePluginplugin.name=sampleplugin.path=D\:/Workspace/OpenfirePlugin/src/plugins/sample注意:這里我沒(méi)有編寫(xiě)編譯java代碼到class的步驟,我是直接使用MyEclipse自動(dòng)編譯的bin/class的。如果你沒(méi)有用MyEclipse或Eclipse,那么你需要將src中的Java代碼編譯class。
這里需要配置tomcat的目錄,我這里是5.0.28的版本。我用tomcat6有些問(wèn)題,這里主要是用tomcat中的lib庫,幫助我們編譯jsp。還需要配置你當前工程的所在目錄,也就是工程在Eclipse中的目錄位置。最后你需要配置插件的名稱(chēng)和插件在工程中的所在目錄,這個(gè)是在打包的時(shí)候,需要將其他的html、image、xml等資源導入的jar內。
因為這里的插件是不帶jsp的,所以我們執行clean、java-jar、java-plugin-jar。也就是openfire-plugin-java這個(gè)命令即可。執行命令后,你可以看到工作空間的工程目錄下多了目錄和文件。見(jiàn)圖:
java-dist目錄里面的就是src/plugin/sample目錄中的java代碼打成的jar包。具體你可以用zip打開(kāi)看看。
sample就是我們的插件目錄,和sample.jar中的內容是一模一樣的。
sample.jar就是將sample目錄打成jar包。
5、 發(fā)布插件
發(fā)布插件有2種方式
第一種:直接將插件放置在openfire服務(wù)器的plugins目錄下。我的是在:C:\Program Files\openfire\plugins目錄。重起openfire后你可以看到控制臺輸出我們插件中輸出的內容,并且在C:\Program Files\openfire\plugins目錄中可以看到該目錄下多了一個(gè)sample的目錄(openfire可以自動(dòng)解壓jar包)。
當你在關(guān)閉服務(wù)器的瞬間,也會(huì )打印銷(xiāo)毀插件的消息。
第二種:在openfire啟動(dòng)的情況下,訪(fǎng)問(wèn)http://localhost:9090/plugin-admin.jsp頁(yè)面,點(diǎn)擊頁(yè)面下方的upload plugin完成插件上傳操作。
插件按照成功后,訪(fǎng)問(wèn)http://localhost:9090/plugin-admin.jsp頁(yè)面你就可以看到安裝好的插件了。
至此,不帶jsp頁(yè)面的簡(jiǎn)單插件就編寫(xiě)部署成功了。
有些插件是單純的繼承Plugin或Handler什么的,但有些是需要jsp頁(yè)面和Servlet的。下面我們就來(lái)開(kāi)發(fā)帶jsp和servlet的插件。
在之前的目錄下添加文件,目錄結構如下:
1、 首先建立一個(gè)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;@Overridepublic void init() throws ServletException {super.init();}@Overrideprotected 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();}@Overrideprotected 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();}@Overridepublic void destroy() {super.destroy();}}
2、 在當前插件根目錄添加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>
當插件發(fā)布后你可以通過(guò)用:http://127.0.0.1:9090/plugins/sample/servlet 就可以訪(fǎng)問(wèn)到這個(gè)servlet了。但我發(fā)現我們只需用http://127.0.0.1:9090/plugins/sample也是可以訪(fǎng)問(wèn)到的。好像openfire會(huì )自動(dòng)找到我們插件目錄下的servlet配置。
注意:這里的http://127.0.0.1:9090/plugins/是固定的,至少plugins是固定的。所有的插件都在plugins目錄下訪(fǎng)問(wèn)的。如果你想知道為什么,你可以看看openfire源碼下的web.xml,具體目錄路徑在/openfire/src/web/WEB-INF/web.xml。里面有一個(gè)PluginServlet是過(guò)來(lái)plugin的配置的。
3、 在web目錄下添加jsp文件,文件名是插件名稱(chēng)-自定義名稱(chēng).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> 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>其中最重要的一點(diǎn)就是:<meta name="pageID" content="sample-service"/>這個(gè)pageID。這里的是固定的,后面的content對應我們plugin.xml的內容(等下看看plguin.xml的配置)。然后可以適當的看下里面table的 屬性和樣式,因為很多時(shí)候會(huì )在jsp中顯示內容,且用table布局的。
4、 改下之前的plugin.xml的配置,配置組件在openfire 管理員控制臺的哪個(gè)地方顯示,以及顯示的頁(yè)面。
<?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應該是在管理員控制臺頁(yè)面的服務(wù)器菜單中顯示;sidebar中的的id配置固定這樣寫(xiě)即可;item中的id(sample-service)對應的就是上面的sample-service.jsp的<meta name="pageID" content="sample-service"/>的content內容;item的url對應的是我們寫(xiě)的jsp頁(yè)面;name是插件的菜單名稱(chēng)。也就是說(shuō)在管理員控制臺頁(yè)面中的服務(wù)器菜單下增加一個(gè)sample service的菜單,打開(kāi)的頁(yè)面是sample-service.jsp頁(yè)面。
5、 運行ant腳本,打包發(fā)布插件。在上一章節有完整ant腳本的,運行build.xml中的這個(gè)openfire-plugins命令即可打包。然后將打好包的sample.jar發(fā)布到openfire的plugins目錄下即可。
打包后的jar插件目錄結構如下:
啟動(dòng)openfire后,在openfire管理員控制臺頁(yè)面的服務(wù)器->服務(wù)器設置中就可以看到Sample Service插件了。
點(diǎn)擊Sample Servlet就可以看到openfire控制臺打印請求的文字信息。
ok,至此開(kāi)發(fā)自己的openfire插件基本上就是這樣的,網(wǎng)上這方面的資料很少,我也是官方的插件源碼和網(wǎng)上提供的小部分資料才整出來(lái)的。本來(lái)在去年(2012)就應該發(fā)布這篇文章的,不料那個(gè)時(shí)候每天都很忙。加班、上線(xiàn)什么的,所以這篇文章才在今日發(fā)表。
下篇文章就是開(kāi)發(fā)openfire的聊天記錄插件,到時(shí)歡迎大家閱讀。請隨時(shí)關(guān)注我的動(dòng)態(tài)哦!
如果你覺(jué)得本文不錯,請點(diǎn)一下瀏覽器右下角的“頂”。謝謝!^_^
聯(lián)系客服