http://hi.baidu.com/ccyingfu/blog/item/52374116afcf1a12962b4323.html
五:选择ROME作为RSS实现工具
在官网 http://wiki.java.net/bin/view/Javawsxml/Rome下载rome-0.8.jar, rome用到了jdom1.0,下载地址:http://www.jdom.org rome支持:rss_0.9 rss_0.91 rss_0.92 rss_0.93 rss_0.94 rss_1.0 rss_2.0 atom_0.3 atom_1.0 生成RSS类新需要在程序中指定,如:rss_2.0 六:包结构 com.sun.syndication.feed 提供RSS and Atom beans的父类 com.sun.syndication.feed.atom 提供实现Atom feeds核心元素的beans com.sun.syndication.feed.module 提供处理聚合modules的beans com.sun.syndication.feed.rss 提供实现Rss feeds核心元素的beans com.sun.syndication.feed.synd 我们主要用的就是这个包,SyndFeed and SyndEntryImpl com.sun.syndication.io 提供对读取和分析feeds的输入和输出 七:实例: 1:读取远端url的rss,然后输出到控制台: /** * 关键代码: * SyndFeedInput input = new SyndFeedInput(); * SyndFeed feed = input.build(new XmlReader(feedUrl)); */ package com.sun.syndication.samples; import com.sun.syndication.feed.synd.SyndFeed; import com.sun.syndication.io.SyndFeedInput; import com.sun.syndication.io.XmlReader; import java.net.URL; /** * It Reads and prints any RSS/Atom feed type. */ public class FeedReader { public static void main(String[] args) { boolean ok = false; if (args.length==0) { try { URL feedUrl = new URL(" http://seu.org.cn/bbs/rss.php"); //SyndFeedInput:从远程读到xml结构的内容转成SyndFeedImpl实例 SyndFeedInput input = new SyndFeedInput(); //rome按SyndFeed类型生成rss和atom的实例, //SyndFeed是rss和atom实现类SyndFeedImpl的接口 SyndFeed feed = input.build(new XmlReader(feedUrl)); //打印到控制台 System.out.println(feed); ok = true; } catch (Exception ex) { ex.printStackTrace(); System.out.println("ERROR: "+ex.getMessage()); } } if (!ok) { System.out.println(); System.out.println("FeedReader reads and prints any RSS/Atom feed type."); System.out.println("The first parameter must be the URL of the feed to read."); System.out.println(); } } } 2:将多个远程RSS在本地聚集成一个RSS package com.sun.syndication.samples; import java.net.URL; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.List; import java.util.ArrayList; import com.sun.syndication.feed.synd.SyndFeed; import com.sun.syndication.feed.synd.SyndFeedImpl; import com.sun.syndication.io.SyndFeedOutput; import com.sun.syndication.io.SyndFeedInput; import com.sun.syndication.io.XmlReader; /** * It aggregates a list of RSS/Atom feeds (they can be of different types) * into a single feed of the specified type. * <p> * @author Alejandro Abdelnur * */ public class FeedAggregator { public static void main(String[] args) { boolean ok = false; if (args.length>=2) { try { String outputType = args[0]; SyndFeed feed = new SyndFeedImpl(); feed.setFeedType(outputType); feed.setTitle("Aggregated Feed"); feed.setDescription("Anonymous Aggregated Feed"); feed.setAuthor("anonymous"); feed.setLink(" http://www.anonymous.com"); List entries = new ArrayList(); feed.setEntries(entries); for (int i=1;i<args.length;i++) { URL inputUrl = new URL(args ); SyndFeedInput input = new SyndFeedInput(); SyndFeed inFeed = input.build(new XmlReader(inputUrl)); entries.addAll(inFeed.getEntries()); } SyndFeedOutput output = new SyndFeedOutput(); output.output(feed,new PrintWriter(System.out)); ok = true; } catch (Exception ex) { System.out.println("ERROR: "+ex.getMessage()); } } if (!ok) { System.out.println(); System.out.println("FeedAggregator aggregates different feeds into a single one."); System.out.println("The first parameter must be the feed type for the aggregated feed."); System.out.println(" [valid values are: rss_0.9, rss_0.91U, rss_0.91N, rss_0.92, rss_0.93, ]"); System.out.println(" [ rss_0.94, rss_1.0, rss_2.0 & atom_0.3 ]"); System.out.println("The second to last parameters are the URLs of feeds to aggregate."); System.out.println(); } } } 3:将动态生成的RSS存盘,形成静态RSS package com.sun.syndication.samples; import com.sun.syndication.feed.synd.*; import com.sun.syndication.io.SyndFeedOutput; import java.io.FileWriter; import java.io.Writer; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; /** * It creates a feed and writes it to a file. * <p> * @author Alejandro Abdelnur * */ public class FeedWriter { private static final String DATE_FORMAT = "yyyy-MM-dd"; public static void main(String[] args) { boolean ok = false; if (args.length==0) { try { String feedType = "rss_2.0";//指定rss类型 String fileName = "F:\\ss.xml";//静态rss存放目录 DateFormat dateParser = new SimpleDateFormat(DATE_FORMAT); //feed是通过SyndFeedImpl的实例 SyndFeed feed = new SyndFeedImpl(); feed.setFeedType(feedType); feed.setTitle("Sample Feed (created with Rome)"); feed.setLink("http://rome.dev.java.net"); feed.setDescription("This feed has been created using Rome (Java syndication utilities"); //entries就是item集合 List entries = new ArrayList(); //一个entry就是一个item SyndEntry entry; SyndContent description; //第一个item entry = new SyndEntryImpl(); entry.setTitle("Rome v1.0"); entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome01"); entry.setPublishedDate(dateParser.parse("2004-06-08")); description = new SyndContentImpl(); description.setType("text/plain"); description.setValue("Initial release of Rome"); entry.setDescription(description); entries.add(entry); //第二个item entry = new SyndEntryImpl(); entry.setTitle("Rome v2.0"); entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome02"); entry.setPublishedDate(dateParser.parse("2004-06-16")); description = new SyndContentImpl(); description.setType("text/xml"); description.setValue("Bug fixes, <xml>XML</xml> minor API changes and some new features"); entry.setDescription(description); entries.add(entry); //第三个item entry = new SyndEntryImpl(); entry.setTitle("Rome v3.0"); entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome03"); entry.setPublishedDate(dateParser.parse("2004-07-27")); description = new SyndContentImpl(); description.setType("text/html"); description.setValue("<p>More Bug fixes, mor API changes, some new features and some Unit testing</p>"+ "<p>For details check the <a href=\"Changes'>http://wiki.java.net/bin/view/Javawsxml/RomeChangesLog#RomeV03\">Changes Log</a></p>"); entry.setDescription(description); //将所有item存入entries entries.add(entry); //将entries加入channel feed.setEntries(entries); Writer writer = new FileWriter(fileName); SyndFeedOutput output = new SyndFeedOutput(); //存盘,形成静态rss output.output(feed,writer); writer.close(); System.out.println("The feed has been written to the file ["+fileName+"]"); System.out.println(feed); ok = true; } catch (Exception ex) { ex.printStackTrace(); System.out.println("ERROR: "+ex.getMessage()); } } if (!ok) { System.out.println(); System.out.println("FeedWriter creates a RSS/Atom feed and writes it to a file."); System.out.println("The first parameter must be the syndication format for the feed"); System.out.println(" (rss_0.90, rss_0.91, rss_0.92, rss_0.93, rss_0.94, rss_1.0 rss_2.0 or atom_0.3)"); System.out.println("The second parameter must be the file name for the feed"); System.out.println(); } } } 4:动态生成rss,给一个blog站点动态生成rss package com.vaga.rss.web.admin; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.ParameterizableViewController; import com.sun.syndication.feed.synd.SyndContent; import com.sun.syndication.feed.synd.SyndContentImpl; import com.sun.syndication.feed.synd.SyndEntry; import com.sun.syndication.feed.synd.SyndEntryImpl; import com.sun.syndication.feed.synd.SyndFeed; import com.sun.syndication.feed.synd.SyndFeedImpl; import com.sun.syndication.io.FeedException; import com.sun.syndication.io.SyndFeedOutput; import com.sun.syndication.feed.synd.SyndContent; import com.sun.syndication.feed.synd.SyndEntry; import com.totsp.xml.syndication.content.ContentModule; import com.vaga.blog.model.WeblogEntry; import com.vaga.blog.model.Website; import com.vaga.blog.service.WeblogEntryManager; import com.vaga.blog.service.WebsiteManager; public class SiteRssViewController extends ParameterizableViewController { // Constants /** Namespace URI for content:encoded elements */ private static final String CONTENT_NS ="http://purl.org/rss/1.0/modules/content/"; private static final String FEED_TYPE = "type"; private static final String MIME_TYPE = "application/xml; charset=UTF-8"; private static final String COULD_NOT_GENERATE_FEED_ERROR = "Could not generate feed"; private static final String _defaultFeedType="rss_2.0"; private static final String DATE_FORMAT = "yyyy-MM-dd"; //controller starts private WeblogEntryManager weblogEntryManager;//spring依赖注入 private WebsiteManager websiteManager; //spring依赖注入 //spring依赖注入 public void setWeblogEntryManager(WeblogEntryManager weblogEntryManager) { this.weblogEntryManager = weblogEntryManager; } //spring依赖注入 public void setWebsiteManager(WebsiteManager websiteManager) { this.websiteManager = websiteManager; } protected ModelAndView handleRequestInternal(HttpServletRequest request,HttpServletResponse response) throws Exception { try { SyndFeed feed = getFeed(request); String feedType = request.getParameter(FEED_TYPE);//null feedType = (feedType!=null) ? feedType : _defaultFeedType; feed.setFeedType(feedType);//rss_2.0 response.setContentType(MIME_TYPE); SyndFeedOutput output = new SyndFeedOutput(); output.output(feed,response.getWriter());//向发出请求的用户输出该RSS(xml格式) } catch (FeedException ex) { String msg = COULD_NOT_GENERATE_FEED_ERROR; log(msg,ex); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,msg); } return null; } /** * 请求的类型如下: * siteRss.htm?websiteId=21 |ID=66的个人站点最新20条文章 * siteRss.htm?websiteId=21&entryType=hot |ID=66的个人站点最热20条文章 * * @param request */ protected SyndFeed getFeed(HttpServletRequest request) throws IOException,FeedException { DateFormat dateParser = new SimpleDateFormat(DATE_FORMAT); //feed就是channel SyndFeed feed = new SyndFeedImpl(); //item集合 List entries = new ArrayList(); //一个entry就是代表一个item SyndEntry entry; SyndContent description; setFeed(request,feed); Iterator iterator = setIterator(request); //将文章的20记录转成20个item while(iterator.hasNext()){ entry = new SyndEntryImpl(); WeblogEntry weblogEntry = (WeblogEntry)iterator.next(); entry.setTitle(weblogEntry.getTitle()); entry.setLink(feed.getLink()+"?weblogEntryId="+weblogEntry.getId()); try { entry.setPublishedDate(dateParser.parse(weblogEntry.getPubTime().toString())); } catch (ParseException ex) { ex.printStackTrace(); } //该item的description description = new SyndContentImpl(); description.setType("text/plain"); String text=null; if(weblogEntry.getText().length()>500){ text = weblogEntry.getText().substring(0, 500); }else{ text = weblogEntry.getText(); } description.setValue(text); entry.setDescription(description); addFooter(entry); entries.add(entry); } //将所有的item存入channel feed.setEntries(entries); return feed; } private SyndFeed setFeed(HttpServletRequest request,SyndFeed feed){ //blog中的website Website website = websiteManager.getWebsite(request.getParameter("websiteId")); 设置当前website的channel属性 feed.setTitle(website.getName()); feed.setAuthor(website.getCreator()); feed.setCopyright(website.getEmailAddress()); feed.setLink("http://wxz.vaga.com.cn:8080/blog/weblog/"+website.getHandle()); feed.setDescription(website.getDescription()); return feed; } //从数据库中获得20条该website的文章 private Iterator setIterator(HttpServletRequest request){ if(request.getParameter("entryType")==null){ return weblogEntryManager.getRecentWeblogEntriesForRss(request.getParameter("websiteId"), null, "PUBLISHED", 21).iterator(); }else{ return weblogEntryManager.getHotWeblogEntriesForRss(request.getParameter("websiteId"), null, 21).iterator(); } } /** * Add footer to an entry.给每个文章摘要添加页脚 * @param entry */ public static void addFooter(SyndEntry entry) { // Prep variables used in loops String title = entry.getTitle(); String link = entry.getLink(); // Use the add-on ContentModule to handle // <content:encoded/> elments within the feed ContentModule module =((ContentModule) entry.getModule(CONTENT_NS)); // If content:encoded is found, use that. if(module!=null) { // Container for footer-appended HTML strings List newStringList = new ArrayList(); // Iterate through encoded HTML, creating footers Iterator oldStringIter =module.getEncodeds().iterator(); while (oldStringIter.hasNext()) { String original = (String) oldStringIter.next(); newStringList.add(createFooter(original,link, title)); } // Set new encoded HTML strings on entry module.setEncodeds(newStringList); } else { // Fall back to adding footer in <description/> // This results in escaped HTML. Ugly, but common. //Target the description node SyndContent content = entry.getDescription(); // Create and set a footer-appended description String original = content.getValue(); content.setValue(createFooter(original,link, title)); } } /** * Create a feed item footer of immediate actions * by using information from the feed item itself * @param original The original text of the feed item * @param link The link for the feed item * @param title The title of the feed item * @return */ private static String createFooter(String original, String link,String title) { // Use StringBuffer to create a sb StringBuffer sb; if(original==null){ sb=new StringBuffer("<br />"); }else{ sb= new StringBuffer(original); } sb.append("\n\n<div class='feedwarmer'><hr/>"); sb.append("<i>相关操作:</i> "); // Add email link using title and item link sb.append("<a href='mailto:?body=Check this out: "); sb.append(link).append("'>推荐该链接</a> | "); // Add delicious link using item title link sb.append("<a href='http://del.icio.us/post/?url="); sb.append(link).append("&title=").append(title); sb.append("'>添加到delicious</a> | "); // Add Google Blogs Search link using item title sb.append("<a href='http://blogsearch.google.com/"); sb.append("blogsearch?hl=en&q=").append(title); sb.append("'>搜索相关内容</a>"); // Finish and return the sb sb.append("</div>\n"); return sb.toString(); } } |