openfire :openfire 不同类型插件的开发示例

时间:2021-11-21 18:29:59

新建一个自己的Javaproject工程,添加的jar包如下:

将jasper-compiler.jar、jasper-runtime.jar、servlet.jar添加到新建的工程中。如果没有jar先不要急,看下面的步骤:

下载后的openfire源码目录是这样的

openfire :openfire 不同类型插件的开发示例

如果你有ant工具可以用dos命令行的方式,直接运行build目录中的ant脚本,运行脚本后,你会发现有一个target的目录。该目录如下:

openfire :openfire 不同类型插件的开发示例

在lib目录中可以找到我们需要的jar文件了,将openfire.jar也添加到你的工程中。

如果你没有安装ant你可以用MyEclipse,将openfire源码中的build、documentation、resources目录复制到一个javaProject中,然后在MyEclipse中运行src中的build.xml ant脚本就会出现和上面一样的文件目录。

建议将你的MyEclipse中的openfire源码工程目录设置成这样的

openfire :openfire 不同类型插件的开发示例

其中,src/plugins/tree是我自己写的插件,现在暂时可以无视。而target就是我们需要的,里面存放了openfire的配置和需要的jar包。Work是工作目录,是一个完整的openfire服务器。如果你还没有下载openfire服务器的话,可以用这个服务器。

了解openfire源码中的插件

我们找一个插件目录看看,主要看看里面的结构,目录结构很重要。因为我们将写好的插件打成jar包后,打包的jar的目录有一定规范结构,不能随便建立其他目录。

openfire :openfire 不同类型插件的开发示例

这是一个userservice的插件,在src/Java中是我们的插件源代码web目录中则是前端的页面,其中web-custom.xml是配置当前插件的servlet服务器UserServiceServlet配置;changelog.html是修改日志;logo_small.gif是插件图标;plugin.xml是我们配置插件的文件,这个很重要(在这里先提示下);

二、开发简单插件

工程现在的目录机构如下

openfire :openfire 不同类型插件的开发示例

1、 建立自己的插件类,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服务器上的时候,启动服务器一个可以看到初始化的内容,关闭服务器可以看到销毁的内容。

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的配置,那个配置是最为重要的,配置的是插件的全路径;name是插件的名称,安装后的插件名称;author是插件作者;lincenseType是协议;adminconsole是配置插件关联的页面的;稍后再讲!

3、 可部署的插件包jar的目录结构

这个很重要,目录结构将决定你插件 发布的成败。

在编写命令之前,我们可以看看openfire服务器中已经安装的插件的jar包的目录结构,到时候我们也要打包成那样的结构才行的。必须打包成这样的目录结构。

在我机器中的openfire服务器中,插件目录在C:\Program Files\openfire\plugins,里面有一个search.jar插件。提示:当你将一个可以安装的jar安装在openfire后,会被openfire解压成目录结构。就向JavaEE中的war包发布的应用服务器中的效果一样的。

打成可部署的插件jar包(相当于发布的应用服务器的目录结构)的search.jar目录结构如下:

openfire :openfire 不同类型插件的开发示例

首先看看文件命名,

(1)search.jar:打包的插件的名称

(2)i18n: 118n国际化文件,它主要是我们在插件中的jsp和Java程序中的国际化配置。国际化的配置文件是以插件名称开头_118n.properties或_118n_language.properties;

(3)lib:  lib目录是存放插件的src目录的java代码编译后打包的jar,以及jsp编译成servlet的class打包后的jar;带有*-jspc.jar是web目录下的jsp编译成servlet后的class打成的包文件,都是以插件名称开头;WEB-INF/web.xml配置的是*-jspc.jar中的class文件;

(4)web:web目录存放jsp、图片、web.xml内容

(5)plugin.xml文件名固定的,里面是配置插件的xml内容。

其他的文件都是根目录的;

对照上面插件包的jar,我们看看实际开发中的目录结构

openfire :openfire 不同类型插件的开发示例

稍提醒下,如果你的插件中包含servlet,那你需要将它配置在web目录下的WEB-INF/web-custom.xml目录中;这个在以后会经常用到的,比如你提供一个接口给外部程序调用的情况下。目录结构参考:

openfire :openfire 不同类型插件的开发示例

UserServiceServlet配置在web-custom.xml目录中

4、 编写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这个命令即可。执行命令后,你可以看到工作空间的工程目录下多了目录和文件。见图:

openfire :openfire 不同类型插件的开发示例

java-dist目录里面的就是src/plugin/sample目录中的java代码打成的jar包。具体你可以用zip打开看看。

sample就是我们的插件目录,和sample.jar中的内容是一模一样的。

sample.jar就是将sample目录打成jar包。

5、 发布插件

发布插件有2种方式

第一种:直接将插件放置在openfire服务器的plugins目录下。我的是在:C:\Program Files\openfire\plugins目录。重起openfire后你可以看到控制台输出我们插件中输出的内容,并且在C:\Program Files\openfire\plugins目录中可以看到该目录下多了一个sample的目录(openfire可以自动解压jar包)。

