OMG,到底在尋找什么..................
          (構造一個完美的J2EE系統所需要的完整知識體系)
          posts - 198,  comments - 37,  trackbacks - 0
          原帖地址:http://www.aygfsteel.com/iamtin/archive/2006/06/05/50596.aspx

          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.2和Rome 0.8:
          http://wiki.opensymphony.com/display/WW/RomeResult
          參考了和東的這篇Blog,利用rome寫rss feed生成程序:
          http://hedong.3322.org/newblog/archives/000051.html

          首先創建RomeResult類:

          /**
          ?*?
          ?
          */
          package?com.goldnet.framework.webwork.result;

          import?java.io.Writer;

          import?org.apache.log4j.Logger;

          import?com.opensymphony.webwork.ServletActionContext;
          import?com.opensymphony.xwork.ActionInvocation;
          import?com.opensymphony.xwork.Result;
          import?com.sun.syndication.feed.synd.SyndFeed;
          import?com.sun.syndication.io.SyndFeedOutput;

          /**
          ?*?A?simple?Result?to?output?a?Rome?SyndFeed?object?into?a?newsfeed.
          ?*?
          @author?Philip?Luppens
          ?*?
          ?
          */
          public?class?RomeResult?implements?Result?{
          ?
          private?static?final?long?serialVersionUID?=?-6089389751322858939L;

          ?
          private?String?feedName;

          ?
          private?String?feedType;

          ?
          private?final?static?Logger?logger?=?Logger.getLogger(RomeResult.class);

          ?
          /*
          ??*?(non-Javadoc)
          ??*?
          ??*?@see?com.opensymphony.xwork.Result#execute(com.opensymphony.xwork.ActionInvocation)
          ??
          */
          ?
          public?void?execute(ActionInvocation?ai)?throws?Exception?{
          ??
          if?(feedName?==?null)?{
          ???
          //?ack,?we?need?this?to?find?the?feed?on?the?stack
          ???logger
          ?????.error(
          "Required?parameter?'feedName'?not?found.?"
          ???????
          +?"Make?sure?you?have?the?param?tag?set?and?"
          ???????
          +?"the?static-parameters?interceptor?enabled?in?your?interceptor?stack.");
          ???
          //?no?point?in?continuing?..
          ???return;
          ??}

          ??
          //?don't?forget?to?set?the?content?to?the?correct?mimetype
          ??ServletActionContext.getResponse().setContentType("text/xml");
          ??
          //?get?the?feed?from?the?stack?that?can?be?found?by?the?feedName
          ??SyndFeed?feed?=?(SyndFeed)?ai.getStack().findValue(feedName);

          ??
          if?(logger.isDebugEnabled())?{
          ???logger.debug(
          "Found?object?on?stack?with?name?'"?+?feedName?+?"':?"
          ?????
          +?feed);
          ??}
          ??
          if?(feed?!=?null)?{

          ???
          if?(feedType?!=?null)?{
          ????
          //?Accepted?types?are:?rss_0.90?-?rss_2.0?and?atom_0.3
          ????
          //?There?is?a?bug?though?in?the?rss?2.0?generator?when?it?checks
          ????
          //?for?the?type?attribute?in?the?description?element.?It's?has?a
          ????
          //?big?'FIXME'?next?to?it?(v.?0.7beta).
          ????feed.setFeedType(feedType);
          ???}
          ???SyndFeedOutput?output?
          =?new?SyndFeedOutput();
          ???
          //we'll?need?the?writer?since?Rome?doesn't?support?writing?to?an?outputStream?yet
          ???Writer?out?=?null;
          ???
          try?{
          ????out?
          =?ServletActionContext.getResponse().getWriter();
          ????output.output(feed,?out);
          ???}?
          catch?(Exception?e)?{
          ????
          //?Woops,?couldn't?write?the?feed??
          ????logger.error("Could?not?write?the?feed",?e);
          ???}?
          finally?{
          ????
          //close?the?output?writer?(will?flush?automatically)
          ????if?(out?!=?null)?{
          ?????out.close();
          ????}
          ???}

          ??}?
          else?{
          ???
          //?woops?..?no?object?found?on?the?stack?with?that?name??
          ???logger.error("Did?not?find?object?on?stack?with?name?'"?+?feedName
          ?????
          +?"'");
          ??}
          ?}

          ?
          public?void?setFeedName(String?feedName)?{
          ??
          this.feedName?=?feedName;
          ?}

          ?
          public?void?setFeedType(String?feedType)?{
          ??
          this.feedType?=?feedType;
          ?}

          }

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

          <package?name="default"?extends="webwork-default">
          ??
          <result-types>
          ???
          <result-type?name="feed"?class="com.goldnet.framework.webwork.result.RomeResult"/>
          ??
          </result-types>
          ??
          <interceptors>
          ??
          <!--?然后是你的那些inteceptor配置等?-->

          這樣我們就給xwork配置了一個叫做feed的result,它就是我們的romeResult。
          然后我們實現一個類,來測試一下這個romeResult。

          /**
          ?*
          ?
          */
          package?com.goldnet.webwork.action.news;

          import?com.opensymphony.xwork.ActionSupport;

          import?com.sun.syndication.feed.synd.SyndCategory;
          import?com.sun.syndication.feed.synd.SyndCategoryImpl;
          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?org.apache.commons.logging.Log;
          import?org.apache.commons.logging.LogFactory;

          import?java.util.ArrayList;
          import?java.util.Date;
          import?java.util.List;


          /**
          ?*?
          @author?Tin
          ?*
          ?
          */
          public?class?TestFeedCreateAction?extends?ActionSupport?{
          ????
          private?static?final?long?serialVersionUID?=?-2207516408313865979L;
          ????
          private?transient?final?Log?log?=?LogFactory.getLog(TestFeedCreateAction.class);
          ????
          private?int?maxEntryNumber?=?25;
          ????
          private?String?siteUrl?=?"http://127.0.0.1";
          ????
          private?SyndFeed?feed?=?null;

          ????
          public?TestFeedCreateAction()?{
          ????????
          super();
          ????}

          ????@Override
          ????
          public?String?execute()?{
          ????????List
          <News>?newsList?=?getNewsList();

          ????????
          if?(log.isDebugEnabled())?{
          ????????????log.debug(
          "Geting?feed!?and?got?news?"?+?newsList.size()?+
          ????????????????
          "?pieces.");
          ????????}

          ????????feed?
          =?new?SyndFeedImpl();

          ????????feed.setTitle(converttoISO(
          "測試中的新聞系統"));
          ????????feed.setDescription(converttoISO(
          "測試中的新聞系統:測試Rome?Result"));
          ????????feed.setAuthor(converttoISO(
          "測試Tin"));
          ????????feed.setLink(
          "http://www.justatest.cn");

          ????????List
          <SyndEntry>?entries?=?new?ArrayList<SyndEntry>();
          ????????feed.setEntries(entries);

          ????????
          for?(News?news?:?newsList)?{
          ????????????SyndEntry?entry?
          =?new?SyndEntryImpl();
          ????????????entry.setAuthor(converttoISO(news.getAuthor()));

          ????????????SyndCategory?cat?
          =?new?SyndCategoryImpl();
          ????????????cat.setName(converttoISO(news.getCategory()));

          ????????????List
          <SyndCategory>?cats?=?new?ArrayList<SyndCategory>();
          ????????????cats.add(cat);
          ????????????entry.setCategories(cats);

          ????????????SyndContent?content?
          =?new?SyndContentImpl();
          ????????????content.setValue(converttoISO(news.getContent()));

          ????????????List
          <SyndContent>?contents?=?new?ArrayList<SyndContent>();
          ????????????contents.add(content);
          ????????????entry.setContents(contents);
          ????????????entry.setDescription(content);
          ????????????entry.setLink(siteUrl?
          +?"/common/news/displayNews.action?id="?+
          ????????????????news.getId());
          ????????????entry.setTitle(converttoISO(news.getTitle()));
          ????????????entry.setPublishedDate(news.getPublishDate());
          ????????????entries.add(entry);
          ????????}

          ????????
          return?SUCCESS;
          ????}

          ????
          private?static?String?converttoISO(String?s)?{
          ????????
          try?{
          ????????????
          byte[]?abyte0?=?s.getBytes("UTF-8");

          ????????????
          return?new?String(abyte0,?"ISO-8859-1");
          ????????}?
          catch?(Exception?exception)?{
          ????????????
          return?s;
          ????????}
          ????}

          ????
          private?List<News>?getNewsList()?{
          ????????List
          <News>?newsList?=?new?ArrayList<News>();

          ????????
          for?(int?i?=?0;?i?<?maxEntryNumber;?i++)?{
          ????????????News?news?
          =?new?News();
          ????????????news.setTitle(
          "測試標題"?+?i);
          ????????????news.setContent(
          ????????????????
          "<p>測試內容測試內容<span?style=\"color:red\">測試內容</span></p>");
          ????????????news.setPublishDate(
          new?Date());
          ????????????news.setId(
          new?Long(i));
          ????????????news.setAuthor(
          "Tin");
          ????????????newsList.add(news);
          ????????}

          ????????
          return?newsList;
          ????}

          ????
          /**
          ?????*?
          @return?Returns?the?maxEntryNumber.
          ?????
          */
          ????
          public?long?getMaxEntryNumber()?{
          ????????
          return?maxEntryNumber;
          ????}

          ????
          /**
          ?????*?
          @param?maxEntryNumber?The?maxEntryNumber?to?set.
          ?????
          */
          ????
          public?void?setMaxEntryNumber(int?maxEntryNumber)?{
          ????????
          this.maxEntryNumber?=?maxEntryNumber;
          ????}

          ????
          /**
          ?????*?
          @param?siteUrl?The?siteUrl?to?set.
          ?????
          */
          ????
          public?void?setSiteUrl(String?siteUrl)?{
          ????????
          this.siteUrl?=?siteUrl;
          ????}

          ????
          /**
          ?????*?
          @return?Returns?the?feed.
          ?????
          */
          ????
          public?SyndFeed?getFeed()?{
          ????????
          return?feed;
          ????}

          ????
          private?class?News?{
          ????????
          private?Long?id;
          ????????
          private?String?title;
          ????????
          private?String?content;
          ????????
          private?Date?publishDate;
          ????????
          private?String?author;
          ????????
          private?String?category;

          ????????
          /**
          ??*?Getter/Setter都省略了,使用了內部類,就是圖個方便
          ??*?本意是模仿我們常常使用的Pojo,大家的實現都不一樣,我突簡單,里面其實可以有復雜類型的
          ??
          */
          ????}
          }

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

          <package?name="news"?extends="default"?namespace="/news">
          ??
          <action?name="feed"?class="com.goldnet.webwork.action.news.TestFeedCreateAction">
          ???
          <!--?每次生成15條rss?feed?-->
          ???
          <param?name="maxEntryNumber">15</param>
          ???
          <!--?鏈接的前綴,我們使用Weblogic是7001,也許你的是8080?-->
          ???
          <param?name="siteUrl">http://127.0.0.1:7001</param>
          ???
          <!--?result是feed?-->
          ???
          <result?name="success"?type="feed">
          ????
          <!--?feed名字是feed,對應我們這個Action中的那個SyndFeed的實例的名字feed,別忘記寫getter?-->
          ????
          <param?name="feedName">feed</param>
          ????
          <!--?制定生成的feed的類型,我這里選擇rss_2.0?-->
          ????
          <!--?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?-->
          ????
          <param?name="feedType">rss_2.0</param>
          ???
          </result>
          ??
          </action>
          </package>

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

          ?
          posted on 2007-01-14 02:32 OMG 閱讀(256) 評論(0)  編輯  收藏 所屬分類: Ajax/RSS/Tag

          <2007年1月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          IT風云人物

          文檔

          朋友

          相冊

          經典網站

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 满洲里市| 黄山市| 时尚| 宜春市| 泗洪县| 普定县| 商城县| 雷州市| 汝城县| 翼城县| 张家口市| 紫阳县| 华亭县| 绵竹市| 隆回县| 教育| 梁河县| 元氏县| 商城县| 佛坪县| 伊金霍洛旗| 和静县| 陵川县| 霍山县| 综艺| 岫岩| 安丘市| 武汉市| 六盘水市| 宁夏| 秦安县| 青川县| 武宣县| 玛多县| 文水县| 萨嘎县| 马龙县| 信阳市| 肇东市| 东海县| 巴里|