zoukankan      html  css  js  c++  java
  • Web版RSS阅读器(五)——初步完成阅读功能

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




  • 相关阅读:
    appium---纯web app测试
    appium---元素定位工具
    appium---[ADB] Killing adb server on port 5037报错
    pytest---自定义用例识别规则
    pytest---用例执行顺序
    解决Could not find function xmlCheckVersion in library libxml2问题
    pytest---测试框架初探
    layoutSubviews何时被调用
    'addTimeInterval:' is deprecated: first deprecated in iOS 4.0
    iOS7 表格separatorInset的处理
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3285527.html
Copyright © 2011-2022 走看看