? ? 在上一邊博客《[Web版RSS閱讀器(一)——dom4j讀取xml(opml)文件](http://blog.csdn.net/xiaoxian8023/article/details/9628751)》中已經講過如何讀取rss訂閱文件了。這次就把訂閱的文件讀取到頁面上,使用樹形結構進行加載顯示。
<table border="0"><tbody><tr><td><p><span style="font-size:18px">? ? ? 不打算使用特殊的控件進行樹型顯示,也不想自己寫了,想省勁些,</span><span style="font-size:18px">就在</span></p><p><span style="font-size:18px">網上找了一個js樹形腳本——dTree。dTree是一個易于使用的JavaScript</span><span style="font-size:18px">樹形</span></p><p><span style="font-size:18px">菜單控件。支持無限分級,可以在同一個頁面中放置多個dTree,</span><span style="font-size:18px">可以為每個</span></p><p><span style="font-size:18px">節點指定不同的圖標。</span></p><p style="text-align:left"><span style="font-size:18px">? ? ? 主頁:<a target="_blank" href="http://destroydrop.com/javascripts/tree/default.html">http://destroydrop.com/javascripts/tree/default.html</a></span></p><p style="text-align:left"><span style="font-size:18px">? ? ? 下載:<a target="_blank" href="http://destroydrop.com/javascripts/tree/dtree.zip">http://destroydrop.com/javascripts/tree/dtree.zip</a><br/></span></p><p style="text-align:left"><span style="font-size:18px">? ? ? 示例:<a target="_blank" href="http://destroydrop.com/javascripts/tree/v1/">http://destroydrop.com/javascripts/tree/v1/</a></span></p></td><td><p style="text-align:right"><span style="font-size:18px"><img src="image/28c46bbe5897f8bbabaee2168b46805c.jpg" alt=""/><br/></span></p></td></tr></tbody></table>
? ? 我使用的是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 block
e.printStackTrace();
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.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 {
@Override
protected 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);
//轉發request
request.getRequestDispatcher("/left.jsp").forward(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
}
~~~
? ? 最后一步就是在界面上動工了。界面是自己先簡單的做了個html的模版,已上傳至[百度網盤](http://pan.baidu.com/share/link?shareid=2484310135&uk=1259218556)。布局使用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訂閱。敬請期待。