文档章节

Web版RSS阅读器(五)——初步完成阅读功能

白志华
 白志华
发布于 2015/10/18 10:54
字数 1987
阅读 17
收藏 0

       上一篇博文《Web版RSS阅读器(四)——定制自己的Rss解析库myrsslib4j》中,已经分享给大家制作自己的rss解析库。稍微有点遗憾的是,它仅仅支持rss格式的博客。现在给大家分享一下我基于rome修改而成的另一款rss解析库——myrome,完美支持atom和rss 2种格式。


      myrome.jar是在rome的基础上修改而来的,主要改动的地方是:(查看详细修改说明)

    1. 修改GetAuthor()返回null
    2. 修改getPublishedDate()返回null
    3. 添加获取文章摘要的接口和方法


      本篇主题是把myrome加入到RssReader中,修改界面,完成初步的访问和阅读的功能。具体实现的效果为:

    1. 根据不同的订阅信息,加载对应的图标,从而一眼得知订阅的出处
    2. 点击左侧的某个订阅,在中间的页面中显示出标题、时间和摘要列表,用水平线隔开
    3. 点击某个摘要信息,在右侧内容区域,显示该文章的所有内容。
    4. 双击摘要信息,则会用新窗口打开原文章地址。

      等不及了吗?点 这里或者 这里 抢先查看效果吧。

      言归正传,接下来请大家跟随我初步成功的脚步:

      下载myrome-1.0.jar,拷贝到WebRoot/WEB-INF/lib下。如果已经引用过rome-0.2.jar,要提前删除掉。在com.tgb.rssreader.manager包中新建RomeReadRss类,用来解析在线rss内容。
RomeReadRss.java
package com.tgb.rssreader.manager;

import java.net.URL;
import java.net.URLConnection;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

/**
 * 解析Rss订阅信息
 * 
 * @author Longxuan
 * 
 */
public class RomeReadRss {

	/**
	 * 解析Rss订阅信息
	 */
	public SyndFeed parseRss(String rss) {
		SyndFeed feed = null;
		feed = null;
		try {

			URLConnection feedUrl = new URL(rss).openConnection();

			// 由于服务器屏蔽java作为客户端访问rss,所以设置User-Agent
			feedUrl.setRequestProperty("User-Agent",
					"Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

			// 读取Rss源
			XmlReader reader = new XmlReader(feedUrl);

			SyndFeedInput input = new SyndFeedInput();

			// 得到SyndFeed对象,即得到Rss源里的所有信息
			feed = input.build(reader);

		} catch (Exception e) {
			e.printStackTrace();
		}

		return feed;
	}

}

      修改left.jsp页的树形节点加载信息,根据不同的博客提供商,加载不同的图标。点击某节点后,将rss地址传递给servlet,去解析在线的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>
	<script type="text/javascript">
		//获取图标地址
		function getIco(field){
			var s = field.split("/");
			if(s[2].indexOf("163")>0 && s[2].split(".")[0]!="blog"){
				s[2] = s[2].substring(s[2].indexOf("blog"));
			}
			return "icos/"+s[2]+".ico";
		}
	</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()%>','servlet/RssServlet?rss=<%=rssBean.getXmlUrl()%>','<%=rssBean.getText()%>','middlehtml',getIco('<%=rssBean.getXmlUrl()%>'),getIco('<%=rssBean.getXmlUrl()%>'),false);
			//d.add(<%=c%>,<%=i%>,'<%=rssBean.getTitle()%>','<%=rssBean.getXmlUrl()%>','<%=rssBean.getText()%>','contenthtml');
<%	
		}
	}
%>
		//在界面上显示树形结构
		document.write(d);

		//-->
	</script>
</div>
</body>
</html>

      在com.tgb.rssreader.web包中新建一个RssServlet类,继承HttpServlet,实现doGet和doPost方法。它接收到有left.jsp传递过来的rss地址,调用RomeReadRss来解析rss内容。解析完毕后,转向middle.jsp,在中间这个网页中,显示解析的内容。
RssServlet.java
package com.tgb.rssreader.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.syndication.feed.synd.SyndFeed;
import com.tgb.rssreader.manager.RomeReadRss;

/**
 * 解析Rss信息资源Servlet
 * @author Longxuan
 *
 */
