<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 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      128 隨筆 :: 0 文章 :: 221 評(píng)論 :: 0 Trackbacks

    WebWork的result實(shí)現(xiàn)非常實(shí)用,它很好的解決了View渲染的靈活性問題。這才是MVC模式的優(yōu)勢(shì)所在,而像JSF那樣幫定JSP的MVC就吃不到這個(gè)甜頭了。說WebWork2是Model 2 MVC的巔峰就在這些靈活的地方。
    閑扯這個(gè)不是主要目的。現(xiàn)在Rome是Java下最常用的RSS包,最近消息似乎要轉(zhuǎn)入Apache的Abdera合并變成更強(qiáng)大的聚合引擎。用Rome生成和解析RSS都很方便。今天討論一下使用ROME給網(wǎng)站生成RSS,并通過WebWork2的Result機(jī)制渲染。
    最初是從WebWork的Cookbook上看到的RomeResult的文章,一看就會(huì),我這里其實(shí)不過是舉個(gè)詳細(xì)點(diǎn)的例子,注意我使用的是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

    首先創(chuàng)建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;
    ?}

    }

    程序很簡(jiǎn)單。實(shí)現(xiàn)了Result接口,尋找一個(gè)與feedName參數(shù)匹配的SyndFeed實(shí)例,然后轉(zhuǎn)換為指定的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配置了一個(gè)叫做feed的result,它就是我們的romeResult。
    然后我們實(shí)現(xiàn)一個(gè)類,來測(cè)試一下這個(gè)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(
    " 測(cè)試中的新聞系統(tǒng) " ));
    ????????feed.setDescription(converttoISO(
    " 測(cè)試中的新聞系統(tǒng):測(cè)試Rome?Result " ));
    ????????feed.setAuthor(converttoISO(
    " 測(cè)試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(
    " 測(cè)試標(biāo)題 " ? + ?i);
    ????????????news.setContent(
    ????????????????
    " <p>測(cè)試內(nèi)容測(cè)試內(nèi)容<span?style=\ " color:red\ " >測(cè)試內(nèi)容</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都省略了,使用了內(nèi)部類,就是圖個(gè)方便
    ??*?本意是模仿我們常常使用的Pojo,大家的實(shí)現(xiàn)都不一樣,我突簡(jiǎn)單,里面其實(shí)可以有復(fù)雜類型的
    ??
    */
    ????}
    }

    真是不好意思,Getter/Setter占了大部分地方我省略去了。邏輯很簡(jiǎn)單,就是把我們的POJO影射到Feed的模型上面,過程很簡(jiǎn)單。我留下了幾個(gè)參數(shù)可以在外面設(shè)置:
    maxEntryNumber顯示的feed的條數(shù),鏈接生成時(shí)使用的SiteUrl,當(dāng)然也可以通過request獲取。
    下面我們配置我們的Action,注意平時(shí)我們可能使用DAO生成newsList,而不是我這個(gè)寫死的getNewsList()方法,此時(shí)可能需要配合Spring進(jìn)行IOC的設(shè)置,我們這里省略掉。
    下面是我們這個(gè)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,對(duì)應(yīng)我們這個(gè)Action中的那個(gè)SyndFeed的實(shí)例的名字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就可以訪問到這個(gè)feed了。倒入你的feedDeamon,看看,是不是非常簡(jiǎn)單?
    不過需要考慮兩個(gè)地方,一個(gè)是編碼問題,看了和東說的中文問題,本沒當(dāng)回事,結(jié)果生成亂碼(我們項(xiàng)目全部使用UTF-8),然后還是轉(zhuǎn)了一下。沒有研究ROME源代碼,感覺xml不應(yīng)該有UTF-8還會(huì)亂碼的問題呀,也許還需要看看是否是設(shè)置不到位。還有就是對(duì)于feed如果增加了權(quán)限認(rèn)證則訪問比較麻煩,用feedDeamon這樣的客戶端就無(wú)法訪問到了,因?yàn)樗粫?huì)顯示登陸失敗后顯示的登陸頁(yè)面,也許放feed就要開放一點(diǎn)吧(當(dāng)然還是有變通放案的)。
    和動(dòng)例子里面的rome 0.7和現(xiàn)在的rome 0.8相比,Api已經(jīng)發(fā)生了不少變化,唉,開源要代碼穩(wěn)定還真難。
    就這些,就到這里,粗陋了:D

    posted on 2006-06-05 22:25 Tin 閱讀(3388) 評(píng)論(7)  編輯  收藏 所屬分類: Webwork相關(guān)

    評(píng)論

    # re: 使用WebWork和Rome輕松暴露RSS 2006-06-06 08:59 wolfsquare
    不錯(cuò),贊一個(gè).
    這樣的文章比整天鼓噪自己的開源項(xiàng)目和團(tuán)隊(duì)還在首頁(yè)吵架的文章要好多了.
      回復(fù)  更多評(píng)論
      

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

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

      回復(fù)  更多評(píng)論
      

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

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

    borderj#gmail.com

      回復(fù)  更多評(píng)論
      

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

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

    主站蜘蛛池模板: 一本色道久久综合亚洲精品蜜桃冫 | 丁香五月亚洲综合深深爱| 亚洲www77777| 一二三四免费观看在线电影 | 中文国产成人精品久久亚洲精品AⅤ无码精品| 亚洲精品第一国产综合野| 日韩亚洲国产高清免费视频| 亚洲欧洲日产v特级毛片| 久久九九兔免费精品6| 亚洲视频国产视频| 成人黄色免费网站| 亚洲最大福利视频| 日本免费一区二区三区最新vr| 亚洲日韩AV一区二区三区四区| 91情侣在线精品国产免费| 亚洲欧洲专线一区| 亚洲Av无码乱码在线观看性色| selaoban在线视频免费精品| 国产成人无码综合亚洲日韩| 午夜免费福利片观看| 亚洲人妖女同在线播放| 成人毛片18女人毛片免费| 国产亚洲精品美女久久久久| 国产精品V亚洲精品V日韩精品| 免费看一区二区三区四区| 亚洲国产综合自在线另类| 欧美日韩国产免费一区二区三区| 国产精品亚洲专区无码WEB | 亚洲视频一区二区在线观看| 最新中文字幕电影免费观看| 美女被免费网站视频在线| 亚洲精品成人片在线观看精品字幕 | 久久精品国产亚洲av日韩| 无码日韩精品一区二区免费| 美美女高清毛片视频黄的一免费 | 亚洲AV无码专区国产乱码4SE| h视频在线免费看| 精品免费AV一区二区三区| 国产亚洲人成网站在线观看不卡| 性xxxxx免费视频播放| 国产伦精品一区二区免费|