Feed 适配器

Spring Integration 通过 feed 适配器提供对联合发布(syndication)的支持。该实现基于 ROME 框架

您需要在您的项目中包含此依赖项

  • Maven

  • Gradle

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-feed</artifactId>
    <version>6.4.4</version>
</dependency>
compile "org.springframework.integration:spring-integration-feed:6.4.4"

Web 联合发布是一种发布材料的方式,例如新闻报道、新闻稿、博客文章以及通常在网站上提供但也可以 feed 格式(如 RSS 或 ATOM)提供的其他项目。

Spring Integration 通过其“feed”适配器提供对 Web 联合发布的支持,并为其提供了方便的基于命名空间的配置。要配置“feed”命名空间,请在 XML 配置文件的头部包含以下元素

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

Feed 入站通道适配器

真正提供支持以检索 feed 的唯一适配器是入站通道适配器。它允许您订阅特定的 URL。以下示例展示了一种可能的配置

  • Java DSL

  • Java

  • XML

@Configuration
@EnableIntegration
public class ContextConfiguration {

    @Value("org/springframework/integration/feed/sample.rss")
    private Resource feedResource;

    @Bean
    public IntegrationFlow feedFlow() {
        return IntegrationFlow
                .from(Feed.inboundAdapter(this.feedResource, "feedTest")
                                .preserveWireFeed(true),
                        e -> e.poller(p -> p.fixedDelay(100)))
                .channel(c -> c.queue("entries"))
                .get();
    }

}
@Bean
@InboundChannelAdapter(inputChannel = "fromFeed")
public FeedEntryMessageSource feedEntrySource() {
    return new FeedEntryMessageSource("https://feeds.bbci.co.uk/news/rss.xml", "metadataKey");
}
<int-feed:inbound-channel-adapter id="feedAdapter"
        channel="feedChannel"
        url="https://feeds.bbci.co.uk/news/rss.xml">
    <int:poller fixed-rate="10000" max-messages-per-poll="100" />
</int-feed:inbound-channel-adapter>

在上述配置中,我们订阅了由 url 属性标识的 URL。

当新闻项目被检索时,它们被转换为消息并发送到由 channel 属性标识的通道。每条消息的有效载荷都是一个 com.rometools.rome.feed.synd.SyndEntry 实例。每个实例都封装了关于新闻项目的各种数据(内容、日期、作者和其他详细信息)。

入站 feed 通道适配器是一个轮询消费者。这意味着您必须提供一个轮询器配置。然而,关于 feed,您必须了解一件重要的事情,那就是它的内部工作方式与大多数其他轮询消费者略有不同。当启动一个入站 feed 适配器时,它会执行第一次轮询并接收一个 com.rometools.rome.feed.synd.SyndFeed 实例。该对象包含多个 SyndEntry 对象。每个条目都存储在本地条目队列中,并根据 max-messages-per-poll 属性的值释放,以便每条消息包含一个条目。如果在从条目队列检索条目期间队列变空,适配器会尝试更新 feed,从而用更多的条目(SyndEntry 实例)填充队列(如果有的话)。否则,下一次轮询 feed 的尝试将由轮询器的触发器决定(在上述配置中是每十秒一次)。

重复条目

轮询 feed 可能会导致已经处理过的条目(“我读过那条新闻了,为什么又给我看?”)。Spring Integration 提供了一种方便的机制来消除对重复条目的担忧。每个 feed 条目都有一个“发布日期”字段。每当生成并发送新消息时,Spring Integration 会将最新发布日期的值存储在 MetadataStore 策略的实例中(参见 元数据存储)。metadataKey 用于持久化最新发布日期。

其他选项

从 5.0 版本开始,已废弃的 com.rometools.fetcher.FeedFetcher 选项已被移除,并提供了一个针对 org.springframework.core.io.Resource 的重载 FeedEntryMessageSource 构造函数。当 feed 源不是 HTTP 端点而是任何其他资源(如本地或 FTP 上的远程资源)时,这很有用。在 FeedEntryMessageSource 的逻辑中,此类资源(或提供的 URL)由 SyndFeedInput 解析为 SyndFeed 对象,以便进行前面提到的处理。您还可以将定制的 SyndFeedInput 实例(例如,带有 allowDoctypes 选项)注入到 FeedEntryMessageSource 中。

如果与 feed 的连接需要一些定制,例如连接和读取超时,则必须使用带有其 customizeConnection(HttpURLConnection) 重写方法的 org.springframework.core.io.UrlResource 扩展,而不是将纯 URL 直接注入到 FeedEntryMessageSource 中。例如

@Bean
@InboundChannelAdapter("feedChannel")
FeedEntryMessageSource feedEntrySource() {
    UrlResource urlResource =
	    new UrlResource(url) {

	        @Override
	        protected void customizeConnection(HttpURLConnection connection) throws IOException {
	            super.customizeConnection(connection);
	            connection.setConnectTimeout(10000);
	            connection.setReadTimeout(5000);
	        }
	    };
    return new FeedEntryMessageSource(urlResource, "myKey");
}