注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

神魔破杜梓的叨叨堂

Programming every day!

 
 
 

日志

 
 
 
 

RSSReader–a simple example of Syndication Library  

2008-08-05 15:02:30|  分类: My Tech |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
原文来自ntt.cc
Problem Summary: Once I want to display a series article of Flex performance from InsideRIA(www.insideria.com) in my blog. I recognized that the amount of the articles is increasing. I should keep the links dynamically. However, I am not the provider of the blog system, so I cannot modify the codes to meet my requirement. Luckily, I can embed SWF in my blog articles. So, I just need to develop a simple RSS reader in SWF format.

Solution Summary: I do not want to parse the RSS myself. It’s a hard work to deal with. I tried to find some open source library of RSS parsing in programmed by action script 3.0. Googled for many, I got the syndication library(http://code.google.com/p/as3syndicationlib/) at last.

Use the syndication library to parse Atom and all versions of RSS easily. This library hides the differences between the formats so you can parse any type of feed without having to know what kind of feed it is.

The detailed information will be found in the project home(http://code.google.com/p/as3syndicationlib/). Then, I started to develop my own RSS reader

Search-256x256 Demo | DownloadDownload Full Project

RSSReader

Codes:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <rssreader>
  3.     <proxy path="http://ntt.cc/ext/proxy.php"/>
  4. </rssreader>

Following is URLLoader.php:

Download: URLLoader.php
  1. <?php
  2. $url = $_GET['FeedURL'];
  3. $html = file_get_contents($url);
  4. print($html);
  5. ?>

Following is RSSReaderConfig.as:

  1. package
  2. {
  3.     import flash.events.Event;
  4.     import flash.events.IOErrorEvent;
  5.     import flash.events.SecurityErrorEvent;
  6.     import flash.net.URLLoader;
  7.     import flash.net.URLRequest;
  8.    
  9.     import mx.managers.ISystemManager;
  10.    
  11.     [Mixin]
  12.     public class RSSReaderConfig
  13.     {
  14.         private static var _proxyPath:String="http://ntt.cc/ext/proxy.php";
  15.        
  16.         public static function get proxyPath():String
  17.         {
  18.             return _proxyPath;
  19.         }
  20.        
  21.         public static var loaded:Boolean = false;
  22.         public static function init(systemManager:ISystemManager):void
  23.         {
  24.             var request:URLRequest = new URLRequest("rssreader-config");
  25.             var loader:URLLoader = new URLLoader();
  26.             loader.addEventListener(Event.COMPLETE,complete);
  27.             loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onSecurityError);
  28.             loader.addEventListener(IOErrorEvent.IO_ERROR,onIOError);
  29.            
  30.             loader.load(request);
  31.         }
  32.        
  33.         private static function complete(event:Event):void
  34.         {
  35.             try
  36.             {
  37.                 var config:XML = XML(event.currentTarget.data);
  38.                 _proxyPath = config.proxy.@path;
  39.                 loaded = true;
  40.             }
  41.             catch(err:Error)
  42.             {
  43.                 loaded = false;   
  44.             }
  45.         }
  46.        
  47.         private static function onIOError(event:Event):void
  48.         {
  49.             trace(event);
  50.         } 
  51.        
  52.         private static function onSecurityError(event:Event):void
  53.         {
  54.             trace(event);
  55.         } 
  56.     }
  57. }

Following is RSSReader.mxml:

Download: RSSReader.mxml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application 
  3.     xmlns:mx="http://www.adobe.com/2006/mxml" 
  4.     layout="absolute"
  5.     creationComplete="initApp();">
  6.     <mx:Style>
  7.         global
  8.         {
  9.             font-size:12;
  10.         }
  11.         ToolTip
  12.         {   
  13.             font-size:12;
  14.         }
  15.     </mx:Style>
  16.     <mx:Script>
  17.         <![CDATA[
  18.             import mx.core.UIComponent;
  19.             import mx.core.FlexSprite;
  20.             import mx.controls.Alert;
  21.             import mx.core.ByteArrayAsset;
  22.             import mx.managers.CursorManager;
  23.             import mx.utils.StringUtil;
  24.             import mx.utils.URLUtil;
  25.             import mx.utils.XMLUtil;
  26.            
  27.             import flash.net.navigateToURL;
  28.            
  29.             import com.adobe.xml.syndication.generic.Excerpt;           
  30.             import com.adobe.xml.syndication.generic.IFeed;           
  31.             import com.adobe.xml.syndication.generic.FeedFactory;
  32.            
  33.             [Bindable]
  34.             private var feedURL:String = "http://blogs.oreilly.com/cgi-bin/mt/mt-search.cgi?search=Flex%20RIA%20Performance%20Considerations&Template=feed&IncludeBlogs=34";
  35.        
  36.             [Bindable]
  37.             private var feeds:IFeed;
  38.            
  39.             private function initApp():void
  40.             {
  41.                 Security.allowDomain("*");
  42.                 var uic:UIComponent = new UIComponent();
  43.                 trace(uic.eventListeners);
  44.                 if(parameters.FeedURL!=null)
  45.                 {
  46.                     feedURL = parameters.FeedURL;
  47.                 }
  48.  
  49.                 fetchEntries();
  50.             }
  51.            
  52.             private function fetchEntries():void
  53.             {
  54.                 // we should check the url here
  55.                 if(feedUrl.text == "")
  56.                 {
  57.                     return;
  58.                 }
  59.                 else
  60.                 {
  61.                     feedURL = feedUrl.text;
  62.                 }
  63.                
  64.                 var uri:String = encodeURIComponent(feedURL);
  65.  
  66.                 uri = RSSReaderConfig.proxyPath +"?FeedURL="+uri;
  67.                
  68.                    
  69.                 var request:URLRequest = new URLRequest(uri);
  70.                 var loader:URLLoader = new URLLoader();
  71.                 loader.addEventListener(Event.COMPLETE,onLoad);
  72.                 loader.addEventListener(IOErrorEvent.IO_ERROR,onIOError);
  73.                 loader.dataFormat = URLLoaderDataFormat.BINARY;
  74.                 loader.load(request);
  75.                
  76.                 CursorManager.setBusyCursor();
  77.             }
  78.            
  79.             private function onLoad(event:Event):void
  80.             {
  81.                 var result:ByteArray = event.currentTarget.data;
  82.                 try{
  83.                     feeds = FeedFactory.getFeedByString(result.readMultiByte(result.length,"gb2312"));   
  84.                 }
  85.                 catch(error:Error)
  86.                 {
  87.                     Alert.show("Encounter an unknown error, please confirm your rss source url","Error");
  88.                     CursorManager.removeBusyCursor();
  89.                     return;
  90.                 }
  91.                 if(!feeds)
  92.                 {
  93.                     Alert.show("Cannot get feeds from the specified url","Error");
  94.                     CursorManager.removeBusyCursor();
  95.                     return ;
  96.                 }
  97.                 entries.dataProvider = feeds.items;
  98.                 CursorManager.removeBusyCursor();
  99.             }
  100.            
  101.             private function onIOError(event:IOErrorEvent):void
  102.             {
  103.                 trace(event);
  104.             }
  105.         ]]>
  106.     </mx:Script>
  107.     <mx:Panel title="rss reader" layout="vertical" width="100%" height="100%">
  108.         <mx:HBox width="100%">
  109.             <mx:Label text="URL"/>
  110.             <mx:TextInput id="feedUrl" text="{feedURL}" width="50%"/>
  111.             <mx:Button label="Fetch" click="fetchEntries()"/>
  112.         </mx:HBox>
  113.         <mx:HRule width="100%" height="2" visible="{feeds.metadata.authors!=null}"/>
  114.         <mx:HBox width="100%" verticalAlign="middle">
  115.             <mx:Repeater id="metadataAuthors" dataProvider="{feeds.metadata.authors}">
  116.                 <mx:LinkButton>
  117.                     <mx:click>
  118.                         <![CDATA[
  119.                             var dataItem:Object = event.currentTarget.repeater.dataProvider[event.currentTarget.repeaterIndex];
  120.                             if(dataItem.url)
  121.                             {
  122.                                 try
  123.                                 {
  124.                                     navigateToURL( new URLRequest(dataItem.link),'_blank');
  125.                                 }
  126.                                 catch(err:Error)
  127.                                 {
  128.                                     System.setClipboard(dataItem.link);
  129.                                     Alert.show("Security box error. the link url has been copied to your clipboard. paste the url into the browser's location bar, then go to the address");
  130.                                 }
  131.                             }
  132.                         ]]>
  133.                     </mx:click>
  134.                     <mx:label>
  135.                         {metadataAuthors.currentItem.name!=null?metadataAuthors.currentItem.name:metadataAuthors.currentItem.email}
  136.                     </mx:label>
  137.                 </mx:LinkButton>
  138.             </mx:Repeater>
  139.             <mx:Image 
  140.                 toolTip="{feeds.metadata.image.title}" 
  141.                 visible="{feeds.metadata.image!=null}" 
  142.                 source="{feeds.metadata.image.url}"
  143.                 buttonMode="true"
  144.                 mouseChildren="false">
  145.                 <mx:click>
  146.                     <![CDATA[
  147.                         if(feeds.metadata.image.link)
  148.                         {
  149.                             try
  150.                             {
  151.                                 navigateToURL( new URLRequest(feeds.metadata.image.link),'_blank');
  152.                             }
  153.                             catch(err:Error)
  154.                             {
  155.                                 System.setClipboard(feeds.metadata.image.link);
  156.                                 Alert.show("Security box error. the link url has been copied to your clipboard. paste the url into the browser's location bar, then go to the address");
  157.                             }
  158.                         }
  159.                     ]]>
  160.                 </mx:click>
  161.             </mx:Image>
  162.         </mx:HBox>
  163.         <mx:Label text="Entries"/>
  164.         <mx:HRule width="100%" height="1"/>
  165.         <mx:VBox width="100%" height="100%">
  166.             <mx:Repeater id="entries" width="100%" height="100%">
  167.                     <mx:LinkButton 
  168.                         label="{entries.currentItem.title}" 
  169.                         fontSize="14" fontWeight="bold">
  170.                         <mx:click>
  171.                             <![CDATA[
  172.                                 var dataItem:Object = event.currentTarget.repeater.dataProvider[event.currentTarget.repeaterIndex];
  173.                                 if(dataItem.link)
  174.                                 {
  175.                                     try
  176.                                     {
  177.                                         navigateToURL( new URLRequest(dataItem.link),'_blank');
  178.                                     }
  179.                                     catch(err:Error)
  180.                                     {
  181.                                         System.setClipboard(dataItem.link);
  182.                                         Alert.show("Security box error. the link url has been copied to your clipboard. paste the url into the browser's location bar, then go to the address");
  183.                                     }
  184.                                 }
  185.                             ]]>
  186.                         </mx:click>
  187.                     </mx:LinkButton>
  188.                     <mx:Repeater id="authors"  dataProvider="{entries.currentItem.authors}">
  189.                         <mx:LinkButton 
  190.                             fontWeight="normal"
  191.                             fontSize="12"
  192.                             label="{authors.currentItem.name!=null?authors.currentItem.name:authors.currentItem.email}">
  193.                             <mx:click>
  194.                                 <![CDATA[
  195.                                     var dataItem:Object = event.currentTarget.repeater.dataProvider[event.currentTarget.repeaterIndex];
  196.                                     if(dataItem.url)
  197.                                     {
  198.                                         try
  199.                                         {
  200.                                             navigateToURL( new URLRequest(dataItem.url),'_blank');
  201.                                         }
  202.                                         catch(err:Error)
  203.                                         {
  204.                                             System.setClipboard(dataItem.url);
  205.                                             Alert.show("Security box error. the link url has been copied to your clipboard. paste the url into the browser's location bar, then go to the address");
  206.                                         }                                       
  207.                                     }
  208.                                 ]]>
  209.                             </mx:click>
  210.                         </mx:LinkButton>
  211.                     </mx:Repeater>                   
  212.             </mx:Repeater>
  213.         </mx:VBox>
  214.     </mx:Panel>
  215. </mx:Application>

Description: During the development process of my simple RSS reader, I meet a problem raised by flash player security sand box. For example, the domain of my blog is www.mydomain.com, the domain of another blog is www.otherdomain.com. If the SWF embed in my blog wants to access the data from www.otherdomain.com, the www.otherdomain.com must grant the related permission to www.mydomain.com. However, I cannot control the permission of www.otherdomain.com. So I need a server to store my SWF file。Suppose the domain of the server is www.server.com.The SWF will load the data from www.otherdomain.com by a HTTP request from www.server.com. For the SWF and the data request are from the same domain, there will be no security sand box issue.

The “proxy” defined in the file rssreader-config is the server referred to above. “Path” is the server-side service with which the SWF stored in the server is able to access data from any web sites without security sandbox issue.

  1. <proxy path=”http://ntt.cc/ext/proxy.php”/>

The class RSSReaderConfig is used to load RSSReader configuration settings into the SWF, such as RSSReaderConfig.proxyPath will return the attribute “path” of the “proxy” tag defined in file rssreader-config.

Pay attention to the class metadata tag “mixin”. With this tag, the init function will be executed automatically to initialize class RSSReaderConfig.

The usage of Syndication library is quite easy. FeedFactory provides us a general way to parse a feed, in ATOM format or RSS, because of all the class implemented the interface IFeed.

FeedFactory.getFeedByString(result.readMultiByte(result.length,“gb2312″));

As the codes above, getFeedByString returns an instance implemented IFeed interface. I am a Chinese, “gb2312” is used to make sure the content loaded correct.

At last, the detailed definition of IFeed and other classes or interfaces lists in the distributed documentation of Syndication library, which is contained in a compressed package you will get from the project home(http://code.google.com/p/as3syndicationlib/).


  评论这张
 
阅读(520)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017