RSS(也叫聚合内容,Really Simple Syndication)现在用的已经很广啦,最初的RSS要追溯到1995年,当Ramanathan V. Guha和其他在苹果电脑公司的高级技术组开发了一个测试的内容框架。更多有关RSS的资料可查看这里,下面我们来为我们的JSP网站生成RSS。
首先我们来看看最基本的RSS结构:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
</rss>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"></rss>
其实就是一个XML文件!在<rss></rss>之间我们可以自由配置自己要发布的RSS的格式。例如此次我们要发布的RSS是这样的:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" x
mlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/" x
mlns:slash="http://purl.org/rss/1.0/modules/slash/">
<channel>
<item>
<title>JSP网站RSS的实现</title>
<author>neeke</author>
<pubDate>2008-10-04</pubDate>
<description>这是来自尼克技术博客博客的RSS</description>
<category>J2EE技术</category>
</item>
</channel>
</rss>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><item><title>JSP网站RSS的实现</title><author>neeke</author><pubDate>2008-10-04</pubDate><description>这是来自尼克技术博客博客的RSS</description><category>J2EE技术</category></item></channel></rss>
了解了它的结构实现起来就容易了。我们创建IO流,并从数据库中获取到我们要发布的RSS资源的集合,然后按照它的格式与结构一行一行的写入到一个RSS.XML文件中即可。
public static void publishRss(String rssPath)
{
//获得要发布的RSS数据集合
ArrayList rssArticle = ArticleManager.getArticlesAll();
try {
//创建输入输出流
FileWriter fw = new FileWriter(rssPath);
BufferedWriter bw = new BufferedWriter(fw);
//开始按照格式写入数据
bw.write(
"<?xml version=/"1.0/" encoding=/"UTF-8/" standalone=/"yes/"?>/r/n");
bw.write("<?xml-stylesheet type=/"text/xsl/" href=/"CSS/rss.xslt/"?>");
bw.write("<rss version=/"2.0/" xmlns:dc=/"http://purl.org/dc/elements/1.1//" xmlns:trackback=/"http://madskills.com/public/xml/rss/module/trackback//" xmlns:wfw=/"http://wellformedweb.org/CommentAPI//" xmlns:slash=/"http://purl.org/rss/1.0/modules/slash//">/r/n");
bw.write("<channel>/r/n");
for (int i = 0; i < rssArticle.size(); i++) {
ArticleBean article = (ArticleBean) rssArticle.get(i);
bw.write("<item>/r/n");
bw.write("<title>" + article.getTitle() + "</title>/r/n");
bw.write("<author>" + article.getAuthorId() + "</author>/r/n");
bw.write("<pubDate>" + article.getPostTime() + "</pubDate>/r/n");
bw.write("<description>" + article.getIntro() +
"</description>/r/n");
bw.write("<category>" + article.getCateId() + "</category>/r/n");
bw.write("</item>/r/n");
}
bw.write("</channel>/r/n");
bw.write("</rss>");
//关闭流,RSS发布完毕。
bw.close();
fw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void publishRss(String rssPath) { //获得要发布的RSS数据集合 ArrayList rssArticle = ArticleManager.getArticlesAll(); try { //创建输入输出流 FileWriter fw = new FileWriter(rssPath); BufferedWriter bw = new BufferedWriter(fw); //开始按照格式写入数据 bw.write( "<?xml version=/"1.0/" encoding=/"UTF-8/" standalone=/"yes/"?>/r/n"); bw.write("<?xml-stylesheet type=/"text/xsl/" href=/"CSS/rss.xslt/"?>"); bw.write("<rss version=/"2.0/" xmlns:dc=/"http://purl.org/dc/elements/1.1//" xmlns:trackback=/"http://madskills.com/public/xml/rss/module/trackback//" xmlns:wfw=/"http://wellformedweb.org/CommentAPI//" xmlns:slash=/"http://purl.org/rss/1.0/modules/slash//">/r/n"); bw.write("<channel>/r/n"); for (int i = 0; i < rssArticle.size(); i++) { ArticleBean article = (ArticleBean) rssArticle.get(i); bw.write("<item>/r/n"); bw.write("<title>" + article.getTitle() + "</title>/r/n"); bw.write("<author>" + article.getAuthorId() + "</author>/r/n"); bw.write("<pubDate>" + article.getPostTime() + "</pubDate>/r/n"); bw.write("<description>" + article.getIntro() + "</description>/r/n"); bw.write("<category>" + article.getCateId() + "</category>/r/n"); bw.write("</item>/r/n"); } bw.write("</channel>/r/n"); bw.write("</rss>"); //关闭流,RSS发布完毕。 bw.close(); fw.close(); } catch (IOException ex) { ex.printStackTrace(); } }
发布完毕,经过我的测试打开后会提示出错,用记事本打开生成的源文件,然而我们的RSS文件是一点问题都没有的哇,怎么可能呢?接着又用JBuilder打开这个XML文件,晕倒~汉字全是乱码,立刻意识到问题出在了哪里了。在哪呢?其实就是文件的编码问题!将原先
bw.write("<?xml version=/"1.0/" encoding=/"UTF-8/" standalone=/"yes/"?>/r/n");该行代码中的UTF-8改为GBK,重新跑一次程序,一切OK!
I implement this RSS feed generator using Regular Expression, this is really a handy tool to work with. you can specify max amount of feed items, all newly added feed items will be inserted right into the place where the previous first feed item sits, and all this is done with only TWO methods invocation. You just create an RSSEntryFeed object, and pass it as a parameter to the createRSSFeedItem(RSSFeedEntry feedEntry) method to create an XML representation(just a String) of the object, and invoke the addRSSFeedItem(String strFeedItem, int limit) method, and you have your newly created blog entry added to your RSS feed...
package cn.com.kevintse.rss;
/**
* @author Kevin Tse
* @version 0.1
*/
public class RSSFeedEntry {
private String title;
private String description;
private String link;
private String author;
private String guid;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
}
package cn.com.kevintse.rss;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Kevin Tse
* @version 0.1
*/
public class RSSFeedGenerator {
char n = '/n';
char tab = '/t';
public void createRSSFeedFile()throws Exception {
File file = new File("feed.rss");
FileOutputStream fos = new FileOutputStream(file);
PrintStream ps = new PrintStream(fos, false, "UTF-8");
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=/"1.0/" encoding=/"UTF-8/"?>").append(n);
sb.append("<rss version=/"2.0/">").append(n);
sb.append(tab).append("<channel>").append(n);
sb.append(tab).append(tab).append("<title>Energetic Mind</title>").append(n);
sb.append(tab).append(tab).append("<link>http://kevintse.com.cn</link>").append(n);
sb.append(tab).append(tab).append("<description><![CDATA[Kevin Tse's blog]]></description>").append(n);
sb.append(tab).append(tab).append("<pubDate>Thu, 18 Dec 2008 01:44:08 +0800</pubDate>").append(n);
sb.append(tab).append(tab).append("<language>en</language>").append(n);
sb.append(tab).append(tab).append("<copyright>Copyright 2008, Kevin Tse</copyright>").append(n);
sb.append(tab).append("</channel>").append(n);
sb.append("</rss>");
ps.print(sb.toString());
ps.close();
}
public void addRSSFeedItem(String strFeedItem, int limit)throws Exception {
File file = new File("feed.rss");
if(!file.exists()) createRSSFeedFile();
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
StringBuffer sb = new StringBuffer();
String temp = null;
while((temp = br.readLine()) != null) {
sb.append(temp).append(n);
}
String fileContent = sb.toString();
String newFileContent = "";
Pattern pattern = Pattern.compile("//t*+<item>.*?</item>", Pattern.DOTALL);
Matcher matcher = pattern.matcher(fileContent);
if(matcher.find()) {
newFileContent = matcher.replaceFirst(strFeedItem + matcher.group());
}else {
matcher.usePattern(Pattern.compile("//t*+</channel>"));
matcher.reset(fileContent);
newFileContent = matcher.replaceFirst(strFeedItem + matcher.group());
}
matcher.usePattern(Pattern.compile("//t*+<item>.*?</item>//n", Pattern.DOTALL));
matcher.reset(newFileContent);
int itemCount = 0;
StringBuffer items = new StringBuffer();
while(matcher.find())
if(++itemCount <= limit)
items.append(matcher.group());
matcher.usePattern(Pattern.compile("//t*+<item>.*</item>//n", Pattern.DOTALL));
newFileContent = matcher.replaceFirst(items.toString());
matcher.usePattern(Pattern.compile("<pubDate>(.*)?</pubDate>"));
matcher.reset(newFileContent);
//update pubDate of last feed
Calendar cal = new GregorianCalendar();
Date pubDate = cal.getTime();
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
newFileContent = matcher.replaceFirst("<pubDate>" + dateFormat.format(pubDate) + "</pubDate>");
//regenerate the feed.rss file
FileOutputStream fos = new FileOutputStream(file);
PrintStream ps = new PrintStream(fos, false, "UTF-8");
ps.print(newFileContent);
ps.close();
}
public String createRSSFeedItem(RSSFeedEntry feedEntry) {
StringBuffer sb = new StringBuffer();
sb.append(tab).append(tab).append("<item>").append(n);
sb.append(tab).append(tab).append(tab).append("<title><![CDATA[").append(feedEntry.getTitle()).append("]]></title>").append(n);
sb.append(tab).append(tab).append(tab).append("<description><![CDATA[").append(feedEntry.getDescription()).append("]]></description>").append(n);
sb.append(tab).append(tab).append(tab).append("<link><![CDATA[").append(feedEntry.getLink()).append("]]></link>").append(n);
sb.append(tab).append(tab).append(tab).append("<author><![CDATA[").append(feedEntry.getAuthor()).append("]]></author>").append(n);
sb.append(tab).append(tab).append(tab).append("<guid>").append(feedEntry.getGuid()).append("</guid>").append(n);
sb.append(tab).append(tab).append("</item>").append(n);
return sb.toString();
}
}
package cn.com.kevintse.rss;
public class Test {
public static void main(String[] args) throws Exception{
RSSFeedGenerator g = new RSSFeedGenerator();
RSSFeedEntry rssFeedEntry = new RSSFeedEntry();
rssFeedEntry.setTitle("this is a test");
rssFeedEntry.setDescription("this is description.");
rssFeedEntry.setAuthor("Kevin Tse (kevintse.onjee@gmail.com)");
rssFeedEntry.setGuid("http://url.of.your.blog.entry/");
rssFeedEntry.setLink("http://url.of.your.blog.entry/");
g.addRSSFeedItem(g.createRSSFeedItem(rssFeedEntry), 10);
}
}
RSS是一个标准的XML文件,Rss阅读器可以读取这个XML文件获得文章的信息,使用户可以通过Rss阅读器
而非浏览器阅读Blog