<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Tin's Blog

    You are coming a long way, baby~Thinking, feeling, memory...

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      128 隨筆 :: 0 文章 :: 221 評論 :: 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.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 2006-06-05 22:25 Tin 閱讀(3386) 評論(7)  編輯  收藏 所屬分類: Webwork相關

    評論

    # re: 使用WebWork和Rome輕松暴露RSS 2006-06-06 08:59 wolfsquare
    不錯,贊一個.
    這樣的文章比整天鼓噪自己的開源項目和團隊還在首頁吵架的文章要好多了.
      回復  更多評論
      

    # re: 使用WebWork和Rome輕松暴露RSS 2006-06-07 00:54 差沙
    寫的很好呀,贊一個。厚厚。  回復  更多評論
      

    # re: 使用WebWork和Rome輕松暴露RSS 2006-07-11 18:50 Border
    怎么解決中文編碼問題,現在已經調試成功,但是當有中文就出現一部分亂碼,不知道怎么解決。不知道你是怎么解決的,能不能給些建議。
    先謝過了

      回復  更多評論
      

    # re: 使用WebWork和Rome輕松暴露RSS 2006-07-11 22:15 Tin
    如果只有部分中文亂碼,可能是使用了GBK編碼,轉換為UTF-8等編碼時會有部分字符無法轉換吧。你從GBK轉到ISO8850-1看看。  回復  更多評論
      

    # re: 使用WebWork和Rome輕松暴露RSS 2006-07-12 09:55 Border
    還是不行,我的原feed文件是utf-8的,也就是你的rss文件,http://www.tkk7.com/iamtin/Rss.aspx
    要是我GBK轉到ISO8859-1還是亂碼,我只有通過
    entry.setTitle(new String(entry.getTitle().getBytes("utf-8")));
    來把原feed文件,方到目標文件,不過還是出現部分亂碼。如果方便的話,我把我的代碼給你發過去,你看看。

    borderj#gmail.com

      回復  更多評論
      

    # re: 使用WebWork和Rome輕松暴露RSS 2006-09-25 17:39 feiyi10
    我開始也出現了中文亂碼問題。。跟蹤發現,其實跟set的時候沒關系。
    之所以出現亂碼問題。是因為RomeResult這個類默認編碼為ISO8859-1。
    在ServletActionContext.getResponse().setContentType( " text/xml " );出加一句ServletActionContext.getResponse().setCharacterEncoding("utf-8");//根據需要添寫自己的編碼。希望對大家有所幫助。說的不對。還望見諒。  回復  更多評論
      

    # re: 使用WebWork和Rome輕松暴露RSS 2006-09-25 18:14 Tin
    謝謝feiyi10提醒。估計是response的編碼設置問題,我沒有認真跟蹤。希望遇到問題的朋友嘗試一下。  回復  更多評論
      

    主站蜘蛛池模板: 亚洲AV无码国产精品麻豆天美 | 欧美日韩亚洲精品| 久视频精品免费观看99| 中文字幕一精品亚洲无线一区| 美女裸免费观看网站| 无码免费又爽又高潮喷水的视频 | 亚洲日本va午夜中文字幕久久| EEUSS影院WWW在线观看免费 | 91香蕉国产线观看免费全集| 内射少妇36P亚洲区| 2021精品国产品免费观看| 亚洲午夜精品在线| 全免费a级毛片免费看不卡| 亚洲aⅴ无码专区在线观看| 亚洲AV无码一区二区三区国产| 免费高清A级毛片在线播放| 亚洲精品无码久久久久AV麻豆| 国产在线观看无码免费视频| 久久精品国产亚洲av麻| 免费99精品国产自在现线| 99亚洲乱人伦aⅴ精品| 久久99亚洲综合精品首页| 免费va在线观看| 亚洲综合av永久无码精品一区二区 | 免费永久看黄在线观看app| 成人免费区一区二区三区| 99精品免费视品| 国产在线观看免费完整版中文版 | 999国内精品永久免费观看| 亚洲午夜久久久久妓女影院| 亚洲影视自拍揄拍愉拍| 你懂的免费在线观看网站| 国产精品亚洲mnbav网站| 免费VA在线观看无码| 亚洲情侣偷拍精品| 三上悠亚电影全集免费| 亚洲精品国产电影| 毛片免费全部播放无码 | 亚洲aⅴ无码专区在线观看春色| 中文字幕不卡亚洲| 国产在线观看片a免费观看|