openfire插件开发(plugin sevlet)入门

来源:互联网 发布:sqlserver date tochar 编辑:程序博客网 时间:2024/05/24 08:33

近来几天为了写一个openfire的小插件可谓脑袋都大了。。。自己又是初学小菜鸟一个,学习过程算是非常的磕磕绊绊。这里记录下来仅供后来的同学参考,也少走些弯路。勤能补拙,期望大家多多支持,共同学习,共同进步。


1.plugin插件开发

网上关于openfire插件开发的有很多,其中jooho大大的《跟我一步一步开发自己的openfire插件》很是受欢迎,我这里也是参考他的。不过相对于他的《跟我一步一步开发自己的Openfire插件》相对于我这样的小白还是有点费解的,所以这里我就更简单通俗的再讲解一遍,在助人为乐的同时也能加深学习。

本人用的是myeclipse,其他开发工具类同。

1.1简单插件入门(简单plugin结构)

在结构方面我最初也是很头疼,给那么多图反而更容易把人搞混淆。我们还是用文字加配图说明吧。

新建一个 java project ,这里命名为 test_plugin。(new -> java project -> finish)然后把src删除或重命名为 src/plugins/test/src/java (即与openfire原生插件保持一致)。若是删除src的话,就新建 Source Folder命名为 src/plugins/test/src/java (new ->  Source Folder )。然后项目目录下就会自动生成对应的 src文件夹及层级结构。

   

同样,在工程项目中新建文件夹(new ->folder)命名 build ,lib .其中build下边新建 build.properties 和 build.xml文件,用以ant编译生成插件。llib文件存放openfire等jar库。这里将openfir.jar + sevlet.jar拷贝至lib目录并add to buid path.

(servlet其实可以不用,仅导入openfire.jar即可)

1.2 build文件

build文件用于编译和打包,很多像我这样的小白基本不会用代码打包编译。网上有推荐利用源码包里边的build来编译打包,这也是一种方法,这里我使用的是jooho大大写好的build文件。我稍微做了些修改。贴上两个文件源码

uild.properties

tomcat.home=D:/Program Files/tomcat-5.0.28# If you want to build a plugin, please set the value to the plugin name.# Note:The plugin name must is the same as the plugins folder.plugin.name=test
(tomcat_home是你自己的tomcat安装/解压路径,plugin name是插件名)

build.xml

