在Spring Boot项目里接入RSS读取能力,核心目标是把远端不断更新的XML订阅流转换成可查询的业务对象。借助成熟的Rome类库,我们无需关心底层XML节点差异,就能用统一模型拿到标题、链接与发布时间。
一、引入依赖与基础配置
Spring Boot本身并未内置RSS解析模块,因此需要在构建文件中加入Rome及其辅助工具。Rome负责解析多种RSS与Atom格式,JDOM作为底层DOM实现被自动携带。我们还引入Spring的调度 starter 来开启定时任务。
下面以Maven为例,注意rome的版本应选择仍在维护的分支,避免旧版不支持HTTPS证书校验。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.rometools</groupId>
<artifactId>rome</artifactId>
<version>1.18.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-scheduling</artifactId>
</dependency>
</dependencies>
依赖就位后,在配置类上开启调度支持。若仅做单次读取演示,也可直接在单元测试中调用工具方法,不必启动整个Web容器。
将待订阅地址外置到application.yml,方便后续不改代码即可增减源。使用@ConfigurationProperties绑定到POJO,比硬编码更利于运维。
@Configuration
@EnableScheduling
public class RssConfig {
// 空方法即可激活调度
}
二、封装RSS读取服务
读取逻辑集中在Service层。通过URLConnection或Spring的RestTemplate拿到输入流,交给Rome的SyndFeedInput解析。该对象能自动识别RSS 1.0、2.0与Atom,返回统一的SyndFeed视图。
需要注意,部分站点返回的流未声明编码,Rome默认按UTF-8处理。若遇到乱码,应先用InputStreamReader指定正确字符集再传入解析器,否则中文标题会变成问号。
@Service
public class RssFetchService {
public List<Article> fetch(String urlStr) throws Exception {
URL url = new URL(urlStr);
InputStream is = url.openStream();
SyndFeedInput input = new SyndFeedInput();
// 指定编码避免乱码
SyndFeed feed = input.build(new InputStreamReader(is, StandardCharsets.UTF_8));
List<Article> list = new ArrayList<>();
for (SyndEntry entry : feed.getEntries()) {
Article a = new Article();
a.setTitle(entry.getTitle());
a.setLink(entry.getLink());
a.setPublishedDate(entry.getPublishedDate());
list.add(a);
}
is.close();
return list;
}
}
上面的代码未处理超时,生产环境必须设置URLConnection.setConnectTimeout与读取超时,防止某个源挂掉拖死整个任务线程。
异常隔离也很关键:一个源解析失败不应中断其他源。建议在调用处捕获异常并记录日志,而不是抛到调度层导致后续源不再执行。
三、定时拉取与数据落地
借助@Scheduled注解,我们可以每十分钟批量刷新一次。配合数据库唯一索引,实现增量写入,避免重复文章堆积。
以下示例在固定延迟下执行,若上轮未完成不会并发启动,降低系统压力。实际项目中可改用线程池异步处理不同源以提升吞吐。
@Component
public class RssScheduler {
@Autowired
private RssFetchService fetchService;
@Autowired
private ArticleRepository repository;
@Scheduled(fixedDelay = 600000)
public void pullAll() {
String[] sources = {"https://ipipp.com/feed.xml", "https://ipipp.com/news.atom"};
for (String src : sources) {
try {
List<Article> items = fetchService.fetch(src);
repository.saveAll(items);
} catch (Exception e) {
// 单源失败不影响其他源
System.err.println("拉取失败:" + src);
}
}
}
}
数据落地后,业务层就能像查询普通表一样展示最新资讯。若需要全文检索,可将标题与摘要同步进Elasticsearch。
在单元测试中,用WireMock模拟HTTP响应能脱离外网验证解析逻辑。构造一段标准RSS XML返回,断言标题被正确提取即可,这样CI环境也能稳定跑通。
四、常见问题与优化思路
不少开发者忽略源的HTTPS证书问题,老版本Rome在JDK8下可能报错。升级到新版本或自定义TrustManager可解决,但生产环境不建议关闭校验。
另一个误区是每次全量拉取所有历史条目。其实大多数源只保留近期内容,可只取前二十条并依据发布时间做断点续拉,显著减少带宽与数据库写入。
| 方案 | 优点 | 缺点 |
|---|---|---|
| 手动HttpURLConnection加正则 | 无第三方依赖 | 格式变动即失效,维护成本高 |
| Rome统一解析 | 兼容多格式,代码量少 | 需引入约1MB依赖包 |
通过合理的超时、异常隔离与增量策略,Spring Boot集成RSS源读取可以成为稳定且低耗的资讯聚合底座,支撑运营后台或门户网站的动态内容板块。
Spring_BootRSSrome修改时间:2026-08-01 22:39:21