该版本仍在开发中,尚未被视为稳定。对于最新的稳定版本,请使用 Spring Integration 7.0.0spring-doc.cadn.net.cn

XMPP 支持

Spring Integration 提供 XMPP 的通道适配器。 XMPP代表“可扩展消息与在线协议”(Extensible Messaging and Presence Protocol)。spring-doc.cadn.net.cn

XMPP描述了分布式系统中多个代理之间通信的一种方式。 典型的使用场景是发送和接收聊天消息,尽管XMPP也可以(并且确实)用于其他类型的应用。 XMPP描述了一个行为者网络。 在该网络中,参与者可以直接互通并广播状态变化(如“在场”)。spring-doc.cadn.net.cn

XMPP为全球一些最大即时通讯网络提供了消息架构,包括Google Talk(GTalk,GMail内部也可用)和Facebook Chat。 市面上有许多优质的开源XMPP服务器。 两种流行的实现方式是 Openfireejabberdspring-doc.cadn.net.cn

Spring集成通过提供XMPP适配器支持XMPP,支持发送和接收XMPP聊天消息以及客户端名单中其他条目的存在变化。spring-doc.cadn.net.cn

你需要把这种依赖性纳入你的项目中:spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-xmpp</artifactId>
    <version>6.3.12-SNAPSHOT</version>
</dependency>
compile "org.springframework.integration:spring-integration-xmpp:6.3.12-SNAPSHOT"

与其他适配器一样,XMPP 适配器支持便捷的基于命名空间的配置。 要配置XMPP命名空间,请在您的XML配置文件的头部中包含以下元素:spring-doc.cadn.net.cn

xmlns:int-xmpp="http://www.springframework.org/schema/integration/xmpp"
xsi:schemaLocation="http://www.springframework.org/schema/integration/xmpp
	https://www.springframework.org/schema/integration/xmpp/spring-integration-xmpp.xsd"

XMPP连接

在使用入站或出站XMPP适配器参与XMPP网络之前,演员必须建立其XMPP连接。 所有连接到特定账户的XMPP适配器都可以共享该连接对象。 通常,这至少需要用户,密码主机. 要创建基础的XMPP连接,你可以利用命名空间的便利性,如下示例所示:spring-doc.cadn.net.cn

<int-xmpp:xmpp-connection
    id="myConnection"
    user="user"
    password="password"
    host="host"
    port="port"
    resource="theNameOfTheResource"
    subscription-mode="accept_all"/>
为了方便起见,你可以依赖默认命名规则,省略身份证属性。 默认名称(xmpp连接)用于连接豆。

如果XMPP连接失效,只要之前的连接状态被记录(认证),就会通过自动登录重新连接。 我们还注册了连接听者,如果调试日志级别已启用。spring-doc.cadn.net.cn

订阅模式属性启动名单监听器来处理来自其他用户的订阅。 该功能并不总是适用于目标XMPP服务器。 例如,Google Cloud Messaging(GCM)和 Firebase Cloud Messaging(FCM)会完全禁用它。 要关闭订阅的名册监听器,你可以在使用 XML 配置时用空字符串配置 (订阅模式=”)或XmppConnectionFactoryBean.setSubscriptionMode(null)当使用 Java 配置时。 这样做也会在登录阶段禁用该名册。 看Roster.setRosterLoadedAtLogin(布林值)更多信息请见。spring-doc.cadn.net.cn

XMPP 消息

Spring 集成支持发送和接收XMPP消息。 为了接收这些信息,它提供了一个入站消息通道适配器。 为了发送这些信息,它提供了一个出站消息通道适配器。spring-doc.cadn.net.cn

入站消息通道适配器

Spring 集成适配器支持接收系统中其他用户的聊天消息。 为此,入站消息通道适配器会以用户身份代表你“登录”,并接收发送给该用户的消息。 这些消息随后会转发到你的 Spring 集成客户端。 这入站信道适配器element 为 XMPP 入站消息通道适配器提供配置支持。 以下示例展示了如何配置:spring-doc.cadn.net.cn

<int-xmpp:inbound-channel-adapter id="xmppInboundAdapter"
	channel="xmppInbound"
	xmpp-connection="testConnection"
	payload-expression="getExtension('google:mobile:data').json"
	stanza-filter="stanzaFilter"
	auto-startup="true"/>

除了通常的属性(对于消息通道适配器),该适配器还需要引用XMPP连接。spring-doc.cadn.net.cn

XMPP入站适配器是事件驱动的,且生命周期实现。 启动时,它会识别数据包监听器它监听 XPP 聊天消息。 它会将收到的任何消息转发给底层适配器,适配器将其转换为 Spring 集成消息并发送给指定的渠道. 停止时,会取消数据包监听器.spring-doc.cadn.net.cn

