備注學院

          LuLu

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            5 隨筆 :: 50 文章 :: 16 評論 :: 0 Trackbacks

          WebWork的result實現非常實用,它很好的解決了View渲染的靈活性問題。這才是MVC模式的優勢所在,而像JSF那樣幫定JSP的MVC就吃不到這個甜頭了。說WebWork2是Model 2 MVC的巔峰就在這些靈活的地方。
          閑扯這個不是主要目的。現在Rome是Java下最常用的RSS包,最近消息似乎要轉入Apache的Abdera合并變成更強大的聚合引擎。用Rome生成和解析RSS都很方便。今天討論一下使用ROME給網站生成RSS,并通過WebWork2的Result機制渲染。
          最初是從WebWork的Cookbook上看到的RomeResult的文章,一看就會,我這里其實不過是舉個詳細點的例子,注意我使用的是WebWork 2.2.2Rome 0.8
          http://wiki.opensymphony.com/display/WW/RomeResult
          參考了和東的這篇Blog,利用rome寫rss feed生成程序:
          http://hedong.3322.org/newblog/archives/000051.html

          首先創建RomeResult類:

          代碼
          1. /**  
          2.  *   
          3.  */  
          4. package com.goldnet.framework.webwork.result;   
          5.   
          6. import java.io.Writer;   
          7.   
          8. import org.apache.log4j.Logger;   
          9.   
          10. import com.opensymphony.webwork.ServletActionContext;   
          11. import com.opensymphony.xwork.ActionInvocation;   
          12. import com.opensymphony.xwork.Result;   
          13. import com.sun.syndication.feed.synd.SyndFeed;   
          14. import com.sun.syndication.io.SyndFeedOutput;   
          15.   
          16. /**  
          17.  * A simple Result to output a Rome SyndFeed object into a newsfeed.  
          18.  * @author Philip Luppens  
          19.  *   
          20.  */  
          21. public class RomeResult implements Result {   
          22.     private static final long serialVersionUID = -6089389751322858939L;   
          23.   
          24.     private String feedName;   
          25.   
          26.     private String feedType;   
          27.   
          28.     private final static Logger logger = Logger.getLogger(RomeResult.class);   
          29.   
          30.     /*  
          31.      * (non-Javadoc)  
          32.      *   
          33.      * @see com.opensymphony.xwork.Result#execute(com.opensymphony.xwork.ActionInvocation)  
          34.      */  
          35.     public void execute(ActionInvocation ai) throws Exception {   
          36.         if (feedName == null) {   
          37.             // ack, we need this to find the feed on the stack   
          38.             logger   
          39.                     .error("Required parameter 'feedName' not found. "  
          40.                             + "Make sure you have the param tag set and "  
          41.                             + "the static-parameters interceptor enabled in your interceptor stack.");   
          42.             // no point in continuing ..   
          43.             return;   
          44.         }   
          45.   
          46.         // don't forget to set the content to the correct mimetype   
          47.         ServletActionContext.getResponse().setContentType("text/xml");   
          48.         // get the feed from the stack that can be found by the feedName   
          49.         SyndFeed feed = (SyndFeed) ai.getStack().findValue(feedName);   
          50.   
          51.         if (logger.isDebugEnabled()) {   
          52.             logger.debug("Found object on stack with name '" + feedName + "': "  
          53.                     + feed);   
          54.         }   
          55.         if (feed != null) {   
          56.   
          57.             if (feedType != null) {   
          58.                 // Accepted types are: rss_0.90 - rss_2.0 and atom_0.3   
          59.                 // There is a bug though in the rss 2.0 generator when it checks   
          60.                 // for the type attribute in the description element. It's has a   
          61.                 // big 'FIXME' next to it (v. 0.7beta).   
          62.                 feed.setFeedType(feedType);   
          63.             }   
          64.             SyndFeedOutput output = new SyndFeedOutput();   
          65.             //we'll need the writer since Rome doesn't support writing to an outputStream yet   
          66.             Writer out = null;   
          67.             try {   
          68.                 out = ServletActionContext.getResponse().getWriter();   
          69.                 output.output(feed, out);   
          70.             } catch (Exception e) {   
          71.                 // Woops, couldn't write the feed ?   
          72.                 logger.error("Could not write the feed", e);   
          73.             } finally {   
          74.                 //close the output writer (will flush automatically)   
          75.                 if (out != null) {   
          76.                     out.close();   
          77.                 }   
          78.             }   
          79.   
          80.         } else {   
          81.             // woops .. no object found on the stack with that name ?   
          82.             logger.error("Did not find object on stack with name '" + feedName   
          83.                     + "'");   
          84.         }   
          85.     }   
          86.   
          87.     public void setFeedName(String feedName) {   
          88.         this.feedName = feedName;   
          89.     }   
          90.   
          91.     public void setFeedType(String feedType) {   
          92.         this.feedType = feedType;   
          93.     }   
          94.   
          95. }  

           

          程序很簡單。實現了Result接口,尋找一個與feedName參數匹配的SyndFeed實例,然后轉換為指定的feedType類型,然后通過rome的SyndFeedOutput輸出到Response去。
          然后我們給我們的WebWork配置romeResult。
          在xwork.xml中配置:

          代碼
          1. <package name="default" extends="webwork-default">  
          2.         <result-types>  
          3.             <result-type name="feed" class="com.goldnet.framework.webwork.result.RomeResult"/>  
          4.         </result-types>  
          5.         <interceptors>  
          6.         <!-- 然后是你的那些inteceptor配置等 -->  
          這樣我們就給xwork配置了一個叫做feed的result,它就是我們的romeResult。
          然后我們實現一個類,來測試一下這個romeResult。
          代碼
          1. /**   
          2.  *   
          3.  */   
          4. package com.goldnet.webwork.action.news;   
          5.   
          6. import com.opensymphony.xwork.ActionSupport;   
          7.   
          8. import com.sun.syndication.feed.synd.SyndCategory;   
          9. import com.sun.syndication.feed.synd.SyndCategoryImpl;   
          10. import com.sun.syndication.feed.synd.SyndContent;   
          11. import com.sun.syndication.feed.synd.SyndContentImpl;   
          12. import com.sun.syndication.feed.synd.SyndEntry;   
          13. import com.sun.syndication.feed.synd.SyndEntryImpl;   
          14. import com.sun.syndication.feed.synd.SyndFeed;   
          15. import com.sun.syndication.feed.synd.SyndFeedImpl;   
          16.   
          17. import org.apache.commons.logging.Log;   
          18. import org.apache.commons.logging.LogFactory;   
          19.   
          20. import java.util.ArrayList;   
          21. import java.util.Date;   
          22. import java.util.List;   
          23.   
          24. /**   
          25.  * @author Tin   
          26.  *   
          27.  */   
          28. public class TestFeedCreateAction extends ActionSupport {   
          29.     private static final long serialVersionUID = -2207516408313865979L;   
          30.     private transient final Log log = LogFactory.getLog(TestFeedCreateAction.class);   
          31.     private int maxEntryNumber = 25;   
          32.     private String siteUrl = "http://127.0.0.1";   
          33.     private SyndFeed feed = null;   
          34.   
          35.     public TestFeedCreateAction() {   
          36.         super();   
          37.     }   
          38.   
          39.     @Override   
          40.     public String execute() {   
          41.         List<News> newsList = getNewsList();   
          42.   
          43.         if (log.isDebugEnabled()) {   
          44.             log.debug("Geting feed! and got news " + newsList.size() +   
          45.                 " pieces.");   
          46.         }   
          47.   
          48.         feed = new SyndFeedImpl();   
          49.   
          50.         feed.setTitle(converttoISO("測試中的新聞系統"));   
          51.         feed.setDescription(converttoISO("測試中的新聞系統:測試Rome Result"));   
          52.         feed.setAuthor(converttoISO("測試Tin"));   
          53.         feed.setLink("http://www.justatest.cn");   
          54.   
          55.         List<SyndEntry> entries = new ArrayList<SyndEntry>();   
          56.         feed.setEntries(entries);   
          57.   
          58.         for (News news : newsList) {   
          59.             SyndEntry entry = new SyndEntryImpl();   
          60.             entry.setAuthor(converttoISO(news.getAuthor()));   
          61.   
          62.             SyndCategory cat = new SyndCategoryImpl();   
          63.             cat.setName(converttoISO(news.getCategory()));   
          64.   
          65.             List<SyndCategory> cats = new ArrayList<SyndCategory>();   
          66.             cats.add(cat);   
          67.             entry.setCategories(cats);   
          68.   
          69.             SyndContent content = new SyndContentImpl();   
          70.             content.setValue(converttoISO(news.getContent()));   
          71.   
          72.             List<SyndContent> contents = new ArrayList<SyndContent>();   
          73.             contents.add(content);   
          74.             entry.setContents(contents);   
          75.             entry.setDescription(content);   
          76.             entry.setLink(siteUrl + "/common/news/displayNews.action?id=" +   
          77.                 news.getId());   
          78.             entry.setTitle(converttoISO(news.getTitle()));   
          79.             entry.setPublishedDate(news.getPublishDate());   
          80.             entries.add(entry);   
          81.         }   
          82.   
          83.         return SUCCESS;   
          84.     }   
          85.   
          86.     private static String converttoISO(String s) {   
          87.         try {   
          88.             byte[] abyte0 = s.getBytes("UTF-8");   
          89.   
          90.             return new String(abyte0, "ISO-8859-1");   
          91.         } catch (Exception exception) {   
          92.             return s;   
          93.         }   
          94.     }   
          95.   
          96.     private List<News> getNewsList() {   
          97.         List<News> newnewsList = new ArrayList<News>();   
          98.   
          99.         for (int i = 0; i < maxEntryNumber; i++) {   
          100.             News newnews = new News();   
          101.             news.setTitle("測試標題" + i);   
          102.             news.setContent(   
          103.                 "<p>測試內容測試內容<span style=\"color:red\">測試內容</span></p>");   
          104.             news.setPublishDate(new Date());   
          105.             news.setId(new Long(i));   
          106.             news.setAuthor("Tin");   
          107.             newsList.add(news);   
          108.         }   
          109.   
          110.         return newsList;   
          111.     }   
          112.   
          113.     /**   
          114.      * @return Returns the maxEntryNumber.   
          115.      */   
          116.     public long getMaxEntryNumber() {   
          117.         return maxEntryNumber;   
          118.     }   
          119.   
          120.     /**   
          121.      * @param maxEntryNumber The maxEntryNumber to set.   
          122.      */   
          123.     public void setMaxEntryNumber(int maxEntryNumber) {   
          124.         this.maxEntryNumber = maxEntryNumber;   
          125.     }   
          126.   
          127.     /**   
          128.      * @param siteUrl The siteUrl to set.   
          129.      */   
          130.     public void setSiteUrl(String siteUrl) {   
          131.         this.siteUrl = siteUrl;   
          132.     }   
          133.   
          134.     /**   
          135.      * @return Returns the feed.   
          136.      */   
          137.     public SyndFeed getFeed() {   
          138.         return feed;   
          139.     }   
          140.   
          141.     private class News {   
          142.         private Long id;   
          143.         private String title;   
          144.         private String content;   
          145.         private Date publishDate;   
          146.         private String author;   
          147.         private String category;   
          148.   
          149.         /**   
          150.      * Getter/Setter都省略了,使用了內部類,就是圖個方便   
          151.      * 本意是模仿我們常常使用的Pojo,大家的實現都不一樣,我突簡單,里面其實可以有復雜類型的     
          152.   
          153. */   
          154.     }   
          155. }  

           

          真是不好意思,Getter/Setter占了大部分地方我省略去了。邏輯很簡單,就是把我們的POJO影射到Feed的模型上面,過程很簡單。我留下了幾個參數可以在外面設置:
          maxEntryNumber顯示的feed的條數,鏈接生成時使用的SiteUrl,當然也可以通過request獲取。
          下面我們配置我們的Action,注意平時我們可能使用DAO生成newsList,而不是我這個寫死的getNewsList()方法,此時可能需要配合Spring進行IOC的設置,我們這里省略掉。
          下面是我們這個Action的xwork配置:

          代碼
          1. <package name="news" extends="default" namespace="/news">  
          2.         <action name="feed" class="com.goldnet.webwork.action.news.TestFeedCreateAction">  
          3.             <!-- 每次生成15條rss feed -->  
          4.             <param name="maxEntryNumber">15</param>  
          5.             <!-- 鏈接的前綴,我們使用Weblogic是7001,也許你的是8080 -->  
          6.             <param name="siteUrl">http://127.0.0.1:7001</param>  
          7.             <!-- result是feed -->  
          8.             <result name="success" type="feed">  
          9.                 <!-- feed名字是feed,對應我們這個Action中的那個SyndFeed的實例的名字feed,別忘記寫getter -->  
          10.                 <param name="feedName">feed</param>  
          11.                 <!-- 制定生成的feed的類型,我這里選擇rss_2.0 -->  
          12.                 <!-- rome 0.8支持atom_0.3、atom_1.0、rss_1.0、rss_2.0、rss_0.90、rss_0.91、rss_0.91、rss_0.91U、rss_0.92、rss_0.93、rss_0.94 -->  
          13.                 <param name="feedType">rss_2.0</param>  
          14.             </result>  
          15.         </action>  
          16. </package>  

          OK,配置完畢后訪問/news/feed.action就可以訪問到這個feed了。倒入你的feedDeamon,看看,是不是非常簡單?
          不過需要考慮兩個地方,一個是編碼問題,看了和東說的中文問題,本沒當回事,結果生成亂碼(我們項目全部使用UTF-8),然后還是轉了一下。沒有研究ROME源代碼,感覺xml不應該有UTF-8還會亂碼的問題呀,也許還需要看看是否是設置不到位。還有就是對于feed如果增加了權限認證則訪問比較麻煩,用feedDeamon這樣的客戶端就無法訪問到了,因為它不會顯示登陸失敗后顯示的登陸頁面,也許放feed就要開放一點吧(當然還是有變通放案的)。
          和動例子里面的rome 0.7和現在的rome 0.8相比,Api已經發生了不少變化,唉,開源要代碼穩定還真難。
          就這些,就到這里,粗陋了:D

          摘自:http://www.javaeye.com/post/125096
          posted on 2007-11-18 12:08 smildlzj 閱讀(282) 評論(0)  編輯  收藏 所屬分類: Web開發
          主站蜘蛛池模板: 灵台县| 磴口县| 平塘县| 乡城县| 枣强县| 武宣县| 营山县| 洛南县| 镇安县| 湘潭市| 荔浦县| 深州市| 陕西省| 安顺市| 海林市| 策勒县| 图们市| 旌德县| 永川市| 黔东| 固阳县| 广东省| 忻州市| 西平县| 盐亭县| 曲麻莱县| 正蓝旗| 涟水县| 海宁市| 建平县| 永泰县| 唐山市| 黄骅市| 西和县| 贵德县| 普宁市| 屏南县| 大同市| 遂溪县| 永济市| 德昌县|