<project name="Webapp Precompilation" default="openfire-plugins" basedir="."><!-- 全局变量设置 --><property file="build.properties" /><!-- 插件源码位置 --><property name="plugin.path" value="../src/plugins/${plugin.name}/src" /><!-- web应用输出目录 --><property name="webapp.output.path" value="../src/plugins/${plugin.name}/bin" /><!-- java servlet相关文件编译jar存放位置 --><property name="java.jar.dir" value="${webapp.output.path}/java-dist"/><!-- jsp servlet编译后jar存放位置 --><property name="jsp.jar.dir" value="${webapp.output.path}/jsp-dist/lib"/><!-- 定义java servlet编译打包的Jar包名称 --><property name="java.jar" value="${java.jar.dir}/plugin-${plugin.name}.jar"/><!-- 定义jsp servlet编译打包的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.output.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.output.path}/jsp-dist/src"            package="com.qiao.univer.blog.plugin.${plugin.name}" /><!-- 编译后的servlet class 配置到web.xml文件中 --><jasper2            validateXml="false"            uriroot="${plugin.path}/web"            outputDir="${webapp.output.path}/jsp-dist/src"            package="com.qiao.univer.blog.plugin.${plugin.name}"            webXml="${plugin.web.xml}"/></target><!-- 编译jsp 并将其打jar包 --><target name="compile"><mkdir dir="${webapp.output.path}/jsp-dist/classes" /><mkdir dir="${webapp.output.path}/jsp-dist/lib" /><mkdir dir="${webapp.output.path}/jsp-dist/src" /><javac destdir="${webapp.output.path}/jsp-dist/classes" optimize="off"            encoding="UTF-8" debug="on" failonerror="false"            srcdir="${webapp.output.path}/jsp-dist/src" excludes="**/*.smap"><classpath><pathelement location="${webapp.output.path}/jsp-dist/classes" /><fileset dir="${webapp.output.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.output.path}/jsp-dist/classes" /></target><!-- 将java servlet打包成jar --><target name="java-jar"><mkdir dir="${java.jar.dir}"/><jar jarfile="${java.jar}"><fileset dir="../bin" includes="**/*.class"/></jar></target><!-- 生成可部署的插件包 --><target name="plug-jar"><!-- 插件插件包相关lib、 web目录 --><mkdir dir="${webapp.output.path}/${plugin.name}/lib"/><mkdir dir="${webapp.output.path}/${plugin.name}/web/WEB-INF"/><!-- 复制jsp servlet的jar和java servlet的相关jar包到插件包的lib目录下 --><copy file="${java.jar}" todir="${webapp.output.path}/${plugin.name}/lib"/><copy file="${jsp.jar}" todir="${webapp.output.path}/${plugin.name}/lib"/><!-- 将相关的图片、帮助文档、修改日志等文件复制到插件目录下 --><copy todir="${webapp.output.path}/${plugin.name}"><fileset dir="${plugin.path}" includes="*.*"/></copy><copy todir="${webapp.output.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.output.path}/${plugin.name}/web/WEB-INF"/><copy todir="${webapp.output.path}/${plugin.name}/web"><fileset dir="${plugin.path}/web" includes="**/*.xml"/></copy><!-- 将国际化相关资源文件复制到插件目录下         <copy file="${webapp.output.path}/bin/i18n" todir="${webapp.output.path}/${plugin.name}"/>        --><!-- 产生可部署插件包 --><jar jarfile="${webapp.output.path}/${plugin.name}.jar"><fileset dir="${webapp.output.path}/${plugin.name}" includes="**/**"/></jar></target><!-- 生成没有Web资源的可部署插件包 --><target name="java-plug-jar"><!-- 插件插件包相关lib、 web目录 --><mkdir dir="${webapp.output.path}/${plugin.name}/lib"/><!-- 复制java servlet的相关jar包到插件包的lib目录下 --><copy file="${java.jar}" todir="${webapp.output.path}/${plugin.name}/lib"/><!-- 将相关的图片、帮助文档、修改日志等文件复制到插件目录下 --><copy todir="${webapp.output.path}/${plugin.name}"><fileset dir="${plugin.path}" includes="*.*"/></copy><!-- 产生可部署插件包 --><jar jarfile="${webapp.output.path}/${plugin.name}.jar"><fileset dir="${webapp.output.path}/${plugin.name}" includes="**/**"/></jar></target><!-- 清理生成的文件 --><target name="clean"><delete file="${webapp.output.path}/${plugin.name}.jar"/><delete dir="${webapp.output.path}/${plugin.name}"/><delete dir="${webapp.output.path}/jsp-dist"/><delete dir="${webapp.output.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>
(这里有两点请注意修改
这两个地方请修改为你新建的包名。例如我的 com.qiao.univer.blogplugin)
此处不修改对 1.1简单plugin并没有影响,但对于复杂插件开发如servlet等功能添加将导致打包失败。

1.3 其他文件结构

在source folder下新建包(例 com.qiao.test.plugin),此包即为上边要修改的地方。

新建TestPlugin 类并实现Plugin接口 中的 init 和 destroy方法:

TestPlugin .java

import java.io.File;import org.jivesoftware.openfire.XMPPServer;import org.jivesoftware.openfire.container.Plugin;import org.jivesoftware.openfire.container.PluginManager;public class TestPlugin implements Plugin {private XMPPServer server;@Overridepublic void initializePlugin(PluginManager manager, File pluginDirectory) {server = XMPPServer.getInstance();System.out.println("qiao init Plugin!");System.out.println(server.getServerInfo());}@Overridepublic void destroyPlugin() {System.out.println("qiao destroy Plugin!");}}

在自动生成的src文件夹层级结构最底层src目录下添加 

changelog.htmllogo_small.giflogo_large.gif readme.html 和plugin.xml文件,其中前面是个可以从openfire源码中拷贝

changelog.html是修改日志;logo_small.gif是插件图标;plugin.xml是我们配置插件的文件,这个很重要。

配置 plugin.xml

<?xml version="1.0" encoding="UTF-8"?><plugin><!-- Main plugin class  这里是最重要滴,就是你的插件的全路径--><class>com.qiao.test.plugin.TestPlugin</class> <!-- Plugin meta-data --><name>TestPlugin</name><description>This is testplugin.</description><author>qiao</author> <version>1.0</version><date>10/05/20134</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是配置插件关联的页面的,这里用不上

至此,整个框架大概就是这样:



 编写ant命令,打可部署jar包。如果你不懂ant命令也没关系,你总知道java的基本常用的dos命令。只不过ant就是将dos转换成一个可重复多次调用的命令行。我们这里就是用上边的build.xml利用ant来编译和打包。

以下是jooho大大的话,小白可以略过。

注意:这里我没有编写编译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这个命令即可。执行命令后,你可以看到工作空间的工程目录下多了目录和文件。

1.4 插件打包部署


我们右键点击build.xml选择 run as -> ant build..


一个openfire的完美开发实例


选择openfire-plugin-java


一个openfire的完美开发实例


等待打包完成

一个openfire的完美开发实例

打包完成后刷新工程项目,会看到多出来个bin文件夹


打包成功的test.jar部署到openfire服务器,部署有两种方法:

1.直接拷贝至openfire安装目录下的plugins的文件夹内,自启动后它会自动解压

一个openfire的完美开发实例  

2.登录openfire管理界面,选择插件,上传

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

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



测试插件。启动openfire,就可以看到插件的运行结果如下:



2.含有servlet和JSP的插件开发

2.1 serlet开发及配置

 新建一个TestServlet.java 继承HttpServlet

TestServlet.java

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;import org.jivesoftware.admin.AuthCheckFilter;public class TestServlet extends HttpServlet {private static final long serialVersionUID = 1L;private static final String SERVICE_NAME = "test/*";@Overridepublic void init() throws ServletException {super.init();AuthCheckFilter.addExclude(SERVICE_NAME);}@Override    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {                response.setContentType("text/plain");        PrintWriter out = response.getWriter();        System.out.println("请求TestServlet GET Method");        out.print("请求TestServlet GET Method");        out.flush();    }     @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {                response.setContentType("text/plain");        PrintWriter out = response.getWriter();        System.out.println("请求TestServlet GET Method");        out.print("请求TestServlet POST Method");        out.flush();    }@Overridepublic void destroy() {super.destroy();AuthCheckFilter.removeExclude(SERVICE_NAME);}}

其中 AuthCheckFilter.addExclude(SERVICE_NAME); 是为了避免登录验证,如果没有这一段代码。每次访问TestServelt都会出现跳转到登录界面的情况。

在项目目录src层次结构最底层的src添加web目录,在目录下建立WEB-INF目录,添加web-custom.xml文件(文件名应该是固定的)。在里面配置我们的servlet。

web-custom.xml

<?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.qiao.test.plugin.servlet.TestServlet</servlet-class>        <servlet-name>TestServlet</servlet-name>    </servlet>        <servlet-mapping>        <servlet-name>TestServlet</servlet-name>        <url-pattern>/servlet</url-pattern>    </servlet-mapping></web-app>


2.2 Jsp开发及配置

在web目录下添加jsp文件。例 test-demo.jsp

test-demo.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>test service: 你好openfire</title>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">    <meta name="pageID" content="test-service"/>  </head>    <body>    <h3>test server jsp!! <a href="/plugins/test/servlet">TestServlet</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>

其中最重要的一点就是:<meta name="pageID" content="sample-service"/>这个pageID。这里的是固定的,后面的content对应我们plugin.xml的内容(等下看看plguin.xml的配置)。然后可以适当的看下里面table的 属性和样式,因为很多时候会在jsp中显示内容,且用table布局的。
改下之前的plugin.xml的配置,配置组件在openfire 管理员控制台的哪个地方显示,以及显示的页面。

plugin.xml

<?xml version="1.0" encoding="UTF-8"?><plugin><!-- Main plugin class  这里是最重要滴,就是你的插件的全路径--><class>com.qiao.test.plugin.TestPlugin</class> <!-- Plugin meta-data --><name>TestPlugin</name><description>This is testplugin.</description><author>qiao</author> <version>1.0</version><date>10/05/20134</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="test-service" name="Test Service" url="test-demo.jsp"                     description="Click is trigger blog plugin" />            </sidebar>        </tab>    </adminconsole></plugin>

注意,这里是jsp里边的pageID


2.3 运行ant,发布插件

这里选中openfire-plugins(default)命令打包,然后发布test.jar
注意:若最初没有修改build.xml中的包名(com.***略),这里会报错。打包失败



将test.jar发布之后,启动openfire,在openfire管理员控制台页面的服务器->服务器设置中就可以看到Test Service插件了。

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

3.Servlet拓展问题及解决

3.1.servlet登录验证问题

在没有特殊要求的情况下,我们希望直接调用sevlet却常常会跳转到另外一个界面,即管理控制台登录界面。

那怎么单独对自己插件的url进行排除呢?接着往下看!

有两种方法:修改openfire的web.xml或使用AuthCheckFilter.addExclude方法其中一种即可

1)修改openfire的web.xml

这个web.xml出现在openfire的源码很多地方,了解正确的配置方法很重要。下面展示不同路径下的web.xml修改说明,取其一即可。

a. 修改/openfire_src/src/web/WEB-INF/web.xml,修改完后,记得还要用ant编译一次并重启才能生效。

b. 修改/openfire_src/target/openfire/plugins/admin/webapp/WEB-INF/web.xml

修改完后,直接重启即可生效,本方法同样适用于安装版的openfire

[html] view plaincopy
  1. <filter>  
  2.     <filter-name>AuthCheck</filter-name>  
  3.     <filter-class>org.jivesoftware.admin.AuthCheckFilter</filter-class>  
  4.     <init-param>  
  5.         <param-name>excludes</param-name>  
  6.         <param-value>  
  7.             popplugin/*,login.jsp,index.jsp?logout=true,setup/index.jsp,setup/setup-*,.gif,.png,error-serverdown.jsp,setup/clearspace-integration-prelogin.jsp  
  8.         </param-value>  
  9.     </init-param>  
  10. </filter>  


 url的匹配规则比较复杂,有兴趣的同学可以去看AuthCheckFilter类源码,如果要测试自己的pattern对不对,可以使用org.jivesoftware.admin.AuthCheckFilterTest类执行JUnitTest试试,如自己加上一段:

[java] view plaincopy
  1. assertTrue(AuthCheckFilter.testURLPassesExclude("popplugin/sendmessage""popplugin*"));  
  2. assertTrue(AuthCheckFilter.testURLPassesExclude("popplugin/sendmessage""popplugin/sendmessage"));  

 

2)使用AuthCheckFilter.addExclude方法

调用该方法和配置web.xml的效果是完全一样的,个人建议用此方法,因为本方法绿色安全、无污染,不修改和破坏原生openfire代码。

这个方法可以在servlet的init方法或plugin的initializePlugin方法中调用。

个人建议在servlet的init方法中调用,因为servlet的init方法比plugin的initializePlugin方法更早初始化,这个问题在“插件初始化顺序”会讲到。

使用完后记得removeExclude一下,有始有终嘛。

[java] view plaincopy
  1. @Override  
  2. public void init() throws ServletException  
  3. {  
  4.     System.out.println("UserMgrServlet init....");  
  5.     AuthCheckFilter.addExclude("popplugin/usermgr*");  
  6.     AuthCheckFilter.addExclude("popplugin/usermgr/*");  
  7. }  
  8.   
  9. @Override  
  10. public void destroy()  
  11. {  
  12.     System.out.println("UserMgrServlet destroy....");  
  13.     // Release the excluded URL  
  14.     AuthCheckFilter.removeExclude("popplugin/usermgr*");  
  15.     AuthCheckFilter.removeExclude("popplugin/usermgr/*");  
  16. }  


 注意:这种方式仅限于servlet的访问,如果访问插件的jsp/html页面,页面会报NullPointException异常,解决办法见下面的说明

3.2.servlet仍然需要登录验证或者报NullPointException空指针异常

有时候在添加AuthCheckFilter.addExclude()后虽然没有跳转到登录验证了,但是若果没有登录过(session记录下管理控制台验证),会出现空指针现象:

异常:
java.lang.NullPointerExceptionat org.jivesoftware.openfire.admin.decorators.main_jsp._jspService(main_jsp.java:195)at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:547)at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:480)at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:520)at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:227)at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:941)at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:409)at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:186)at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:875)at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)at org.eclipse.jetty.server.Dispatcher.include(Dispatcher.java:195)at com.opensymphony.module.sitemesh.filter.PageFilter.applyDecorator(PageFilter.java:156)at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:59)at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1330)at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:478)at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:520)at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:227)at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:941)at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:409)at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:186)at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:875)at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250)at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149)at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)at org.eclipse.jetty.server.Server.handle(Server.java:349)at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:441)at org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:919)at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:582)at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:218)at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:51)at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:586)at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:44)at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:598)at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:533)at java.lang.Thread.run(Unknown Source)

而如果我们先在管理控制台登录一次就可以正常跳转了,这又怎么解决呢?!


还有一种情况,我们发现在单纯使用servlet作为服务接口提供数据时候,openfire会莫名地加上它原有的布局及样式,而我们仅仅只需要 servlet的 writer 去 out.print()来respons回应数据,这又该如何解决呢?


在多方查阅资料无果后,恨不得自己另写个服务器端的时候,终于找到了解决方案:

插件的页面不使用openfire控制台的页面框架

安装版的openfire的话,修改/openfire/plugins/admin/webapp/WEB-INF/decorators.xml文件

源代码版的,要修改/openfire_src/src/web/WEB-INF/decorators.xml文件

示例:

[html] view plaincopy
  1. <excludes>  
  2.     <pattern>/plugins/test/*</pattern>  
  3.     <pattern>/setup/setup-completed.jsp*</pattern>  
  4.     <pattern>/setup/setup-ldap-server_test.jsp*</pattern>  
  5.     <pattern>/setup/setup-ldap-user_test.jsp*</pattern>  
  6.     <pattern>/setup/setup-ldap-group_test.jsp*</pattern>  
  7.     <pattern>/setup/setup-clearspace-integration_test.jsp*</pattern>  
  8.     <pattern>/setup/setup-admin-settings_test.jsp*</pattern>  
  9.     <pattern>/login.jsp*</pattern>  
  10.     <pattern>/plugin-icon.jsp*</pattern>  
  11.     <pattern>/js/jscalendar/i18n.jsp*</pattern>  
  12. </excludes>  

这样,插件popplugin目录下的所有路径的jsp页面及js,css等,都能被自由的访问了。

至此,海阔天空任鸟飞了。。


感谢各位认真努力的童鞋看完这篇博文,同小白我一起了解学习了openfire插件的全过程。文中参考借鉴和挪用了不少大大的文字说明及图片,就不一一感谢了。希望看了这篇文章有收获的童鞋能给支持下。
最后附上今天开发的插件示例源码:
test_plugin


0 0
原创粉丝点击