从4.3版本开始,聊天消息监听端点(以及它的<int-xmpp:inbound-channel-adapter>)支持一个org.jivesoftware.smack.filter.StanzaFilter注册于提供的XMPP通讯,以及内部诗节听者实现。 更多信息请参见 Javadocspring-doc.cadn.net.cn

4.3 版本引入了有效载荷表达式属性聊天消息监听端点. 即将到来的org.jivesoftware.smack.packet.Message表示评估上下文的根对象。 这个选项在使用 XMPP 扩展时非常有用。 例如,对于GCM协议,我们可以通过以下表达式提取主体:spring-doc.cadn.net.cn

payload-expression="getExtension('google:mobile:data').json"

以下示例提取了XHTML协议的正文:spring-doc.cadn.net.cn

payload-expression="getExtension(T(org.jivesoftware.smackx.xhtmlim.packet.XHTMLExtension).NAMESPACE).bodies[0]"

为了简化对XMPP消息扩展的访问,以下外延变量被添加到评价背景. 注意,当消息中只有一个分机时,会添加该分机。 前面的例子展示了Namespace作可以简化为以下示例:spring-doc.cadn.net.cn

payload-expression="#extension.json"
payload-expression="#extension.bodies[0]"

出站消息通道适配器

你也可以使用外站消息通道适配器向XMPP上的其他用户发送聊天消息。 这出站通道适配器element 为 XMPP 出站消息通道适配器提供配置支持。spring-doc.cadn.net.cn

<int-xmpp:outbound-channel-adapter id="outboundEventAdapter"
						channel="outboundEventChannel"
						xmpp-connection="testConnection"/>

适配器期望其输入至少是某类有效载荷java.lang.字符串以及一个头值XmppHeaders.CHAT_TO这会指定消息应发送给哪个用户。 创建消息时,您可以使用类似以下的 Java 代码:spring-doc.cadn.net.cn

Message<String> xmppOutboundMsg = MessageBuilder.withPayload("Hello, XMPP!" )
						.setHeader(XmppHeaders.CHAT_TO, "userhandle")
						.build();

你也可以通过XMPP头部增强器支持来设置头部,如下示例所示:spring-doc.cadn.net.cn

<int-xmpp:header-enricher input-channel="input" output-channel="output">
	<int-xmpp:chat-to value="[email protected]"/>
</int-xmpp:header-enricher>