openfire :openfire 不同类型插件的开发示例

当你在关闭服务器的瞬间,也会打印销毁插件的消息。

第二种:在openfire启动的情况下,访问http://localhost:9090/plugin-admin.jsp页面,点击页面下方的upload plugin完成插件上传操作。

插件按照成功后,访问http://localhost:9090/plugin-admin.jsp页面你就可以看到安装好的插件了。

openfire :openfire 不同类型插件的开发示例

至此,不带jsp页面的简单插件就编写部署成功了。

三、开发带jsp、PluginServlet的插件

有些插件是单纯的继承Plugin或Handler什么的,但有些是需要jsp页面和Servlet的。下面我们就来开发带jsp和servlet的插件。

在之前的目录下添加文件,目录结构如下:

openfire :openfire 不同类型插件的开发示例

1、 首先建立一个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();
}

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>

当插件发布后你可以通过用: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的配置的。

3、 在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布局的。

4、 改下之前的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页面。

5、 运行ant脚本,打包发布插件。在上一章节有完整ant脚本的,运行build.xml中的这个openfire-plugins命令即可打包。然后将打好包的sample.jar发布到openfire的plugins目录下即可。

打包后的jar插件目录结构如下:

openfire :openfire 不同类型插件的开发示例

启动openfire后,在openfire管理员控制台页面的服务器->服务器设置中就可以看到Sample Service插件了。

openfire :openfire 不同类型插件的开发示例

点击Sample Servlet就可以看到openfire控制台打印请求的文字信息。

5.openfire(2)协议插件开发

昨天说了怎么配置openfire的开发环境。今天写一点openfire的插件开发。我这里做了一个例子主要是针对于XMPP的通信。后边会说一点smack和openfire通信的实现。

在openfire的源码里有很多插件。我这里实际就是拷贝了其中的一个插件。重名了一下名字。目录结构如下:

openfire :openfire 不同类型插件的开发示例

貌似图片传不上来了。如果看不到图,就看看源码中的其他插件的例子。跟其他插件的目录结构是一样一样的。

在这些文件里最重要的就是plugin.xml文件。因为有这个文件openfire才认识这个插件。在这个文件里会配置插件的入口类。我这里简单写了一个plugin.xml.示例如下。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <plugin>
  3. <class>org.yangzc.testplugin.TestPlugin</class>
  4. <name>test Plugin</name>
  5. <description>test Plugin descript</description>
  6. <author>yangzc</author>
  7. <version>1.0.0</version>
  8. <date>20/6/2011</date>
  9. <minServerVersion>3.7.0</minServerVersion>
  10. <databaseKey>testPlugin</databaseKey>
  11. <databaseVersion>0</databaseVersion>
  12. <adminconsole>
  13. </adminconsole>
  14. </plugin>

class部分就是插件的实现类。

具体TestPlugin的实现。这里也有一个例子:

  1. package org.yangzc.testplugin;
  2. import java.io.File;
  3. import org.dom4j.Element;
  4. import org.jivesoftware.openfire.IQHandlerInfo;
  5. import org.jivesoftware.openfire.XMPPServer;
  6. import org.jivesoftware.openfire.auth.UnauthorizedException;
  7. import org.jivesoftware.openfire.container.Plugin;
  8. import org.jivesoftware.openfire.container.PluginManager;
  9. import org.jivesoftware.openfire.handler.IQHandler;
  10. import org.xmpp.packet.IQ;
  11. import org.xmpp.packet.PacketError;
  12. public class TestPlugin implements Plugin{
  13. @Override
  14. public void destroyPlugin() {
  15. }
  16. @Override
  17. public void initializePlugin(PluginManager manager, File pluginDirectory) {
  18. XMPPServer service = XMPPServer.getInstance();
  19. service.getIQRouter().addHandler(new MyIQHandler());
  20. }
  21. class MyIQHandler extends IQHandler{
  22. public static final String moduleName = "testPlugin";
  23. private IQHandlerInfo info;
  24. public MyIQHandler(){
  25. super(moduleName);
  26. info = new IQHandlerInfo("group", "com:im:group");//设置监听的命名空间
  27. }
  28. @Override
  29. public IQHandlerInfo getInfo() {
  30. return info;//取得指定监听命名空间的IQHandeler
  31. }
  32. @Override
  33. public IQ handleIQ(IQ packet) throws UnauthorizedException {
  34. IQ reply = IQ.createResultIQ(packet);
  35. Element groups = packet.getChildElement();//取得客户端发送过来的xml
  36. if (!IQ.Type.get.equals(packet.getType())){
  37. System.out.println("非法的请求类型");
  38. reply.setChildElement(groups.createCopy());
  39. reply.setError(PacketError.Condition.bad_request);
  40. return reply;
  41. }
  42. //String userName = StringUtils.substringBefore(packet.getFrom().toString(),"@");
  43. //GroupManager.getInstance().initElement(groups,userName);
  44. //reply.setChildElement(groups.createCopy());//2
  45. //System.out.println("返回的最终XML" reply.toXML());
  46. return reply;
  47. }
  48. }
  49. }