@SuppressWarnings("serial")
public class RssServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		//获取rss地址
		String rss = request.getParameter("rss");
		
		//获取基于myrome的解析对象
		RomeReadRss romeReadRss = RomeReadRss.getInstance();
		
		//解析rss内容,存放到SyndFeed对象中
		SyndFeed feed = romeReadRss.parseRss(rss);
		
		//设置属性,用于传递SyndFeed对象
	    request.getSession().removeAttribute("feed");
	    request.getSession().setAttribute("feed", feed);
        //转向middle.jsp
        request.getRequestDispatcher("/middle.jsp").forward(request, response);
      }

     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
         doGet(req, resp);
     }
}
      解析完毕后,开始修改middle.jsp。它接受到request中传递过来的SyndFeed对象,读取文章标题、发布时间及摘要信息,每篇文章都用横线隔开。未阅读过的显示黑色字体,阅读过后,显示灰色字体,鼠标指上去会变蓝色。点击文章摘要后,将该摘要的索引值传递过去;双击文章摘要信息,则会在新窗口中打开对应文章的实际连接。
middle.jsp
<%@ page language="java" contentType="text/html; charset=GB18030"
	pageEncoding="GB18030"%>
<%@ page import="com.sun.syndication.feed.synd.*"%>
<%@page import="java.util.List"%>
<%@page session="true" %>

<%
	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">
	<style type="text/css">
		#middleTitle ul li {
			text-align: left;
			display: inline;
			line-height: 24px;
			height: auto;
			word-break: break-all;
			word-wrap: break-word;
		}
		
		a {
			text-decoration: none;
		}
		
		a:link {
			color: #000000;
		}  /* 未被访问的链接 */
		a:visited {
			color: #808080;
		}  /* 已被访问的链接 */
		a:hover {
			color: #0000FF;
		}  /* 鼠标指针移动到链接上 */
		a:active {
			color: #0000FF;
		} /* 正在被点击的链接 */
	</style>


	<script type="text/javascript">
		function openInBrowser(url) {
			window.open(url);
		}		
	</script>
</head>
<body>
	<div id="middleTitle">
		<ul>

		<%
		//获取设置到session中的摘要信息
		SyndFeed feed = (SyndFeed) request.getSession().getAttribute("feed");
		if (feed == null)return;
		
		//获取所有文章列表
		List entriesList = feed.getEntries();
		
		//循环加载文章摘要列表
		for (int i = 0; i < entriesList.size(); i++) {
			SyndEntry entry = (SyndEntry) entriesList.get(i);%>

			<a href="servlet/ArticleServlet?articleIndex=<%=i%>"
				title="<%=entry.getTitle()%>" target="contenthtml"
				ondblclick="openInBrowser('<%=entry.getLink().trim()%>')">
				<li>
					<%=entry.getTitle().trim()%>
					<%=entry.getPublishedDate().toLocaleString()%>
				</li>
				<li>
					<%=((SyndContent) entry.getContents().get(0)).getSummary(30)%>
				</li> </a>
			<hr>
			<%}%>
		</ul>
	</div>
</body>
</html>

      
      当点击某篇文章标题时,将该文章的索引值传递到ArticleServlet中,在Session中找到对应的文章,把文章正文内容传递到content.jsp页面。所以在com.tgb.rssreader.web包中新建ArticleServlet类,继承HttpServlet,实现doGet和doPost方法。
ArticleServlet.java
package com.tgb.rssreader.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;

/**
 * 获取文章正文
 * @author Longxuan
 *
 */
@SuppressWarnings("serial")
public class ArticleServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		//获取要查看的文章的索引值
		int articleIndex = request.getParameter("articleIndex") == null? 0: Integer.parseInt( request.getParameter("articleIndex"));
		
		//获取session中的变量
		SyndFeed feed = (SyndFeed) request.getSession().getAttribute("feed");
		SyndContent content = (SyndContent)((SyndEntry)feed.getEntries().get(articleIndex)).getContents().get(0);
		request.setAttribute("content", content.getValue());
		request.getRequestDispatcher("/content.jsp").forward(request, response);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doGet(req, resp);
	}
}

      在content.jsp中获取文章内容进行显示即可:
content.jsp
<%@ page language="java" contentType="text/html; charset=GB18030"
	pageEncoding="GB18030"%>
<%@page import="com.sun.syndication.feed.synd.*"%>
<%
	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">
	</head>
	<body>
		<div id="content">
			<div id="welcome" class="content" style="display: block;">
				<div align="left">
					<p>
						<%= request.getAttribute("content")==null?"<marquee behavior='alternate'" +
								"onmouseover='this.stop()' onmouseout='this.start()' wight='60%' scrollamount='4'>" +
								"<font size='6' text-align='center' >欢迎使用提高班在线Rss阅读器!" +
								"——@<a href = \"http://blog.csdn.net/xiaoxian8023\" target='_blank'>龙轩</a></font>" 
								:request.getAttribute("content").toString()%>
					</p>
					<hr>
				</div>
			</div>
		</div>
	</body>