从4.3版本开始,对聊天消息发送消息处理器<int-xmpp:出站-通道-适配器>在XML配置中)。 除了常规的字符串org.jivesoftware.smack.packet.Message有效载荷,现在你可以发送一个载荷为org.jivesoftware.smack.packet.XmlElement(该填充于org.jivesoftware.smack.packet.Message.addExtension()setBody(). 为了方便起见,我们添加了一个分机-提供者选项聊天消息发送消息处理器. 它允许你注射org.jivesoftware.smack.provider.ExtensionElementProvider,构建一个XmlElement运行时对有效载荷进行对比。 在这种情况下,有效载荷必须是 JSON 或 XML 格式的字符串,具体取决于 XEP 协议。spring-doc.cadn.net.cn

XMPP 的存在感

XMPP还支持广播状态。 你可以利用这个功能让拥有你名单的人看到你所在的状态变化。 这种情况在你的即时通讯客户身上经常发生。 你更改了离开状态并设置了离开消息,所有拥有你的人都会看到你的图标或用户名因新状态变化,可能会看到你的新“离开”消息。 如果您想接收状态变化的通知或通知他人,可以使用 Spring Integration 的“在席”适配器。spring-doc.cadn.net.cn

入站在线消息通道适配器

Spring Integration提供了一个入站在线信息通道适配器,支持接收系统中其他用户的在线状态事件。 为此,适配器会以用户身份“登录”,代表你注册名录听众,并将收到的在线状态更新事件作为消息转发到由渠道属性。 消息的有效载荷是org.jivesoftware.smack.packet.Presence(存在)对象(见 www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smack/packet/Presence.html)。spring-doc.cadn.net.cn

在线进信道适配器element 为 XMPP 入站在线消息通道适配器提供配置支持。 以下示例配置了一个入站在线消息通道适配器:spring-doc.cadn.net.cn

<int-xmpp:presence-inbound-channel-adapter channel="outChannel"
		xmpp-connection="testConnection" auto-startup="false"/>

除了常规属性外,该适配器还需要引用XMPP连接。 该适配器是事件驱动的,且生命周期实现。 它识别了一个名录听众启动时并取消了名录听众当停下时。spring-doc.cadn.net.cn

出站在线消息通道适配器

Spring Integration还支持发送在线状态事件,让网络中恰好拥有你的其他用户看到。 当你向出站在线消息通道适配器发送消息时,它会提取有效载荷(预计类型为org.jivesoftware.smack.packet.Presence(存在))并将其发送到XMPP连接,从而向网络其他部分宣传你的在线事件。spring-doc.cadn.net.cn

在线-出站-通道适配器element 为 XMPP 出站在线消息通道适配器提供配置支持。 以下示例展示了如何配置出站在线消息通道适配器:spring-doc.cadn.net.cn

<int-xmpp:presence-outbound-channel-adapter id="eventOutboundPresenceChannel"
	xmpp-connection="testConnection"/>

它也可以是轮询消费者(如果接收的是可轮询信道的消息),这时你需要注册轮询器。 以下示例展示了如何实现:spring-doc.cadn.net.cn

<int-xmpp:presence-outbound-channel-adapter id="pollingOutboundPresenceAdapter"
		xmpp-connection="testConnection"
		channel="pollingChannel">
	<int:poller fixed-rate="1000" max-messages-per-poll="1"/>
</int-xmpp:presence-outbound-channel-adapter>

与其入站对应服务一样,它需要引用 XMPP 连接。spring-doc.cadn.net.cn

如果你依赖XMPP连接豆的默认命名规则(前面描述),并且在应用上下文中只配置了一个XMPP连接豆,你可以省略XMPP连接属性。 在这种情况下,命名的豆子xmpp连接被定位并注入适配器。

高级配置

Spring Integration 的 XMPP 支持基于 Smack 4.0 API(www.igniterealtime.org/projects/smack/),该 API 允许对 XMPP 连接对象进行更复杂的配置。spring-doc.cadn.net.cn

前所述XMPP连接命名空间支持旨在简化基本连接配置,只支持少数常见配置属性。 然而,org.jivesoftware.smack.ConnectionConfiguration对象定义了大约20个属性,给所有属性添加命名空间支持并没有实际价值。 因此,对于更复杂的连接配置,你可以配置我们的实例Xmpp连接工厂豆作为普通豆子并注入org.jivesoftware.smack.ConnectionConfiguration作为构造子论证工厂豆. 你可以直接在上面指定所有需要的属性连接配置实例。 (带有“p”命名空间的豆子定义会很合适。) 这样你可以直接设置SSL(或其他属性)。 以下示例展示了如何实现:spring-doc.cadn.net.cn

<bean id="xmppConnection" class="o.s.i.xmpp.XmppConnectionFactoryBean">
    <constructor-arg>
        <bean class="org.jivesoftware.smack.ConnectionConfiguration">
            <constructor-arg value="myServiceName"/>
            <property name="socketFactory" ref="..."/>
        </bean>
    </constructor-arg>
</bean>

<int:channel id="outboundEventChannel"/>

<int-xmpp:outbound-channel-adapter id="outboundEventAdapter"
    channel="outboundEventChannel"
    xmpp-connection="xmppConnection"/>

Smack API 还提供静态初始化器,这很有帮助。 对于更复杂的情况(例如注册SASL机制),你可能需要执行某些静态初始化器。 其中一个静态初始化器是SASL自学,允许你注册支持的SASL机制。 对于这种复杂度,我们建议使用 Spring Java 配置来实现 XMPP 连接配置。 这样,你可以通过 Java 代码配置整个组件,并在适当的时候执行所有其他必要的 Java 代码,包括静态初始化器。 以下示例展示了如何在 Java 中配置带有 SASL(简单认证和安全层)的 XMPP 连接:spring-doc.cadn.net.cn

@Configuration
public class CustomConnectionConfiguration {
  @Bean
  public XMPPConnection xmppConnection() {
	SASLAuthentication.supportSASLMechanism("EXTERNAL", 0); // static initializer

	ConnectionConfiguration config = new ConnectionConfiguration("localhost", 5223);
	config.setKeystorePath("path_to_truststore.jks");
	config.setSecurityEnabled(true);
	config.setSocketFactory(SSLSocketFactory.getDefault());
	return new XMPPConnection(config);
  }
}

有关使用 Java 进行应用上下文配置的更多信息,请参阅 Spring 参考手册中的以下部分。spring-doc.cadn.net.cn

XMPP消息头

Spring Integration XMPP 适配器会自动映射标准 XMPP 属性。 默认情况下,这些属性会被复制到Spring Integration之间消息头通过DefaultXmppHeaderMapper.spring-doc.cadn.net.cn

除非请求首部名称回复头名称的性质DefaultXmppHeaderMapper.spring-doc.cadn.net.cn

在映射用户自定义的头部时,值也可能包含简单的万用字符模式(如“thing*”或“*thing”)。

从4.1版本开始,抽象首部映射器(一个超类DefaultXmppHeaderMapper)允许你配置NON_STANDARD_HEADERS用于请求首部名称性质(除了STANDARD_REQUEST_HEADERS),用于映射所有用户定义的头部。spring-doc.cadn.net.cn

org.springframework.xmpp.XmppHeaders类识别将被DefaultXmppHeaderMapper:spring-doc.cadn.net.cn

从4.3版本开始,你可以通过在模式前面加上 来消除头部映射中的模式!. 否定模式优先级,因此列表如STANDARD_REQUEST_HEADERS,thing1,thing*,!thing2,!thing3,qux,!thing1不映射东西1,东西2东西3. 那个列表确实映射了标准头部 plus东西4库克斯.spring-doc.cadn.net.cn

如果你有一个用户自定义的头部,开头是!你想要映射的,可以通过以下方式逃离:\STANDARD_REQUEST_HEADERS,\!我的爆炸头. 在该示例中,标准请求头和!我的BangHeader被映射。

XMPP扩展

扩展将“可扩展”纳入“可扩展消息与在线状态协议”中。spring-doc.cadn.net.cn

XMPP 基于 XML 数据格式,支持一种称为命名空间的概念。 通过命名空间,你可以向XMPP添加原始规范中未定义的位。 XMPP规范有意只描述一组核心特性:spring-doc.cadn.net.cn

实现后,你就拥有了一个XMPP客户端,可以发送任何你想要的数据。 不过,你可能需要做的不仅仅是基础。 例如,您可能需要在消息中包含格式(加粗、斜体等),而这在核心XMPP规范中没有定义。 嗯,你可以编造一种方法来实现这一点,但除非其他人都用和你一样的方式,否则其他软件无法解释它(它们忽略了自己无法理解的命名空间)。spring-doc.cadn.net.cn

为解决这一问题,XMPP标准基金会(XSF)发布了一系列额外文件,称为XMPP扩展协议(XEPs)。 一般来说,每个 XEP 描述的是特定的活动(从消息格式化到文件传输、多用户聊天等)。 他们还为所有人提供了该活动的标准格式。spring-doc.cadn.net.cn

Smack API 提供了许多 XEP 实现扩展实验的 项目。 从 Spring Integration 4.3 版本开始,你可以用现有的 XMPP 通道适配器使用任何 XEP。spring-doc.cadn.net.cn

要处理 XEP 或其他自定义 XMPP 扩展,您必须提供 Smack 的ProviderManager(服务经理)预配置。 你可以用静态的Java代码,如下示例所示:spring-doc.cadn.net.cn

ProviderManager.addIQProvider("element", "namespace", new MyIQProvider());
ProviderManager.addExtensionProvider("element", "namespace", new MyExtProvider());

你也可以使用。提供商在特定实例中设置配置文件,并用JVM参数访问,如下示例所示:spring-doc.cadn.net.cn

-Dsmack.provider.file=file:///c:/my/provider/mycustom.providers

mycustom.providers文件可能如下:spring-doc.cadn.net.cn

<?xml version="1.0"?>
<smackProviders>
<iqProvider>
    <elementName>query</elementName>
    <namespace>jabber:iq:time</namespace>
    <className>org.jivesoftware.smack.packet.Time</className>
</iqProvider>

<iqProvider>
    <elementName>query</elementName>
    <namespace>https://jabber.org/protocol/disco#items</namespace>
    <className>org.jivesoftware.smackx.provider.DiscoverItemsProvider</className>
</iqProvider>

<extensionProvider>
    <elementName>subscription</elementName>
    <namespace>https://jabber.org/protocol/pubsub</namespace>
    <className>org.jivesoftware.smackx.pubsub.provider.SubscriptionProvider</className>
</extensionProvider>
</smackProviders>

例如,最受欢迎的XMPP消息扩展是Google Cloud Messaging(GCM)。 Smack 库提供org.jivesoftware.smackx.gcm.provider.GcmExtensionProvider为了这个目的。 默认情况下,它会用毒品实验通过使用experimental.providersresource,正如以下Maven示例所示:spring-doc.cadn.net.cn

<!-- GCM JSON payload -->
<extensionProvider>
    <elementName>gcm</elementName>
    <namespace>google:mobile:data</namespace>
    <className>org.jivesoftware.smackx.gcm.provider.GcmExtensionProvider</className>
</extensionProvider>

另外,还有GcmPacket扩展目标消息协议解析进来的数据包并构建出数据包,如下示例所示:spring-doc.cadn.net.cn

GcmPacketExtension gcmExtension = (GcmPacketExtension) xmppMessage.getExtension(GcmPacketExtension.NAMESPACE);
String message = gcmExtension.getJson());
GcmPacketExtension packetExtension = new GcmPacketExtension(gcmJson);
Message smackMessage = new Message();
smackMessage.addExtension(packetExtension);

更多信息请参见本章前半部分的入站消息通道适配器出站消息通道适配器spring-doc.cadn.net.cn