在这个实现类中需要实现接口plugin。这个接口包含两个方法。一个是初始化插件,一个是销毁插件动作。

这个例子里在初始化插件的时候通过service添加了一个监听。这里我理解为监听。这个监听可以监听指定命名空间的消息。

openfire :openfire 不同类型插件的开发示例的更多相关文章

  1. NPAPI火狐插件VS2013开发示例

    NPAPI火狐插件VS2013开发示例 下面是我根据网上开发示例自己做的一个demo,并提供代码下载. 开发环境 Windows 8.1 x64 Visual studio 2013 准备工作 首先需 ...

  2. IDEA插件(Android Studio插件)开发示例代码及bug解决

    IDEA插件(Android Studio插件)开发示例代码及bug解决 代码在actionPerformed方法中,有个AnActionEvent e 插件开发就是要求我们复写上述的这个方法即可,在 ...

  3. WPF常用控件样式&lpar; 内含一简单插件式开发示例&rpar;

    最近离职,离职前面的一份外派然后又外包的工作,总觉得不妥,之后外派的办个入职手续都一再失约,干脆推了.恰逢清明时节,暴雨纷纷,于是打算先休息休息调整下状态,工作的事情还是谨慎点的好,免得影响心情.话说 ...

  4. &lbrack;Liferay6&period;2&rsqb;Liferay入门级portlet开发示例

    什么是Portlet 来自百度百科(http://baike.baidu.com/view/58961.htm)的定义如下: portlet是基于java的web组件,处理request并产生动态内容 ...

  5. jQuery插件的开发

    jQuery插件的开发包括两种: 一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法.jQuery的全局函数就是属于jQuery命名空间的函数,另一种是对象级 ...

  6. jQuery插件的开发(一)

    jQuery插件的开发包括两种: 一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法.jQuery的全局函数就是属于jQuery命名空间的函数,另一种是对象级 ...

  7. 详解Android插件化开发-资源访问

    动态加载技术(也叫插件化技术),当项目越来越庞大的时候,我们通过插件化开发不仅可以减轻应用的内存和CPU占用,还可以实现热插拔,即在不发布新版本的情况下更新某些模块.     通常我们把安卓资源文件制 ...

  8. MEF 插件式开发 - 小试牛刀

    原文:MEF 插件式开发 - 小试牛刀 目录 MEF 简介 实践出真知 面向接口编程 控制反转(IOC) 构建入门级 MEF 相关参考 MEF 简介 Managed Extensibility Fra ...

  9. MEF 插件式开发 - WPF 初体验

    原文:MEF 插件式开发 - WPF 初体验 目录 MEF 在 WPF 中的简单应用 加载插件 获取元数据 依赖注入 总结 MEF 在 WPF 中的简单应用 MEF 的开发模式主要适用于插件化的业务场 ...

随机推荐

  1. Tomcat去除项目名称和端口号,直接使用ip地址访问项目的方法

    网站开发过程中,一般的工程访问路径是 http://112.74.51.37/projectName如何设置成http://112.74.51.37/ 解决方法: 首先,进入tomcat的安装目录下的 ...

  2. mac OS&lpar;OS X&rpar;的OI编译环境配置指南

    编译环境:gdb+Atom 如何安装gdb: http://logic0.blog.163.com/blog/static/1889281462014183271283/   Atom下载地址: ht ...

  3. c&plus;&plus; template怎么使用及注意事项

    c++ 中的template和c#的什么有点相似? 先看下定义方式: template <typename|class T> T myFunction(T param1,T param2. ...

  4. &period;Net 自己写个简单的 半 ORM (练手)

    ORM 大家都知道, .Net 是EF  还有一些其他的ORM  从JAVA 中移植过来的 有 , 大神自己写的也有 不管ORM 提供什么附加的 乱七八糟的功能 但是 最主要的 还是 关系映射 的事情 ...

  5. 转 互联网推送服务原理:长连接&plus;心跳机制&lpar;MQTT协议&rpar;

    http://blog.csdn.net/zhangzeyuaaa/article/details/39028369 目录(?)[-] 无线移动网络的特点 android系统的推送和IOS的推送有什么 ...

  6. ThreadLocal 线程本地变量 及 源码分析

    ■ ThreadLocal 定义 ThreadLocal通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量 ...

  7. 两个ArrayList之间求交并补

    class ArraylistCalculate{ // 两个整数集求差集 public ArrayList<Integer> integerArrayListDifference( Ar ...

  8. Power BI 与 Azure Analysis Services 的数据关联:1、建立 Azure Analysis Services服务

    Power BI 与 Azure  Analysis Services 的数据关联:1.建立  Azure  Analysis Services服务

  9. innodb表锁情况

    MySQL InnoDB默认行级锁.行级锁都是基于索引的 行级锁变为表级锁情况如下: 1.如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁把整张表锁住. 2.表字段进行变更. 3.进行整表 ...

  10. ios http请求 配置

    需要在xcode 中配置下才能请求