在上一邊部落格《Web版RSS閱讀器(一)——dom4j讀取xml(opml)檔案》中已經講過如何讀取rss訂閱檔案了。這次就把訂閱的檔案讀取到頁面上,使用樹形結構進行載入顯示。
不打算使用特殊的控制項進行樹型顯示,也不想自己寫了,想省勁些,就在 網上找了一個js樹形指令碼——dTree。dTree是一個便於使用的JavaScript樹形 菜單控制項。支援無限分級,可以在同一個頁面中放置多個dTree,可以為每個 節點指定不同的表徵圖。 首頁:http://destroydrop.com/javascripts/tree/default.html 下載:http://destroydrop.com/javascripts/tree/dtree.zip
樣本:http://destroydrop.com/javascripts/tree/v1/ |
|
我使用的是mvc2來實現載入rss分組列表的。mvc2的流程如下:
由於這次是使用jsp來顯示,所以把rss檔案夾轉移到WebRoot檔案夾下了。對原來的【ReadXML.java】做了部分修改,重新貼出來。
package com.tgb.rssreader.manager;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.tgb.rssreader.bean.RssBean;import com.tgb.rssreader.bean.RssConfigBean;import com.tgb.rssreader.bean.RssTeamBean;/** * 讀取xml檔案 * @author Longxuan * */public class ReadXML {// rss分組訂閱列表private List<RssTeamBean> rssTeamBeanList = new ArrayList<RssTeamBean>();/** * 讀取rss檔案清單 * @param directory */public void ReadRssTeam(String directory) {// rss檔案清單配置資訊實體RssConfigMgr rssConfigMgr = new RssConfigMgr();List<RssConfigBean> list = rssConfigMgr.getRssConfig();String errText = "";// 記錄錯誤資訊// 迴圈讀取rss檔案清單for (RssConfigBean rssConfig : list) {// System.out.println(rssConfig.getName() + "----" +// rssConfig.getPath());try {// 讀取rss檔案內容//ReadRss(System.getProperty("user.dir")+ rssConfig.getPath());ReadRss(directory + rssConfig.getPath());} catch (Exception e) {errText += e.getMessage();}}//如果有異常資訊,則匯總後拋出if(!"".equals(errText)){throw new RuntimeException(errText);}}/** * 讀取ompl檔案 * * @param filePath */private void ReadRss(String filePath) {File file = new File(filePath);if (!file.exists()) {// System.out.println("找不到【" + filePath + "】檔案");// return;throw new RuntimeException("找不到【" + filePath + "】檔案");}try {// 讀取並解析XML文檔// SAXReader就是一個管道,用一個流的方式,把xml檔案讀出來SAXReader reader = new SAXReader();FileInputStream fis = new FileInputStream(file);// 下面的是通過解析xml字串的Document doc = reader.read(fis);// 擷取根節點Element rootElt = doc.getRootElement(); // 擷取根節點// System.out.println("根節點:" + rootElt.getName()); // 拿到根節點的名稱// 擷取head/title節點Element titleElt = (Element) rootElt.selectSingleNode("head/title");// 擷取head節點下的子節點title// 擷取分組名稱String title = titleElt.getTextTrim();// 擷取body節點Element bodyElt = (Element) rootElt.selectSingleNode("body");// 擷取body下的第一個outline節點Element outlineElt = (Element) bodyElt.selectSingleNode("outline");// 判斷該outlineElt節點的屬性數量,>2說明是詳細部落格訂閱資訊,否則則是分組資訊。if (outlineElt.attributes().size() > 2) { // 詳細部落格訂閱資訊// 執行個體化 RSS分組實體RssTeamBean rssTeamBean = new RssTeamBean();// 擷取body節點下的outline節點Iterator<?> iter = bodyElt.elementIterator("outline");// 輸出分組名稱// System.out.println("分組名稱:" + title);// 記錄分組名稱rssTeamBean.setTitle(title);rssTeamBean.setText(title);// 執行個體化訂閱列表List<RssBean> rssBeanList = new ArrayList<RssBean>();// 擷取詳細部落格訂閱資訊ReadBlogsInfo(iter, rssBeanList);// 設定訂閱列表到分組中rssTeamBean.setRssBeanList(rssBeanList);// 添加分組到rss分組訂閱列表rssTeamBeanList.add(rssTeamBean);} else { // 分組資訊// 擷取body節點下的outline節點Iterator<?> iter = bodyElt.elementIterator("outline");while (iter.hasNext()) {// 讀取outline節點下的所有outline資訊,每條資訊都是一條訂閱記錄Element TeamElt = (Element) iter.next();// 執行個體化 RSS分組實體RssTeamBean rssTeamBean = new RssTeamBean();// 重新擷取分組名稱title = TeamElt.attributeValue("title");String text = TeamElt.attributeValue("text");// System.out.println("分組title:" + title + " text:" +// text);// 記錄分組名稱和顯示名稱rssTeamBean.setTitle(title);rssTeamBean.setText(text);// 執行個體化訂閱列表List<RssBean> rssBeanList = new ArrayList<RssBean>();// 擷取body節點下的outline節點Iterator<?> iterRss = TeamElt.elementIterator("outline");// 擷取詳細部落格訂閱資訊ReadBlogsInfo(iterRss, rssBeanList);// 設定訂閱列表到分組中rssTeamBean.setRssBeanList(rssBeanList);// 添加分組到rss分組訂閱列表rssTeamBeanList.add(rssTeamBean);}}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (DocumentException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/** * 讀取當前組部落格訂閱資訊 * * @param iter * 當前節點的子節點迭代器 * @param rssBeanList * 訂閱列表 */private void ReadBlogsInfo(Iterator<?> iter, List<RssBean> rssBeanList) {// 遍曆所有outline節點,每個節點都是一條訂閱資訊while (iter.hasNext()) {RssBean rssBean = new RssBean();Element outlineElt = (Element) iter.next();String htmlUrl = outlineElt.attributeValue("htmlUrl"); // 拿到當前節點的htmlUrl屬性值String xmlUrl = outlineElt.attributeValue("xmlUrl"); // 拿到當前節點的xmlUrl屬性值String version = outlineElt.attributeValue("version"); // 拿到當前節點的version屬性值String type = outlineElt.attributeValue("type"); // 拿到當前節點的type屬性值String outlineTitle = outlineElt.attributeValue("title"); // 拿到當前節點的title屬性值String outlineText = outlineElt.attributeValue("text"); // 拿到當前節點的text屬性值rssBean.setHtmlUrl(htmlUrl);rssBean.setXmlUrl(xmlUrl);rssBean.setVersion(version);rssBean.setType(type);rssBean.setTitle(outlineTitle);rssBean.setText(outlineText);rssBean.setText(outlineText);// 將每條訂閱資訊,存放到訂閱列表中rssBeanList.add(rssBean);}}/** * 擷取Rss分組訂閱列表 * * @return */public List<RssTeamBean> getRssTemBeanList() {return rssTeamBeanList;}}
正題終於開始了:在src中建立包com.tgb.rssreader.web,添加RssTeamServlet,繼承HttpServlet,實現doGet和doPost方法。它主要是用來調用com.tgb.rssreader.manager包下的ReadXML 類,以擷取到分組資訊,然後將其轉寄給left.jsp。原始碼如下:
package com.tgb.rssreader.web;import java.io.IOException;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.tgb.rssreader.bean.RssTeamBean;import com.tgb.rssreader.manager.ReadXML;/** * 載入Rss分組 * @author Longxuan * */@SuppressWarnings("serial")public class RssTeamServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//擷取web項目的根目錄的實際目錄String path = this.getServletConfig().getServletContext().getRealPath("/"); ReadXML readXML = new ReadXML();//讀取目錄下的rss檔案夾中的所有opml檔案//將所有分組資訊儲存在一個List<RssTeamBean>中,//將每個分組下的所有訂閱資訊,儲存在該RssTeamBean中的一個List<RssBean>中readXML.ReadRssTeam(path);//擷取裝有所有分組資訊的列表List<RssTeamBean> rssTemBeanList = readXML.getRssTemBeanList();//將所有分組資訊儲存在request的屬性rssTemBeanList中request.setAttribute("rssTemBeanList", rssTemBeanList);//轉寄requestrequest.getRequestDispatcher("/left.jsp").forward(request, response);}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}}
最後一步就是在介面上動工了。介面是自己先簡單的做了個html的模版,已上傳至百度網盤。布局使用frameset分割成3列,樹形結構的Rss分組資訊左側,即left.jsp。中間的為某個rss訂閱地址的文章列表,名為middle.jsp,右側則是顯示文章的地方,名為content.jsp。
現在先做成這樣一個效果:左側的left.jsp頁,使用dTree的樹形結構載入rss分組資訊。點擊一個訂閱資訊節點,在右側顯示出來對應的訂閱內容。修改的是left.jsp,貼出源碼:
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%><%@ page import="com.tgb.rssreader.bean.*" %><%@ page import="java.util.*" %><%String path = request.getContextPath();String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+path+"/";%><html><head><base href="<%=basePath %>" /><link rel="stylesheet" href="style/main.css"><link rel="StyleSheet" href="style/dtree.css" type="text/css" /><script type="text/javascript" src="js/dtree.js"></script></head><body><div id="leftMenu" style="overflow-y:auto; overflow-x:auto;"> <script type="text/javascript"><!--<!-- add(id, pid, name, url, title, target, icon, iconOpen, open);//9個參數說明: id,pid,顯示名稱,開啟的url,提示資訊,目標框架,閉合時的表徵圖,展開時的表徵圖,是否展開(open || false)-->d = new dTree('d');d.add(0,-1,'部落格分組','','','','','img/blog.png');<%int i = 0;//當前分組的節點索引值int c = 0;//節點總數//擷取所有分組資訊List<RssTeamBean> rssTemBeanList = (List)request.getAttribute("rssTemBeanList");//遍曆所有分組資訊for (RssTeamBean rssTeamBean:rssTemBeanList) {c = c+1;//總個數加1%>//添加組節點d.add(<%=c%>,0,'<%=rssTeamBean.getTitle()%>','','','','img/open.png','img/close.png');<%i=c;//設定當前節點為分組節點索引值//遍曆分組下的所有訂閱資訊for (RssBean rssBean : rssTeamBean.getRssBeanList()) {c = c+1;//總個數加1%>//添加訂閱資訊節點d.add(<%=c%>,<%=i%>,'<%=rssBean.getTitle()%>','<%=rssBean.getXmlUrl()%>','<%=rssBean.getText()%>','contenthtml');<%}}%>//在介面上顯示樹形結構document.write(d);//--></script></div></body></html>
暫時的如下:
至此,讀取rss分組已經完成了。接下來的博文中,會給大家解說一下rss版本以及解析線上的rss訂閱。敬請期待。