在本教程中,学习从spring boot应用程序创建和使用RSS和Atom提要。 您必须在各种网站上(例如我们的RSS提要)以文本或图像按钮的形式看到这一点,邀请您“通过RSS订阅”。RSS是简单的联合API - 通常称为Rich Site Summary。 RSS革新了用户与在线内容交互的方式。
与RSS类似,Atom也是基于XML的Web内容和元数据联合格式,以及用于发布和编辑属于定期更新网站的Web资源的应用程序级协议。 所有Atom提要必须是格式良好的XML文档,应用程序/ atom + xml媒体类型。
在这个spring boot例子中,我们将使用spring bootAPI公开两个简单的RSS和ATOM端点,我们将看到如何使用java客户端来使用这些订阅。
基本上用Spring框架发布RSS或Atom提要非常简单。 在Spring框架中有两个http消息转换器(RssChannelHttpMessageConverter和AtomFeedHttpMessageConverter),可以将spring控制器方法的响应转换为XML feed格式,如果返回类型与任何这些feed有关。
两个转换器都依赖于ROME库,当它发现类路径中的库时,Spring Framework会自动注册这两个转换器。 我们所要做的就是将ROME库作为依赖添加到我们的pom.xml中。
Spring Boot 项目创建可以参考:Spring Boot 入门 创建项目
<dependency>
<groupId>com.rometools</groupId>
<artifactId>rome</artifactId>
<version>1.8.0</version>
</dependency>
现在添加一个Spring Controller,并分别添加两个端点/ rss和/ atom来公开RSS和Atom提要。 正如我们已经提到的,只是添加这个控制器会自动工作的情况下,因为内部弹簧框架将注册两个http消息转换器(RssChannelHttpMessageConverter和AtomFeedHttpMessageConverter),一旦我们在类路径中有ROAM依赖关系,将被注册。
只有我们需要这样做才能从控制器方法返回适当的Feed类型对象。 在我们的例子中,feed对象的类型是com.rometools.rome.feed.rss.Channel,而Atom则是com.rometools.rome.feed.atom.Feed。 所以在添加Feed的内容和有关频道的其他细节之后,我们的控制器将如下所示。
package net.xqlee.project.controller;
import java.util.Collections;
import java.util.Date;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.rometools.rome.feed.atom.Category;
import com.rometools.rome.feed.atom.Content;
import com.rometools.rome.feed.atom.Entry;
import com.rometools.rome.feed.atom.Feed;
import com.rometools.rome.feed.atom.Link;
import com.rometools.rome.feed.atom.Person;
import com.rometools.rome.feed.rss.Channel;
import com.rometools.rome.feed.rss.Description;
import com.rometools.rome.feed.rss.Image;
import com.rometools.rome.feed.rss.Item;
import com.rometools.rome.feed.synd.SyndPerson;
@RestController
public class FeedController {
@GetMapping(path = "/rss")
public Channel rss() {
Channel channel = new Channel();
channel.setFeedType("rss_2.0");
channel.setTitle("Leftso Feed");
channel.setDescription("最新技术的不同文章");
channel.setLink("http://www.leftso.com");
channel.setUri("http://www.leftso.com");
channel.setGenerator("在屋里编程");
Image image = new Image();
image.setUrl("/resources/assist/images/blog/b8fb228cdff44b8ea65d1e557bf05d2b.png");
image.setTitle("Leftso Feed");
image.setHeight(32);
image.setWidth(32);
channel.setImage(image);
Date postDate = new Date();
channel.setPubDate(postDate);
Item item = new Item();
item.setAuthor("Leftso");
item.setLink("http://www.leftso.com/blog/64.html");
item.setTitle("http://www.leftso.com/blog/64.html");
item.setUri("http://www.leftso.com/blog/64.html");
item.setComments("http://www.leftso.com/blog/64.html");
com.rometools.rome.feed.rss.Category category = new com.rometools.rome.feed.rss.Category();
category.setValue("CORS");
item.setCategories(Collections.singletonList(category));
Description descr = new Description();
descr.setValue(
"两者没有必然的联系,但是spring boot可以看作为spring MVC的升级版."
+ " <a rel=\"nofollow\" href=\"http://www.leftso.com/blog/64.html/\">Spring boot 入门(一)环境搭建以及第一个应用</a>发布在 <a rel=\"nofollow\" href=\"http://www.leftso.com\">Leftso</a>.");
item.setDescription(descr);
item.setPubDate(postDate);
channel.setItems(Collections.singletonList(item));
//Like more Entries here about different new topics
return channel;
}
@GetMapping(path = "/atom")
public Feed atom() {
Feed feed = new Feed();
feed.setFeedType("atom_1.0");
feed.setTitle("Leftso");
feed.setId("http://www.leftso.com/");
Content subtitle = new Content();
subtitle.setType("text/plain");
subtitle.setValue("最新技术的不同文章");
feed.setSubtitle(subtitle);
Date postDate = new Date();
feed.setUpdated(postDate);
Entry entry = new Entry();
Link link = new Link();
link.setHref("http://www.leftso.com/blog/64.html");
entry.setAlternateLinks(Collections.singletonList(link));
SyndPerson author = new Person();
author.setName("Leftso");
entry.setAuthors(Collections.singletonList(author));
entry.setCreated(postDate);
entry.setPublished(postDate);
entry.setUpdated(postDate);
entry.setId("http://www.leftso.com/blog/64.html");
entry.setTitle("Spring boot 入门(一)环境搭建以及第一个应用");
Category category = new Category();
category.setTerm("CORS");
entry.setCategories(Collections.singletonList(category));
Content summary = new Content();
summary.setType("text/plain");
summary.setValue("两者没有必然的联系,但是spring boot可以看作为spring MVC的升级版."
+ " <a rel=\"nofollow\" href=\"http://www.leftso.com/blog/64.html/\">Spring boot 入门(一)环境搭建以及第一个应用</a>发布在 <a rel=\"nofollow\" href=\"http://www.leftso.com\">Leftso</a>.");
entry.setSummary(summary);
feed.setEntries(Collections.singletonList(entry));
//参加这里关于不同的新话题
return feed;
}
}
我们已经有很多Feed阅读器可用,但是如果您需要以编程方式使用此Feed,则可以通过使用ROAM库的这几行简单代码来完成此操作。
package net.xqlee.project;
import java.net.URL;
import com.rometools.rome.feed.synd.SyndEntry;
import com.rometools.rome.feed.synd.SyndFeed;
import com.rometools.rome.io.SyndFeedInput;
import com.rometools.rome.io.XmlReader;
public class FeedConsumer {
public static void main(String[] args) {
try {
String url = "http://localhost:8080/rss";
try (XmlReader reader = new XmlReader(new URL(url))) {
SyndFeed feed = new SyndFeedInput().build(reader);
System.out.println(feed.getTitle());
System.out.println("***********************************");
for (SyndEntry entry : feed.getEntries()) {
System.out.println(entry);
System.out.println("***********************************");
}
System.out.println("Done");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里的URL是用于RSS提要的,如果将URL更改为Atom提要,同样的代码也可以工作。
输出
这里是控制台输出feed client:
Leftso Feed
***********************************
SyndEntryImpl.comments=http://www.leftso.com/blog/64.html
SyndEntryImpl.author=Leftso
SyndEntryImpl.wireEntry=null
SyndEntryImpl.link=http://www.leftso.com/blog/64.html
SyndEntryImpl.description.mode=null
SyndEntryImpl.description.type=text/html
SyndEntryImpl.description.interface=interface com.rometools.rome.feed.synd.SyndContent
SyndEntryImpl.description.value=两者没有必然的联系,但是spring boot可以看作为spring MVC的升级版. <a rel="nofollow" href="http://www.leftso.com/blog/64.html/">Spring boot 入门(一)环境搭建以及第一个应用</a>发布在 <a rel="nofollow" href="http://www.leftso.com">Leftso</a>.
SyndEntryImpl.foreignMarkup=[]
SyndEntryImpl.updatedDate=null
SyndEntryImpl.source=null
SyndEntryImpl.title=http://www.leftso.com/blog/64.html
SyndEntryImpl.interface=interface com.rometools.rome.feed.synd.SyndEntry
SyndEntryImpl.uri=http://www.leftso.com/blog/64.html
SyndEntryImpl.enclosures=[]
SyndEntryImpl.modules[0].date=Sun Nov 12 11:57:14 CST 2017
SyndEntryImpl.modules[0].formats=[]
SyndEntryImpl.modules[0].rightsList=[]
SyndEntryImpl.modules[0].sources=[]
SyndEntryImpl.modules[0].creators[0]=Leftso
SyndEntryImpl.modules[0].subject=null
SyndEntryImpl.modules[0].description=null
SyndEntryImpl.modules[0].language=null
SyndEntryImpl.modules[0].source=null
SyndEntryImpl.modules[0].type=null
SyndEntryImpl.modules[0].title=null
SyndEntryImpl.modules[0].interface=interface com.rometools.rome.feed.module.DCModule
SyndEntryImpl.modules[0].coverages=[]
SyndEntryImpl.modules[0].descriptions=[]
SyndEntryImpl.modules[0].relation=null
SyndEntryImpl.modules[0].contributor=null
SyndEntryImpl.modules[0].rights=null
SyndEntryImpl.modules[0].publishers=[]
SyndEntryImpl.modules[0].coverage=null
SyndEntryImpl.modules[0].identifier=null
SyndEntryImpl.modules[0].creator=Leftso
SyndEntryImpl.modules[0].types=[]
SyndEntryImpl.modules[0].languages=[]
SyndEntryImpl.modules[0].identifiers=[]
SyndEntryImpl.modules[0].subjects=[]
SyndEntryImpl.modules[0].format=null
SyndEntryImpl.modules[0].dates[0]=Sun Nov 12 11:57:14 CST 2017
SyndEntryImpl.modules[0].titles=[]
SyndEntryImpl.modules[0].uri=http://purl.org/dc/elements/1.1/
SyndEntryImpl.modules[0].publisher=null
SyndEntryImpl.modules[0].contributors=[]
SyndEntryImpl.modules[0].relations=[]
SyndEntryImpl.contents=[]
SyndEntryImpl.links=[]
SyndEntryImpl.contributors=[]
SyndEntryImpl.publishedDate=Sun Nov 12 11:57:14 CST 2017
SyndEntryImpl.categories[0].taxonomyUri=null
SyndEntryImpl.categories[0].name=CORS
SyndEntryImpl.categories[0].interface=interface com.rometools.rome.feed.synd.SyndCategory
SyndEntryImpl.authors=[]
SyndEntryImpl.titleEx.mode=null
SyndEntryImpl.titleEx.type=null
SyndEntryImpl.titleEx.interface=interface com.rometools.rome.feed.synd.SyndContent
SyndEntryImpl.titleEx.value=http://www.leftso.com/blog/64.html
***********************************
Done