上一篇博文《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阅读器的样子了。当然需要优化的地方还很多。暂时打算告一段落,等过段时间再进行优化。基本的代码都已经写过了,不打算单独提供源码了。最后晒一下效果图吧:





Web版RSS阅读器(五)——初步完成阅读功能的更多相关文章

  1. Web版RSS阅读器(三)——解析在线Rss订阅

    上篇博客<Web版RSS阅读器(二)——使用dTree树形加载rss订阅分组列表>已经写到读取rss订阅列表了,今天就说一下,当获取一条在线rss订阅的信息,怎么去解析它,从而获取文章或资 ...

  2. Web版RSS阅读器(二)——使用dTree树形加载rss订阅分组列表

    在上一边博客<Web版RSS阅读器(一)——dom4j读取xml(opml)文件>中已经讲过如何读取rss订阅文件了.这次就把订阅的文件读取到页面上,使用树形结构进行加载显示. 不打算使用 ...

  3. 基于easyui开发Web版Activiti流程定制器详解(五)——Draw2d详解(一)

    背景: 小弟工作已有十年有余,期间接触了不少工作流产品,个人比较喜欢的还是JBPM,因为出自名门Jboss所以备受推崇,但是现在JBPM版本已经与自己当年使用的版本(3.X)大相径庭,想升级也不太容易 ...

  4. RSS阅读器(一)——dom4j读取xml(opml)文件

    接触java不久,偶有收获,最近想做一个web版RSS阅读器来锻炼一下.手头有几个从不同版本的foxmail中导出的opml文件,大家应该都知道,opml文件就是xml格式的.那么就先从这里入手,练习 ...

  5. 为什么说Thunderbird是最好的桌面RSS阅读器

    也许现在再讨论RSS阅读器似乎已经过时了,毕竟随着社交网络服务的发展,通过一个带有大众评分能力的社交网络(比如reddit),相比RSS的固定订阅而言,也许你能更快地在你所关心的话题上更快地获得新的资 ...

  6. Foxit Reader(福昕PDF阅读器) v4.3.1.218 绿色专业版

    软件名称:Foxit Reader(福昕PDF阅读器) v4.3.1.218 绿色专业版 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 4.40MB 图片 ...

  7. ubuntu下安装CAJ阅读器

    目录 1.ubuntu下wine的基本介绍 (1)wine的介绍 (2)wine的安装 (3)exe文件的安装 (4)exe程序的卸载 (6)wine的基本使用 2.CAJ阅读器的安装 (1)首先放上 ...

  8. 采用QT技术,开发OFD电子文档阅读器

    前言 ofd作为板式文档规范,相当于国产化的pdf.由于pdf标准制定的较早,相关生态也比较完备,市面上的pdf阅读器种类繁多.国内ofd阅读器寥寥无几,作者此前采用wpf开发了一款阅读器,但该阅读器 ...

  9. 五个最佳RSS新闻阅读器

    文章出自http://www.williamlong.info/archives/1591.html 在博客和在线新闻充斥的互联网上,大量信息已经使得用户阅读量过载,幸运的是,通过RSS Feed提供 ...

随机推荐

  1. 【BZOJ 2460】线性基

    2460: [BeiJing2011]元素 Description 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法杖的法力 ...

  2. Linux的十个最危险的命令

    Linux命令行佷有用.很高效,也很有趣,但有时候也很危险,尤其是在你不确定你自己在正在做什么时候. 这篇文章将会向你介绍十条命令,但你最好不要尝试着去使用. 当然,以下命令通常都是在root权限下才 ...

  3. java23种设计模式之一: 代理模式(动态代理)

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  4. hdu 4111 Alice and Bob 记忆化搜索 博弈论

    Alice and Bob Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

  5. Cocoapods报错Unable to satisfy the following requirements

    很多时候我们都会去gitHub上down别人的源码去研究,如果别人的项目用pod集成了,当我们下载好后不外乎cd到项目根目录pod install一下,集成项目所需的库类.今天在我pod instal ...

  6. md5加密,md5加盐加密和解密

    package com.java.test; import java.security.MessageDigest; import java.security.SecureRandom; import ...

  7. UVA 11205 The broken pedometer(子集枚举)

    B - The broken pedometer Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu ...

  8. Matlab 2018b 新特性

    新特性简要介绍 一.实时编辑器 所创建的脚本不仅可以捕获代码,还可以讲述与人分享的故事.自动化的上下文提示可让您在编程时快速推进,并且将结果与可视化内容和您的代码一起显示. 二.App Designe ...

  9. JAVA RMI调用实战学习

    JAVA RMI 实战示例,参考网址: http://diaoge.iteye.com/blog/245170 这个示例很清楚地阐释了rmi的使用方法, 但示例都是放在一起的, 实际使用中我们可能会将 ...

  10. ASP.NET Core 1.0基础之应用启动

    来源https://docs.asp.net/en/latest/fundamentals/startup.html ASP.NET 5 使得应用对每个http请求有完整的控制权.Startup类是程 ...