使用FreeMarker/Jsp(WebWork2)產生靜態/動態RSS檔案

來源:互聯網
上載者:User

scud(飛雲小俠)  http://www.jscud.com 轉載請註明作者/來源

關鍵字:rss,freemarker,rss.xml,webwork2

RSS在網路上大行其道,各種網站都加上RSS支援,我最近也研究了一下,給我的文章也加上了RSS訂閱.

RSS目前用的也有幾個版本,很是混亂,下面以RSS2.0為例來說明.

網路上有個rsslibj庫,是用來產生rss支援檔案的,不過已經好久沒有更新了,它是用xml的方式產生的.本文的例子不用到任何xml解析器,不過當然要知道最後產生的XML檔案的格式才行,關於RSS規範,可以瀏覽一下 http://blogs.law.harvard.edu/tech/rss .

在計劃產生RSS檔案的時候,順便搜尋了一下JIRA和Confluence的程式,發現它們分別是用模板方式和JSP動態網頁面來展示的.於是我也想到兩種方式:
1.用FreeMarker產生靜態檔案,適用於更新不是很頻繁的內容.
2.用JSP動態展示,適合更新頻率高,種類繁多的內容.

還是以本站的新聞舉例,其中的新聞資訊類參考 http://www.jscud.com/srun/news/viewhtml/3_2005_8/76.htm ,此處不在列出.

(一) 先說FreeMarker方式.

根據RSS的規範,得到模板如下:

<?xml version="1.0" encoding="UTF-8" ?>
 <rss version="2.0">
 <channel>
  <title>JScud Develop</title>
  <link>http://www.jscud.com/</link>
  <language>zh-cn</language>
  <description >JScud Develop By Scud</description>
  <webMaster>xxx@21cn.com(scud)</webMaster>
  <lastBuildDate>${rssutil.formatRssDate(now)}</lastBuildDate>
   
   <#list newslist as onenews>
  <item>
   <title>${onenews.title?xml}</title>
   <link>http://www.jscud.com/srun/news/viewhtml/${onenews.htmlFilePath}/${onenews.nid}.htm</link>
   <pubDate>${rssutil.formatRssDate(onenews.addtime)}</pubDate>
   <description><![CDATA[
  ${rssutil.formatRssCData(onenews.showContent)}
   ]]>
   </description>
   </item>
 </#list>
  </channel>
 </rss>

其中的網址和網站名稱可以根據自己的實際情況修改.

我每次取出最新的20條文章來產生RSS,不過內容比較多,產生的RSS檔案比較大,看到有的網站的description只是放了文章摘要的內容,這樣檔案就小多了.總之是根據自己的需求設計吧.

其中用到的RssUtil函數庫的函數如下(日期的函數參考上一篇文章):

    /**
     * 把]]>替換為]]&gt;
     * @param content 內容
     * @return 格式化後的內容
     */
    public static String formatRssCData(String content)
    {
        String result = StringFunc.replace(content,"//]//]>","]]&gt;");
       
        return result;
    }
   
    /**
     * 格式化為xml需要的字串
     * @param field 內容
     * @return 格式化後的串
     */
    public static String formatString2XML(String field)
    {
        return StringFunc.str2TextXML(field);
    }
   
    public static String getNowDateTime()
    {
        return formatRssDate(DateTime.getNowTimestamp());
    }

利用FreeMarker產生靜態檔案的代碼如下:

 private Configuration freemarker_cfg = null;
 
    protected Configuration getFreeMarkerCFG()
    {
        if (null == freemarker_cfg)
        {
            // Initialize the FreeMarker configuration;
            // - Create a configuration instance
            freemarker_cfg = new Configuration();

            freemarker_cfg.setClassForTemplateLoading(this.getClass(), "/htmlskin");

            freemarker_cfg.setDefaultEncoding("GBK");
        }

        return freemarker_cfg;
    }

    public boolean geneFileByFreeMarker(String templateFileName, Map propMap, String filePath,
                    String fileName, String encode)
    {
        try
        {
            Template t = getFreeMarkerCFG().getTemplate(templateFileName);

            File afile = new File(filePath + "/" + fileName);

            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(afile),
                            encode));

            propMap.put("baseurl", PropSet.getStringProp("url.root"));

            t.process(propMap, out);
        }
        catch (TemplateException e)
        {
            LogMan.error("Error while processing FreeMarker template " + templateFileName, e);
            return false;
        }
        catch (IOException e)
        {
            LogMan.error("Error while generate File " + fileName, e);
            return false;
        }

        return true;
    }

新聞系統中調用重建RSS檔案的代碼如下:

    /**
     * 重建RSS檔案.
     *
     * @param nid 更新的新聞的id,如果不包含在最新的新聞裡,則不更新RSS.nid <1則更新
     *
     * @return 是否成功
     */
    private boolean renewRSS(int nid)
    {
        List newsList = 裝載新聞的代碼

        boolean shouldUpdate = false;
        if (nid > 0)
        {
            for (int i = 0; i < newsList.size(); i++)
            {
                NewsItem aNews = (NewsItem) newsList.get(i);
                if (aNews.getNid() == nid)
                {
                    shouldUpdate = true;
                    break;
                }
            }
        }
        else
        {
            shouldUpdate = true;
        }

        //不更新,則返回
        if (!shouldUpdate)
        {
            return true;
        }

        Map root = new HashMap();
       
        root.put("rssutil",new RSSUtil());

        root.put("newslist", newsList);
       
        root.put("now",DateTime.getNowTimestamp());

        geneFileByFreeMarker("/news/rss.ftl", root, PropSet.getStringProp("rss.rssdir"), PropSet
                        .getStringProp("rss.rssfile"), "UTF-8");

        return true;
    }

在增加或者更新/刪除新聞的地方需要調用這個renewRSS函數.

(二)JSP動態方式

相對靜態方式而言,簡單的多,不過效率上可能就不太好了.

webwork2的Action代碼如下:

        newsList = 裝載新聞代碼
        return SUCCESS; 

視圖Jsp如下:

<%@ page contentType="text/xml; charset=UTF-8"%>
<%@ taglib uri="jscud" prefix="jscud" %>
<%@ taglib uri="webwork" prefix="ww" %>
<ww:bean name="’com.jscud.www.util.RSSUtil’" id="rssUtil" />
<?xml version="1.0" encoding="UTF-8" ?>
 <rss version="2.0">
 <channel>
  <title>JScud Develop</title>
  <link>http://www.jscud.com/</link>
  <language>zh-cn</language>
  <description >JScud Develop By Scud</description>
  <webMaster>xxx@21cn.com(scud)</webMaster>
  <lastBuildDate><ww:property value="#rssUtil.nowDateTime" /></lastBuildDate>
   
   <ww:iterator value="newsList">
  <item>
   <title><ww:property value="#rssUtil.formatString2XML(title)"/></title>
   <link>http://www.jscud.com/srun/news/viewhtml/<ww:property  value="htmlFilePath" />/<ww:property  value="nid" />.htm</link>
   <pubDate><ww:property  value="#rssUtil.formatRssDate(addtime)" /></pubDate>
   <description><![CDATA[
  <ww:property value="#rssUtil.formatRssCData(showContent)"/>
   ]]>
   </description>
   </item>
 </ww:iterator>
  </channel>
 </rss>

jsp的方式簡單多了,上面的jsp裡面還示範了ww:bean的使用

上面的類裡面引用了很多其他的工具類,這裡不一一列出,可以自己實現它們,都是很簡單的類.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.