</html>

      至此,Web版Rss阅读器阅读博客功能基本已经完工了,终于可以看到这款rss阅读器的样子了。当然需要优化的地方还很多。暂时打算告一段落,等过段时间再进行优化。基本的代码都已经写过了,不打算单独提供源码了。本来不打算提供源码了,因为按照步骤,差不多能整出来的。不过为了方便大家,刚刚还是把源码上传了,资源地址:

       最后晒一下效果图吧:


(点击图片在查看网站实例)

如果您觉得做得不错,值得鼓励,就轻轻地【 顶一下 】吧

版权声明:本文为博主原创文章,未经博主允许不得转载。

本文转载自:http://blog.csdn.net/xiaoxian8023/article/details/10311461

共有 人打赏支持
白志华
粉丝 29
博文 265
码字总数 57524
作品 0
长沙
程序员
Google Reader 的开源替代品

Google关闭Google Reader让所有人认识到过于依赖他人免费服务的后果。如果你有能力和资源,你完全可以自己搭建一个RSS阅读器服务,或者是改用本地客户端。 ownCloud是一个完整的开源自托管服...

oschina
2013/03/28
5.1K
16
为什么 RSS 仍然很重要

据国外媒体报道,谷歌要关闭谷歌阅读器RSS客户端的消息,就像是一颗重磅炸弹,在实时话题广播网Twitter上引发了巨大反响。有些人愤怒,有些人悲伤,有些人则洋洋得意。 那些得意的人说,RSS...

oschina
2013/03/17
1K
8
四款最佳的 RSS 阅读器推荐

前言 RSS 的全称是 Really Simple Syndication,“简易信息聚合”。它把新闻、博客等的标题、摘要和内容按一定要求整理推送,用户通过 RSS 阅读器订阅查看。 我们可以把 RSS 看作是一种信息订...

己立
09/21
0
0
Google Reader关闭在即,Digg Reader下周公开

今天 3 月份,Google 宣布将在 7 月 1 日停止 Google Reader 服务,在用户中引发大量不满与抗议的同时,RSS 阅读器市场也开始了全面洗牌。现在距 Google Reader 正式关闭不到两周的时间,Dig...

oschina
2013/06/18
1K
9
变懒的编程高手

两年前,我还每天都阅读技术文章,有规律的观看演讲,大量的在stackoverflow上回答问题。 后来我开始慢慢的减少这方面的 “努力”。只在微博上关注一些科技聚合信息源(HN,reddit,DZone),这...

oschina
2013/10/28
8.1K
24

没有更多内容

加载失败,请刷新页面

加载更多

【大福利】极客时间专栏返现二维码大汇总

我已经购买了如下专栏,大家通过我的二维码你可以获得一定额度的返现! 然后,再给大家来个福利,只要你通过我的二维码购买,并且关注了【飞鱼说编程】公众号,可以加我微信或者私聊我,我再...

飞鱼说编程
今天
1
0
Spring5对比Spring3.2源码之容器的基本实现

最近看了《Spring源码深度解析》,该书是基于Spring3.2版本的,其中关于第二章容器的基本实现部分,目前spring5的实现方式已有较大改变。 Spring3.2的实现: public void testSimpleLoad(){...

Ilike_Java
今天
1
0
【王阳明心学语录】-001

1.“破山中贼易,破心中贼难。” 2.“夫万事万物之理不外于吾心。” 3.“心即理也。”“心外无理,心外无物,心外无事。” 4.“人心之得其正者即道心;道心之失其正者即人心。” 5.“无...

卯金刀GG
今天
2
0
OSChina 周三乱弹 —— 我们无法成为野兽

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ _刚刚好: 霸王洗发水这波很骚 手机党少年们想听歌,请使劲儿戳(这里) hahahahahahh @嘻酱:居然忘了喝水。 让你喝可乐的话, 你准忘不了...

小小编辑
今天
11
0
vm GC 日志 配置及查看

-XX:+PrintGCDetails 打印 gc 日志 -XX:+PrintTenuringDistribution 监控晋升分布 -XX:+PrintGCTimeStamps 包含时间戳 -XX:+printGCDateStamps 包含时间 -Xloggc:<filename> 可以将数据保存为......

Canaan_
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部