跟我一步一步开发自己的Openfire插件

这篇是简单插件开发,下篇聊天记录插件。

开发环境:

System:Windows

WebBrowser:IE6+、Firefox3+

JavaEE Server:tomcat5.0.2.8、tomcat6

IDE:eclipse、MyEclipse 8

开发依赖库:

Jdk1.6、jasper-compiler.jar、jasper-runtime.jar、openfire.jar、servlet.jar

Email:hoojo_@126.com

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

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目录找到或者其他的地方也有(在下面的步骤会提到),这里就赘述了。

2、 新建一个自己的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服务器的话,可以用这个服务器。

3、 了解openfire源码中的插件

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

clip_image008

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

二、开发简单插件

工程现在的目录机构如下

clip_image010

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目录结构如下:

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目录中。

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

clip_image018

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包)。

clip_image020

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

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

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

clip_image022

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

三、开发带jsp、PluginServlet的插件

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

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

clip_image024

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插件目录结构如下:

clip_image026

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

clip_image028

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

 

ok,至此开发自己的openfire插件基本上就是这样的,网上这方面的资料很少,我也是官方的插件源码和网上提供的小部分资料才整出来的。本来在去年(2012)就应该发布这篇文章的,不料那个时候每天都很忙。加班、上线什么的,所以这篇文章才在今日发表。

下篇文章就是开发openfire的聊天记录插件,到时欢迎大家阅读。请随时关注我的动态哦!

如果你觉得本文不错,请点一下浏览器右下角的“顶”。谢谢!^_^

转载于:https://www.cnblogs.com/hoojo/archive/2013/03/07/2947502.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360931.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React div加载背景图

backgroundImage: url(${ActivitiesBack})

Apache FOP与Eclipse和OSGi的集成

Apache FOP是由XSL格式化对象&#xff08; XSL-FO &#xff09;驱动的开源打印处理器。 例如&#xff0c;将数据对象转换为PDF可能非常有用。 但是&#xff0c;将其集成到PDE中并最终以OSGi Service的形式运行并最终显得有些麻烦。 因此&#xff0c;我提供了一个P2存储库&…

预览视频

window.URL.createObjectURL(files[0].file),

C++ 四

//运算符函数&#xff0c; 重载。 #include<iostream> using namespace std; class A{ int data; public: A(int d0):data(d){ } void show(){ cout<<"data1"<<data<<endl; } //friend A operator-(const A& a1,const A& a2);//授权…

不删除侦听器–使用ListenerHandles

听一个可观察的实例并对它的变化做出反应很有趣。 做一些必要的事情来打断或结束这种聆听会变得很有趣。 让我们看看问题的根源和解决方法。 总览 这篇文章将首先讨论这种情况&#xff0c;然后再讨论常见的方法和问题所在。 然后&#xff0c;它将提供解决大多数问题的简单抽象…

将url参数字符串转成数组

const url"/BaseDictionary?Type34"; const arrurl.split(?); // arr["/BaseDictionary","Type34"]; typeStr parse(arr[1]); // typeStr{Type: "34"}

uniapp /deep/设置uni-app组件样式时 h5生效 小程序失效问题解决

今天写uni-app的项目 设置uni-app扩展组件的样式 使用穿透/deep/ 发现小程序没有效果 h5有效果 //小程序无效 h5生效 /deep/ .uni-list-item .uni-list-item__container .uni-list-item__content .uni-list-item__content-title{color: #333333;font-size: 32upx;}加入一下代…

使用Google Guava Cache进行本地缓存

很多时候&#xff0c;我们将不得不从数据库或另一个Web服务获取数据或从文件系统加载数据。 在涉及网络呼叫的情况下&#xff0c;将存在固有的网络等待时间&#xff0c;网络带宽限制。 解决此问题的方法之一是在应用程序本地拥有一个缓存。 如果您的应用程序跨越多个节点&…

uva 1394poj 3517

递推&#xff0c;把问题转化为具有相同问题的子问题&#xff0c;通过子问题最后所剩余的编号&#xff0c;退出此问题所剩余的编号 #include <iostream> using namespace std; const int maxn1000010; int f[maxn]; int main() {int n,k,m;while(~scanf("%d %d %d&qu…

父级和子级div的点击事件相互影响

解决方法&#xff1a;event.stopPropagation();

Jersey和Spring Boot入门

除了许多新功能&#xff0c;Spring Boot 1.2还带来了Jersey支持。 这是吸引喜欢标准方法的开发人员的重要一步&#xff0c;因为他们现在可以使用JAX-RS规范构建RESTful API&#xff0c;并将其轻松部署到Tomcat或任何其他Springs Boot支持的容器中。 带有Spring平台的Jersey可以…

js对象数组(JSON) 根据某个共同字段分组

希望的是将下面的对象数组&#xff1a; [{"id":"1001","name":"值1","value":"111"},{"id":"1001","name":"值1","value":"11111"},{"id&quo…

用装饰器改变收藏

装饰图案 自从第一次学习编程设计模式以来&#xff0c;装饰器模式一直是我的最爱。 在我看来&#xff0c;这是一个很新颖的想法&#xff0c;比其他想法有趣得多。 不要误会我的意思&#xff0c;其他大多数人也引起了我的注意&#xff0c;但没有什么比装饰器模式更重要。 至今&a…

ASP.NET WebAPI 自定义ControllerSelector

呃..今天同事要实现客户端调用不同版本Controller的功能, 其实几句代码就搞定了.. 首先定义自己的ControllerSelector,代码如下: public class ShadowControllerSelector : IHttpControllerSelector{private readonly HttpConfiguration _configuration;public ShadowControlle…

MomentJS计算两个时间的差值diff方法

moment(endTime).diff(moment(startTime), years)moment(endTime).diff(moment(startTime), months)moment(endTime).diff(moment(startTime), days) // 开始时间和结束时间的时间差&#xff0c;以“天”为单位&#xff1b;endTime和startTime都是毫秒数moment(endTime).d…

JAX-RS 2.0:服务器端处理管道

这篇文章的灵感来自JAX-RS 2.0规范文档 &#xff08;附录C&#xff09;中的Processing Pipeline部分。 我喜欢它是因为它提供了JAX-RS中所有模块的漂亮快照-以准备好吞咽的胶囊形式&#xff01; 礼貌– JAX-RS 2.0规范文档 因此&#xff0c;我想到了使用此图简要概述不同的JA…

基于TCP/IP的文件服务器编程一例

来源&#xff0c;华清远见嵌入式学院实验手册&#xff0c;代码来源&#xff1a;华清远见曾宏安 实现的功能&#xff1a; 编写TCP文件服务器和客户端。客户端可以上传和下载文件 客户端支持功能如下&#xff1a; 1.支持一下命令 help 显示客户端所有命令和说明 list 显示服务器…

React 向children中传值,layouts

const newChild React.children.map(children,function(childItem){return React.cloneElement(childItem,{key:传递的数据}) })

Apache TomEE + JMS。 这从未如此简单。

我记得J2EE &#xff08;1.3和1.4&#xff09;的过去&#xff0c;使用JMS启动项目非常困难。 您需要安装JMS 代理 &#xff0c;创建主题或队列 &#xff0c;最后使用服务器配置文件和JNDI开始自己的战斗。 感谢JavaEE 6及其它&#xff0c;使用JMS确实非常简单。 但是使用Apach…

Struts2显示double价格格式0.00

在国际化资源文件中加入&#xff1a; format.money{0,number,0.00} jsp页面用struts标签&#xff1a; <s:text name"format.money">   <s:param name"value" value"priceName" /> </s:text> 输出格式&#xff1a;0.00转载于…