- 浏览: 87610 次
- 性别:
- 来自: 东莞
文章分类
最新评论
-
isaiahzhong:
没有效果,运行根本没有出来窗体,官网上 ...
Ext Viewport实例 -
allenping923:
新手。没看懂啊。
svn: PROPFIND 403 Forbidden问题的解决 -
liulei901112:
谢谢!
Error building results for action test in namespace问题已解决 -
whitesock:
skip-grant-tables除了禁止加载privileg ...
mysql error nr.1045 解决方法 -
yangzisai:
whitesock 写道这不是解决1045,而是如何处理忘记r ...
mysql error nr.1045 解决方法
在本章中将会介绍3个实例,首先分别使用Struts和Hibernate开发两个实例,帮助读者理解Struts和Hibernate各自单独的使用方法,最后将Struts和Hibernate结合起来,完成最终的实例。
本章介绍的3个例子都与RSS阅读器有关,RSS是在线共享内容的一种简易方式(Really Simple Syndication)。通常用于新闻和其他按时间先后顺序排列的网站,例如Blog。一个RSS包含很多新闻条目,一个新闻条目的介绍可能包含新闻的全部介绍,或者仅仅是额外的内容和简短的介绍。这些条目通常都能链接到全部的内容。使用RSS订阅能更快速获取信息,用户可以在客户端借助于支持RSS的阅读软件(例如SharpReader、NewzCrawler和FeedDemon这些软件),在不打开网站页面的情况下阅读支持RSS输出的网站内容。除了软件形式的RSS阅读器,在线网站形式的RSS阅读器也得到了广泛的应用,本章的实例就是实现简单的RSS在线网站阅读器。
第一个实例是纯粹采用Struts技术的简单RSS阅读器,用户通过输入RSS的地址来阅读此RSS中的文章信息,实例中没有采用数据库,所以不需要用到Hibernate。第二个实例是RSS自动更新器,此实例没有前台界面,仅仅使用了Hibernate来定时地对数据库中的RSS信息进行更新操作。第三个实例结合利用Struts和Hibernate,实现了一个有后台数据库支持的RSS在线阅读器。
12.1 RSS知识
RSS(Really Simple Syndication)是一种利用XML文件来发布网站内容的技术,它是一种对网站内容进行快速阅读的方式。当RSS技术没有出现的时候,用户要阅读新闻等信息,必须访问许多不同的特定网站,这对于很多人来说是一件费时的事情,但是有了RSS技术之后,用户可以通过RSS阅读器(软件或者网站形式)订阅RSS格式的Feed,从这些Feed中阅读需要的信息。同时由于RSS数据流很小,所以此技术也提高了信息的可访问性。
最初的0.90版本RSS是由Netscape公司设计的,目的是用来建立一个整合了各主要新闻站点内容的门户,但是0.90版本的RSS规范过于复杂,而一个简化的RSS 0.91版本也随着Netscape公司对该项目的放弃而于2000年暂停。
不久,一家专门从事博客写作软件开发的公司UserLand接手了RSS 0.91版本,并把它作为其博客写作软件的基础功能之一继续开发,逐步推出了0.92、0.93和0.94版本。随着网络博客的流行,RSS作为一种基本的功能也被越来越多的网站和博客软件支持。
在UserLand公司接手并不断开发RSS的同时,很多的专业人士认识到需要通过一个第三方、非商业的组织,把RSS发展成为一个通用的规范,并进一步标准化。于是2001年一个联合小组在0.90版本RSS的开发原则下,以W3C新一代的语义网技术RDF(Resource Description Framework)为基础,对RSS进行了重新定义,发布RSS1.0,并将RSS定义为“RDF Site Summary”。但是这项工作没有与UserLand公司进行有效的沟通,UserLand公司也不承认RSS 1.0的有效性,并坚持按照自己的设想进一步开发出RSS的后续版本,到2002年9月发布了最新版本RSS 2.0,UserLand公司将RSS定义为“Really Simple Syndication”。目前RSS已经分化为RSS 0.9x/2.0和RSS 1.0两个阵营,由于分歧的存在和RSS 0.9x/2.0的广泛应用现状,RSS 1.0还没有成为标准化组织的真正标准。在本章的实例中只考虑使用RSS 2.0标准。
RSS格式是符合标准的XML格式,RSS 2.0的语法是非常简单并且严格的,如下示例所示。
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="2.0">
<channel>
<title>W3Schools Home Page</title>
<link>http://www.w3schools.com</link>
<description>Free web building tutorials</description>
<item>
<title>RSS Tutorial</title>
<link>http://www.w3schools.com/rss</link>
<description>New RSS tutorial on W3Schools</description>
</item>
<item>
<title>XML Tutorial</title>
<link>http://www.w3schools.com/xml</link>
<description>New XML tutorial on W3Schools</description>
</item>
</channel>
</rss>
为网站提供RSS支持,就是为网站的内容生成如上所示的RSS格式的文件,可以手动编写此XML文件,也可以用工具自动生成此文件。
RSS文件的第一行表明了这是一个XML文件,并使用了XML 1.0标准和ISO-8859-1 (Latin-1/West European)字符集。
<?xml version="1.0" encoding="ISO-8859-1" ?>
第二行是RSS声明,说明这是一个RSS文件并且其版本为2.0。
<rss version="2.0">
<channel>元素定义了一个RSS的Feed,即频道。可以把一个Feed看作是一个网站,或者是网站的一个子内容。比如在新浪网的RSS“频道聚合”中,可以看到许多不同的Feed,对应了各个专门的新闻类别,如图12-1所示。
上图中的每个XML标记即对应了一个Feed,也就是这里所说的<channel>元素。
<channel>
<title>W3Schools Home Page</title>
<link>http://www.w3schools.com</link>
<description>Free web building tutorials</description>
图12-1
<channel>元素包括了3个必须的子元素:
<title> 定义频道的标题(比如“W3Schools Home Page”)。
<link> 定义频道的超链接地址(比如“http://www.w3schools.com”)。
<description> 对此频道的描述(比如“Free web building tutorials”)。
除了这些必须的元素之外,<channel>元素还有一些可选子元素,如表12-1所示。
表12-1 <channel>的可选子元素
元 素 名
描 述
元 素 名
描 述
<category>
定义feed的类别
<managingEditor>
Feed作者的邮件地址
<cloud>
定义feed更新之后的动作
<pubDate>
Feed的发布时间
<copyright>
版权信息
<rating>
Feed的PICS率
<docs>
Feed格式文档的URL
<skipDays>
定义RSS阅读器应该忽略的更新时间
<generator>
指明生成Feed的程序
<skipHours>
定义RSS阅读器应该忽略的更新时间(小时)
<image>
Feed的显示图像
<textInput>
Feed显示时的文字输入
<language>
Feed使用的语言
<ttl>
指定Feed的最小缓存数
<lastBuildDate>
Feed最后被修改的时间
<webMaster>
网站管理员的邮件地址
每个<channel>元素可以包含一个或多个<item>元素。每个<item>元素定义了在RSS Feed中的一篇文章。
<item>
<title>RSS Tutorial</title>
<link>http://www.w3schools.com/rss</link>
<description>New RSS tutorial on W3Schools</description>
</item>
<item>包括3个必须的子元素:
<title> 定义此文章的标题(比如“RSS Tutorial”)。
<link> 定义此文章的超链接地址(比如“http://www.w3schools.com/rss”)。
<description> 对文章的描述(比如“New RSS tutorial on W3Schools”)。
除了这些必须的元素之外,<item>元素还有一些可选子元素,如表12-2所示。
表12-2 <item>的可选子元素
元 素 名
描 述
元 素 名
描 述
<author>
文章作者
<guid>
文章的标示符
<category>
文章类别
<pubDate>
文章发布时间
<comments>
对文章的评论
<source>
文章的第三方源
<enclosure>
包含在文章中的其他类型文件
编写完成符合RSS格式的文件之后,就可以将此RSS文件发布在网上,并通过此RSS文件的URL来订阅。比如将上述的RSS文件发布到“www.w3schools.com/rss/myfirstrss.xml”之后,就可以通过此地址,订阅RSS Feed。
订阅RSS Feed可采用两种方式,第一种是使用RSS阅读软件,比如SharpReader,新浪点点通等。比如使用新浪点点通阅读器可以订阅多个Feed的内容,如图12-2所示。
图12-2
可以在其中添加Feed,如图12-3所示。
另一种是采用在线方式的RSS阅读器,比如Google Reader、Bloglines等。下面以Bloglines(www.bloglines.com)为例进行介绍,如图12-4所示。
同样可以在线的RSS阅读器中添加Feed,如图12-5所示。
图12-3
图12-4
12.2 利用Struts开发RSS在线阅读器
本节利用Struts实现一个简单的RSS在线阅读器。用户首先输入一个RSS Feed的地址,系统通过此地址得到Feed中所有的文章内容,并将文章的内容显示到页面上。由于此实例不需要数据库,所以没有采用Hibernate。
1.功能说明
(1)用户输入欲阅读的RSS Feed的地址,然后点击查看内容,系统找到用户输入的RSS文件,读取其中的内容,如图12-6所示。
图12-6
(2)若在此Feed中不存在文章,则显示“此Feed内目前没有包含文章”,如图12-7所示。
图12-7
(3)若Feed中存在文章,将文章的标题、作者和内容显示出来,并且将文章的列表作为文章的超链接,如图12-8所示。
图12-8
2.准备
此实例由于只采用了Struts,所以只要下载安装Struts,并将安装目录\lib目录下的各个.jar包和标签库中的tld文件导入工程。除了struts-config.xml和web.xml这两个配置文件之外。系统主要包括了以下主要部分:
(1)Item类:存放Feed中每一篇文章单元的内容,包括标题、作者、文章链接地址和文章内容。
(2)RssParser类:提供一个静态方法parseFeed()来解析feed中的内容,得到其中包含的所有文章。
(3)RssReaderAction类:根据用户输入的feed地址,调用RssParser中的方法得到所有的item,并将结果返回到页面。
(4)RssReardForm类:此form包含的主要成员为feed的地址,以及得到的一组item。
(5)Feed.jsp:此页面接受用户输入一个feed地址。
(6)List.jsp:此页面显示feed中包含的文章列表。
各部分集合之后如图12-9所示。
图12-9
3.实现
(1)首先,系统给用户展现一张Feed的输入页面(feed.jsp)。
<!-- 由于页面上采用中文,故需采用utf-8字符集 -->
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"
%>
<!-- 声明页面上使用struts的html, logic, bean标签库 -->
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>在线RSS阅读器</title>
</head>
<body>
<!-- 此form接受用户输入一个feed地址 -->
<html:form action="feed" method="post">
<table border="0" cellspacing="0" cellpadding="0" align="left">
<tr>
<td>请输入RSS Feed地址:</td>
<!-- 采用html:text标签来定义一个输入框 -->
<td><html:text property="address" /></td>
</tr>
<tr>
<!-- 采用html:submit来提交表单 -->
<td><html:submit property="login" value="查看内容" /></td>
</tr>
</table>
</html:form>
</body>
</html>
页面上定义了用于提交用户输入的Feed地址的form:
<html:form action="feed" method="post">
此form中包含一个输入框用,以得到用户输入的Feed地址:
<html:text property="address" />
当此form提交的时候,就会将此请求发送给“feed”对应的Action类去处理,即RssReaderAction。
(2)RssReaderAction类得到此请求之后,首先从Form中得到用户输入的Feed地址:
//得到对应的RssReaderForm
RssReaderForm rssReaderForm = (RssReaderForm) form;
//得到用户输入的rss feed地址
String address = rssReaderForm.getAddress();
然后用此地址作为参数调用RssParser类的parseFeed方法,此方法是一个静态方法,其作用是去访问此地址的RSS文件,并解析其中的文章内容,将里面所有的文章内容作为参数返回,返回值为List类型。
List items = RssParser.parseFeed(address);
通过上述的调用方式就得到了用户输入Feed地址中的文章列表(此列表有可能为空),接着,将得到的列表设置到form中,以供list.jsp页面显示。
rssReaderForm.setItems(items);
最后,RssReaderAction作跳转,前进到list.jsp页面。
return mapping.findForward("list");
下面是RssReaderAction类的完整代码。
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
* @author Chao Wu
*
* Description:
* <p>RssReaderAction类处理的主要工作是根据用户输入的feed地址,调用RssParser中的方法得到所有的item,并将
* 结果返回到页面
*
* Copyright:
* <p>
*/
public class RssReaderAction extends Action {
/**
* 此方法得到form的address属性,并调用RssParser的parseFeed方法,将得到的List赋到form中之后,做页面跳转
* @param mapping
* @param form
* @param req
* @param res
* @return
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
//得到对应的RssReaderForm
RssReaderForm rssReaderForm = (RssReaderForm) form;
//得到用户输入的rss feed地址
String address = rssReaderForm.getAddress();
//调用RssParser的parseFeed方法,解析此feed,若此feed不存在,或者发生了异常错误,返回为空List;
//否则返回包含文章列表的List
List items = RssParser.parseFeed(address);
//将返回的item的列表赋到form中
rssReaderForm.setItems(items);
//跳转到list.jsp
return mapping.findForward("list");
}
}
下面是RssReaderForm类的完整代码。
import java.util.List;
import org.apache.struts.action.ActionForm;
/**
* @author Chao Wu
*
* Description:
* <p>此form包含的主要成员为feed的地址,以及得到的一组item
*
* Copyright:
* <p>
*/
public class RssReaderForm extends ActionForm {
private static final long serialVersionUID = 1L;
//从feed中得到的一组item
private List items;
//feed的地址
private String address;
//以下为items和address的get和set方法
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List getItems() {
return items;
}
public void setItems(List items) {
this.items = items;
}
}
(3)RssReaderAction处理完毕之后,就会前进到list.jsp页面,这张页面的主要作用就是显示解析出来的文章列表。页面上主要调用了以下的struts标签:
Logic:empty标签 处理当文章列表为空的情况。
Logic:notEmpty标签 当文章列表不为空的时候,显示文章列表。
Logic:iterate标签 循环显示文章列表中的内容。
Bean:write标签 显示文章的标题、链接、作者和内容。
List.jsp的内容如下所示。
<!-- 由于页面上采用中文,故需采用utf-8字符集 -->
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- 声明页面上使用struts的html, logic, bean标签库 -->
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<!-- 此页面显示feed中包含的文章列表 -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>在线RSS阅读器</title>
</head>
<body>
<!-- 若没有得到文章,则显示提示信息,使用logic:empty标签来实现此功能 -->
<logic:empty name="rssReaderForm" property="items">
<center><strong>此Feed内目前没有包含文章</strong></center>
</logic:empty>
<!-- 若文章列表不为空,则循环显示每篇文章的题目、作者、链接和内容 -->
<logic:notEmpty name="rssReaderForm" property="items">
<center><strong>文章列表:</strong></center>
<br>
<!-- 使用logic:iterate标签循环显示文章 -->
<logic:iterate indexId="index" id="item" name="rssReaderForm" property="items">
<table>
<tr>
<!-- 分别得到item的title, url和author信息 -->
<td noWrap class="allcapsCenter">
<strong>标题:</strong>
<A href="<bean:write name='item' property='url' />">
<bean:write name="item" property="title" />
</A>
(<strong>by: </strong><bean:write name="item" property="author" />)
</td>
</tr>
<tr>
<!-- 显示文章内容 -->
<td noWrap class="allcapsCenter">
<bean:write name="item" property="description" />
</td>
<tr>
</table>
<br>
</logic:iterate>
</logic:notEmpty>
</TABLE>
</body>
</html>
其中下面代码的作用是从form中取出的items列表,判断其是否为空,如果为空的话,则显示字符串“此Feed内目前没有包含文章”。
<logic:empty name="rssReaderForm" property="items">
<center><strong>此Feed内目前没有包含文章</strong></center>
</logic:empty>
显示效果如图12-10所示。
图12-10
若items列表不为空,则使用logic:iterate标签:
<logic:notEmpty name="rssReaderForm" property="items">
<center><strong>文章列表:</strong></center>
<br>
<!-- 使用logic:iterate标签循环显示文章 -->
<logic:iterate indexId="index" id="item" name="rssReaderForm" property="items">
在logic:iterate中嵌套的是每一篇文章的具体信息,iterate标签循环遍历form中的items集合,将集合中的对象命名为“item”。在嵌套的语句中,就可以用“item”的属性来得到需要显示的文章标题和作者等信息。
<A href="<bean:write name='item' property='url' />">
<bean:write name="item" property="title" />
</A>
(<strong>by: </strong><bean:write name="item" property="author" />)
在上面的代码中,文章的链接地址用bean:write标签得到,并且嵌入在<a>标签中作为链接地址,从中可以看出,struts的标签可以嵌套在普通的html标签中。
通过这种方式,就可以在页面上显示Feed中包含的文章,如图12-11所示。
图12-11
(4)RssParser类用来解析RSS格式的XML文件,将其中的文章列表返回。定义Item来存放文章信息,每一个Item对象,对应了Feed中的一篇文章。Item类是一个简单的JavaBean,其中包含了4个成员:
Title 文章标题。
Description 文章内容。
Author 作者。
Url 全文链接地址。
这些成员的getter和setter方法,代码如下所示。
/**
* @author Chao Wu
*
* Description:
* <p>Item类存放Feed中每一篇文章单元的内容,包括标题、作者、文章链接地址和文章内容
*
* Copyright:
* <p>
*/
public class Item {
private String title; //文章标题
private String description; //文章内容
private String author; //作者
private String url; //全文链接地址
//Item的构造函数
public Item(String title, String description, String author, String url)
{
this.title = title;
this.description = description;
this.author = author;
this.url = url;
}
//以下为title,description,author和url四个成员的get和set方法
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
RssParser类中提供了一个静态方法parseFeed()来解析Feed地址。
public static List parseFeed(String address)
此方法的主要思路为:RSS格式文件是标准的XML文件格式,所以可以通过标准的XML读取方式来访问其中的内容。在这里使用SAX方式来访问XML文件的内容。首先定义返回的文章列表。
List result = new ArrayList();
接着定义DocumentBuilderFactory,DocumentBuilder和Document,用以解析代表rss feed的XML文件,并通过DocumentBuilderFactory.newInstance()方法得到DocumentBuilderFactory对象。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
Document doc;
然后利用DocumentBuilderFactory对象的newDocumentBuilder方法得到DocumentBuilder对象,此DocumentBuilder对象的作用是根据xml文件的url地址生成Document对象。
db = dbf.newDocumentBuilder();
doc对象包含需要解析的feed的xml文件。
doc = db.parse(address);
feed的xml文件的组成单位是item,从doc中取出所有的item。
NodeList nl = doc.getElementsByTagName("item");
接着遍历这些item,取得其中的title, author, description和url等信息。
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
NodeList nl2 = node.getChildNodes();
Node nodeTitle = nl2.item(1);
Node nodeAuthor = nl2.item(2);
Node nodeUrl = nl2.item(3);
Node nodeDescription = nl2.item(4);
通过得到的title、author、description和url构造Item对象。
Item item = new Item(title, description, author, url);
最后将生成的item放到result中,以便返回。
result.add(item);
下面是此方法的完整代码。
/*
* Created on
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* @author Chao Wu
*
* Description:
* <p>RssParser类提供一个静态方法parseFeed()来解析某feed中的内容,得到其中包含的所有文章
*
* Copyright:
* <p>
*/
public class RssParser {
public static List parseFeed(String address) {
//result包含从feed中得到的一组Item对象
List result = new ArrayList();
//定义DocumentBuilderFactory,DocumentBuilder和Document,用以解析代表rss feed的XML文件
//通过DocumentBuilderFactory.newInstance()方法得到Document-
BzuilderFactory对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newIns-
tance();
DocumentBuilder db;
Document doc;
try {
//利用DocumentBuilderFactory对象的newDocumentBuilder方法得到DocumentBuilder对象
//此DocumentBuilder对象的作用是根据xml文件的url地址生成Document对象
db = dbf.newDocumentBuilder();
//doc对象包含需要解析的feed的xml文件
doc = db.parse(address);
//feed的xml文件的组成单位是item,从doc中取出所有的item
NodeList nl = doc.getElementsByTagName("item");
//遍历这些item,取得其中的title, author, description和url等信息
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
NodeList nl2 = node.getChildNodes();
Node nodeTitle = nl2.item(1);
Node nodeAuthor = nl2.item(2);
Node nodeUrl = nl2.item(3);
Node nodeDescription = nl2.item(4);
String title = nodeTitle.getFirstChild().getNodeValue();
String description = nodeDescription.getFirstChild(). getNodeValue();
String author = nodeAuthor.getFirstChild().getNode-
Value();
String url = nodeUrl.getFirstChild().getNodeValue();
//通过得到的title, author, description和url构造Item对象
Item item = new Item(title, description, author, url);
//将生成的item放到result中,以便返回
result.add(item);
}
} catch (ParserConfigurationException e) {
//处理ParserCOnfigurationException异常,输出异常信息
e.printStackTrace();
} catch (SAXException e) {
// 处理SAXException异常,输出异常信息
e.printStackTrace();
} catch (IOException e) {
// 处理IOException异常,输出异常信息
e.printStackTrace();
} finally {
//将结果返回,result数组可能为空
return result;
}
}
}
至此,整个开发过程就此完成。
最后将web.xml和struts-config.xml两个配置文件的内容展示如下。
Web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http: //java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>WebRssReader</display-name>
<!-- 指定使用struts的servlet -->
<servlet>
<!-- 当有请求发送到名为action的servlet时,使用org.apache.struts. action.ActionServlet来处理此请求 -->
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</ser-
vlet-class>
<init-param>
<!-- struts的配置文件struts-config.xml所在位置 -->
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- 将url结尾为.do的请求发送到action所在的servlet -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 初始页面为feed.jsp页面 -->
<welcome-file-list>
<welcome-file>feed.jsp</welcome-file>
</welcome-file-list>
<!-- 声明struts的bean, html, logic, nested标签库 -->
<taglib>
<taglib-uri>/tags/struts-bean</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-html</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-logic</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-nested</taglib-uri>
<taglib-location>/WEB-INF/struts-nested.tld</taglib-location>
</taglib>
</web-app>
Struts-config.xml:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<!--
NOTE: If you have a generator tool to create the corresponding Java classes
for you, you could include the details in the "form-bean" declarations.
Otherwise, you would only define the "form-bean" element itself, with the
corresponding "name" and "type" attributes, as shown here.
-->
<struts-config>
<!-- 在此定义FormBean,FormBean的位置为RssReaderForm,命名为rssReaderForm -->
<form-beans>
<form-bean name="rssReaderForm" type="RssReaderForm" />
</form-beans>
<!-- 定义Action的ActionMapping -->
<action-mappings>
<!—Action中定义RssReaderAction对应的FormBean为rssReaderForm -->
<action name="rssReaderForm" path="/feed" type="RssReaderAction">
<forward name="feed" path="/feed.jsp"></forward>
<forward name="list" path="/list.jsp"></forward>
</action>
</action-mappings>
</struts-config>
12.3 利用Hibernate完成RSS自动更新
本节单独使用Hibernate来操作数据库,通过这个实例,读者可以看到,Hibernate虽然一般用于Web应用的数据访问,但其功能是独立与前台的,无论是Web、Rich Client还是单机应用都可以利用Hibernate来做数据库操作。
本实例的功能是自动获取RSS的更新,系统的数据库中存放了一系列的RSS地址,程序定时地访问数据库,根据这些RSS地址,得到其中的文章列表。
系统主要包括了以下主要部分:
(1)Hibernate的配置文件:hibernate.cfg.xml。
(2)对应数据库feeds表的Feed对象,以及映射文件feed.hbm.xml。
(3)用于解析feed内容的RssParser类和Item类。
(4)用于自动更新的线程UpdateThread。
(5)测试类Test。
系统整体框架如图12-12所示。下面分析整个系统的各个组成部分。
(1)首先需要建立数据库,在MySQL中建立新的schema,命名为feed,并在其中建立表feeds,采用的ddl如下所示。
CREATE TABLE 'feed'.'feeds' (
'url' varchar(80) NOT NULL default '',
PRIMARY KEY ('url')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
图12-12
表feeds仅包含一个字段,即RSS Feed的地址Url。
(2)新建一个Java工程,下载Hibernate,将其中的包导入到工程中,并且配置Hibernate。建立Hibernate配置文件——hibernate.cfg.xml,代码如下所示。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="java:/hibernate/HibernateFactory">
<property name="show_sql">true</property>
<property name="connection.driver_class">
org.gjt.mm.mysql.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost/feed
</property>
<property name="connection.username"></property>
<property name="connection.password"></property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<mapping resource="Feed.hbm.xml" />
</session-factory>
</hibernate-configuration>
本工程只有一个映射文件Feed.hbm.xml。
(3)建立数据库feeds表对应的VO——Feed类,以及其映射文件。Feed类只包含一个成员,因为数据库对应的表也仅有一个字段。
/**
* @author Chao Wu
*
* Description:
* <p>Hibernate的VO类,每个Feed对象对应数据库feeds表中的一条记录
*
* Copyright:
* <p>
*/
public class Feed { //VO是一个普通的JavaBean
private String url; //Feed的地址
//以下为url的get和set方法
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Feed.hbm.xml配置了Feed类和feeds表之间的映射关系。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Feed" table="feeds">
<id name="url" column="url" />
</class>
</hibernate-mapping>
主键用id定义,在此处为url。
(4)RssParser类和Item类的功能与内容与前一个实例相同,在这里不再赘述。
(5)新建FeedUpdate类,此类的提供一个静态方法getFeedList()以更新某一个feed地址中的文章列表。
由于需要使用Hibernate进行数据库操作,所以首先要引入Hibernate所需要的包。
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
在getFeedList()方法中,首先根据hibernate.cfg.xml中的信息,生成SessionFactory对象,并利用SessionFactory对象生成到数据库的session连接。
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session session = sf.openSession();
接着定义一个事务transaction,将数据库操作包含在一个事务中。
Transaction tx = session.beginTransaction();
定义查询语句,从数据库中得到所有的Feed信息。
String sqlQuery = "select f from Feed f";
Query lQuery = session.createQuery(sqlQuery);
feedList = (ArrayList) lQuery.list();
最后将查询到的结果返回,完整的代码如下所示。
import java.util.ArrayList;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
* @author Chao Wu
*
* Description:
* <p>FeedUpdate类提供一个静态方法getFeedList()来取得数据库中Feed数据
*
* Copyright:
* <p>
*/
public class FeedUpdate {
//静态方法getFeedList(),从数据库中取出所有的Feed,并将结果作为一个List返回
public static List getFeedList() {
List feedList;
try {
//Configruation根据hibernate.cfg.xml中的信息,生成Sessio-
nFactory对象
SessionFactory sf = new Configuration().configure().bui-
ldSessionFactory();
//利用SessionFactory对象生成到数据库的session连接
Session session = sf.openSession();
//开始一个事务transaction,数据库操作包含在一个事务中
Transaction tx = session.beginTransaction();
//查询字符串,得到feeds表中所有的记录
String sqlQuery = "select f from Feed f";
//根据查询语句,生成Query对象
Query lQuery = session.createQuery(sqlQuery);
//得到查询结果
feedList = (ArrayList) lQuery.list();
//提交事务
tx.commit();
//关闭session连接
session.close();
//返回得到结果
return feedList;
} catch (HibernateException e) {
//若发生HibernateException,则显示异常信息,并返回null
e.printStackTrace();
return null;
}
}
}
(6)利用Java多线程的功能,新建一个线程类UpdateThread,代码如下所示。
import java.util.List;
public class UpdateThread extends Thread {
boolean keepRunning = true;
long lRefreshInterval = 10000;
public void run() {
while (keepRunning) {
try {
List feedList = FeedUpdate.getFeedList();
// 如果getFeedList方法中发生了异常,返回的feedList为null,则程序返回
if (feedList == null) {
return;
}
// 打印List中包含的feed数量
System.out.println("Size of feedList: " + feedList.size());
// 对每个Feed,得到其中的所有文章
for (int i = 0; i < feedList.size(); i++) {
// 得到每一个Feed对象
Feed feed = (Feed) feedList.get(i);
// 得到其url地址
String address = feed.getUrl();
// 取得feed中所有的文章
List items = RssParser.parseFeed(address);
// 打印feed中包含的文章数量
System.out.println("Items in feed of '" + address + "': "
+ items.size());
}
Thread.sleep(lRefreshInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void stopRunning() {
keepRunning = false;
}
}
其中UpdateThread类继承了Thread,所以可以作为单独的线程运行。
public class UpdateThread extends Thread {
在UpdateThread类中,定义了两个成员变量。其中keepRunning为线程运行的标志位,一开始设置为true,一旦希望线程停止,就将keepRunning设置为false。另一个变量lRefreshInterval制定了自动更新的时间间隔。
boolean keepRunning = true;
long lRefreshInterval = 10000;
UpdateThread类中重载了Thread类的Run方法。
public void run() {
……
}
Run方法的内容是当此线程运行之后要做的行为,所以将主要的操作都放置在Run方法中。在Run方法中,首先调用UpdateFeed的getFeedList方法,得到数据库中的Feed列表。
List feedList = FeedUpdate.getFeedList();
然后对列表中的每一个feed地址,调用RssParser的parseFeed()方法得到其中的文章列表。
for (int i = 0; i < feedList.size(); i++) {
// 得到每一个Feed对象
Feed feed = (Feed) feedList.get(i);
// 得到其url地址
String address = feed.getUrl();
// 取得feed中所有的文章
List items = RssParser.parseFeed(address);
这样就实现了自动对数据库列表中Feed包含文章的自动更新。
在完成更新操作之后,调用Thread.sleep()方法让线程睡眠一段时间,等睡眠时间结束之后继续下一次的更新操作。
Thread.sleep(lRefreshInterval);
stopRunning方法设置keepRunning为false,当keepRunning为false的时候,线程不在继续。
public void stopRunning() {
keepRunning = false;
}
(7)编写测试类,测试自动更新线程是否正常运行,代码如下所示。
import java.util.List;
/**
* @author Chao Wu
* Description:
* Copyright:
* <p>
*/
public class Test {
public static void main(String[] args) {
UpdateThread updateThread = new UpdateThread();
updateThread.start();
}
}
至此,完成了本实例。
http://book.csdn.net/bookfiles/377/10037714193.shtml
本章介绍的3个例子都与RSS阅读器有关,RSS是在线共享内容的一种简易方式(Really Simple Syndication)。通常用于新闻和其他按时间先后顺序排列的网站,例如Blog。一个RSS包含很多新闻条目,一个新闻条目的介绍可能包含新闻的全部介绍,或者仅仅是额外的内容和简短的介绍。这些条目通常都能链接到全部的内容。使用RSS订阅能更快速获取信息,用户可以在客户端借助于支持RSS的阅读软件(例如SharpReader、NewzCrawler和FeedDemon这些软件),在不打开网站页面的情况下阅读支持RSS输出的网站内容。除了软件形式的RSS阅读器,在线网站形式的RSS阅读器也得到了广泛的应用,本章的实例就是实现简单的RSS在线网站阅读器。
第一个实例是纯粹采用Struts技术的简单RSS阅读器,用户通过输入RSS的地址来阅读此RSS中的文章信息,实例中没有采用数据库,所以不需要用到Hibernate。第二个实例是RSS自动更新器,此实例没有前台界面,仅仅使用了Hibernate来定时地对数据库中的RSS信息进行更新操作。第三个实例结合利用Struts和Hibernate,实现了一个有后台数据库支持的RSS在线阅读器。
12.1 RSS知识
RSS(Really Simple Syndication)是一种利用XML文件来发布网站内容的技术,它是一种对网站内容进行快速阅读的方式。当RSS技术没有出现的时候,用户要阅读新闻等信息,必须访问许多不同的特定网站,这对于很多人来说是一件费时的事情,但是有了RSS技术之后,用户可以通过RSS阅读器(软件或者网站形式)订阅RSS格式的Feed,从这些Feed中阅读需要的信息。同时由于RSS数据流很小,所以此技术也提高了信息的可访问性。
最初的0.90版本RSS是由Netscape公司设计的,目的是用来建立一个整合了各主要新闻站点内容的门户,但是0.90版本的RSS规范过于复杂,而一个简化的RSS 0.91版本也随着Netscape公司对该项目的放弃而于2000年暂停。
不久,一家专门从事博客写作软件开发的公司UserLand接手了RSS 0.91版本,并把它作为其博客写作软件的基础功能之一继续开发,逐步推出了0.92、0.93和0.94版本。随着网络博客的流行,RSS作为一种基本的功能也被越来越多的网站和博客软件支持。
在UserLand公司接手并不断开发RSS的同时,很多的专业人士认识到需要通过一个第三方、非商业的组织,把RSS发展成为一个通用的规范,并进一步标准化。于是2001年一个联合小组在0.90版本RSS的开发原则下,以W3C新一代的语义网技术RDF(Resource Description Framework)为基础,对RSS进行了重新定义,发布RSS1.0,并将RSS定义为“RDF Site Summary”。但是这项工作没有与UserLand公司进行有效的沟通,UserLand公司也不承认RSS 1.0的有效性,并坚持按照自己的设想进一步开发出RSS的后续版本,到2002年9月发布了最新版本RSS 2.0,UserLand公司将RSS定义为“Really Simple Syndication”。目前RSS已经分化为RSS 0.9x/2.0和RSS 1.0两个阵营,由于分歧的存在和RSS 0.9x/2.0的广泛应用现状,RSS 1.0还没有成为标准化组织的真正标准。在本章的实例中只考虑使用RSS 2.0标准。
RSS格式是符合标准的XML格式,RSS 2.0的语法是非常简单并且严格的,如下示例所示。
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="2.0">
<channel>
<title>W3Schools Home Page</title>
<link>http://www.w3schools.com</link>
<description>Free web building tutorials</description>
<item>
<title>RSS Tutorial</title>
<link>http://www.w3schools.com/rss</link>
<description>New RSS tutorial on W3Schools</description>
</item>
<item>
<title>XML Tutorial</title>
<link>http://www.w3schools.com/xml</link>
<description>New XML tutorial on W3Schools</description>
</item>
</channel>
</rss>
为网站提供RSS支持,就是为网站的内容生成如上所示的RSS格式的文件,可以手动编写此XML文件,也可以用工具自动生成此文件。
RSS文件的第一行表明了这是一个XML文件,并使用了XML 1.0标准和ISO-8859-1 (Latin-1/West European)字符集。
<?xml version="1.0" encoding="ISO-8859-1" ?>
第二行是RSS声明,说明这是一个RSS文件并且其版本为2.0。
<rss version="2.0">
<channel>元素定义了一个RSS的Feed,即频道。可以把一个Feed看作是一个网站,或者是网站的一个子内容。比如在新浪网的RSS“频道聚合”中,可以看到许多不同的Feed,对应了各个专门的新闻类别,如图12-1所示。
上图中的每个XML标记即对应了一个Feed,也就是这里所说的<channel>元素。
<channel>
<title>W3Schools Home Page</title>
<link>http://www.w3schools.com</link>
<description>Free web building tutorials</description>
图12-1
<channel>元素包括了3个必须的子元素:
<title> 定义频道的标题(比如“W3Schools Home Page”)。
<link> 定义频道的超链接地址(比如“http://www.w3schools.com”)。
<description> 对此频道的描述(比如“Free web building tutorials”)。
除了这些必须的元素之外,<channel>元素还有一些可选子元素,如表12-1所示。
表12-1 <channel>的可选子元素
元 素 名
描 述
元 素 名
描 述
<category>
定义feed的类别
<managingEditor>
Feed作者的邮件地址
<cloud>
定义feed更新之后的动作
<pubDate>
Feed的发布时间
<copyright>
版权信息
<rating>
Feed的PICS率
<docs>
Feed格式文档的URL
<skipDays>
定义RSS阅读器应该忽略的更新时间
<generator>
指明生成Feed的程序
<skipHours>
定义RSS阅读器应该忽略的更新时间(小时)
<image>
Feed的显示图像
<textInput>
Feed显示时的文字输入
<language>
Feed使用的语言
<ttl>
指定Feed的最小缓存数
<lastBuildDate>
Feed最后被修改的时间
<webMaster>
网站管理员的邮件地址
每个<channel>元素可以包含一个或多个<item>元素。每个<item>元素定义了在RSS Feed中的一篇文章。
<item>
<title>RSS Tutorial</title>
<link>http://www.w3schools.com/rss</link>
<description>New RSS tutorial on W3Schools</description>
</item>
<item>包括3个必须的子元素:
<title> 定义此文章的标题(比如“RSS Tutorial”)。
<link> 定义此文章的超链接地址(比如“http://www.w3schools.com/rss”)。
<description> 对文章的描述(比如“New RSS tutorial on W3Schools”)。
除了这些必须的元素之外,<item>元素还有一些可选子元素,如表12-2所示。
表12-2 <item>的可选子元素
元 素 名
描 述
元 素 名
描 述
<author>
文章作者
<guid>
文章的标示符
<category>
文章类别
<pubDate>
文章发布时间
<comments>
对文章的评论
<source>
文章的第三方源
<enclosure>
包含在文章中的其他类型文件
编写完成符合RSS格式的文件之后,就可以将此RSS文件发布在网上,并通过此RSS文件的URL来订阅。比如将上述的RSS文件发布到“www.w3schools.com/rss/myfirstrss.xml”之后,就可以通过此地址,订阅RSS Feed。
订阅RSS Feed可采用两种方式,第一种是使用RSS阅读软件,比如SharpReader,新浪点点通等。比如使用新浪点点通阅读器可以订阅多个Feed的内容,如图12-2所示。
图12-2
可以在其中添加Feed,如图12-3所示。
另一种是采用在线方式的RSS阅读器,比如Google Reader、Bloglines等。下面以Bloglines(www.bloglines.com)为例进行介绍,如图12-4所示。
同样可以在线的RSS阅读器中添加Feed,如图12-5所示。
图12-3
图12-4
12.2 利用Struts开发RSS在线阅读器
本节利用Struts实现一个简单的RSS在线阅读器。用户首先输入一个RSS Feed的地址,系统通过此地址得到Feed中所有的文章内容,并将文章的内容显示到页面上。由于此实例不需要数据库,所以没有采用Hibernate。
1.功能说明
(1)用户输入欲阅读的RSS Feed的地址,然后点击查看内容,系统找到用户输入的RSS文件,读取其中的内容,如图12-6所示。
图12-6
(2)若在此Feed中不存在文章,则显示“此Feed内目前没有包含文章”,如图12-7所示。
图12-7
(3)若Feed中存在文章,将文章的标题、作者和内容显示出来,并且将文章的列表作为文章的超链接,如图12-8所示。
图12-8
2.准备
此实例由于只采用了Struts,所以只要下载安装Struts,并将安装目录\lib目录下的各个.jar包和标签库中的tld文件导入工程。除了struts-config.xml和web.xml这两个配置文件之外。系统主要包括了以下主要部分:
(1)Item类:存放Feed中每一篇文章单元的内容,包括标题、作者、文章链接地址和文章内容。
(2)RssParser类:提供一个静态方法parseFeed()来解析feed中的内容,得到其中包含的所有文章。
(3)RssReaderAction类:根据用户输入的feed地址,调用RssParser中的方法得到所有的item,并将结果返回到页面。
(4)RssReardForm类:此form包含的主要成员为feed的地址,以及得到的一组item。
(5)Feed.jsp:此页面接受用户输入一个feed地址。
(6)List.jsp:此页面显示feed中包含的文章列表。
各部分集合之后如图12-9所示。
图12-9
3.实现
(1)首先,系统给用户展现一张Feed的输入页面(feed.jsp)。
<!-- 由于页面上采用中文,故需采用utf-8字符集 -->
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"
%>
<!-- 声明页面上使用struts的html, logic, bean标签库 -->
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>在线RSS阅读器</title>
</head>
<body>
<!-- 此form接受用户输入一个feed地址 -->
<html:form action="feed" method="post">
<table border="0" cellspacing="0" cellpadding="0" align="left">
<tr>
<td>请输入RSS Feed地址:</td>
<!-- 采用html:text标签来定义一个输入框 -->
<td><html:text property="address" /></td>
</tr>
<tr>
<!-- 采用html:submit来提交表单 -->
<td><html:submit property="login" value="查看内容" /></td>
</tr>
</table>
</html:form>
</body>
</html>
页面上定义了用于提交用户输入的Feed地址的form:
<html:form action="feed" method="post">
此form中包含一个输入框用,以得到用户输入的Feed地址:
<html:text property="address" />
当此form提交的时候,就会将此请求发送给“feed”对应的Action类去处理,即RssReaderAction。
(2)RssReaderAction类得到此请求之后,首先从Form中得到用户输入的Feed地址:
//得到对应的RssReaderForm
RssReaderForm rssReaderForm = (RssReaderForm) form;
//得到用户输入的rss feed地址
String address = rssReaderForm.getAddress();
然后用此地址作为参数调用RssParser类的parseFeed方法,此方法是一个静态方法,其作用是去访问此地址的RSS文件,并解析其中的文章内容,将里面所有的文章内容作为参数返回,返回值为List类型。
List items = RssParser.parseFeed(address);
通过上述的调用方式就得到了用户输入Feed地址中的文章列表(此列表有可能为空),接着,将得到的列表设置到form中,以供list.jsp页面显示。
rssReaderForm.setItems(items);
最后,RssReaderAction作跳转,前进到list.jsp页面。
return mapping.findForward("list");
下面是RssReaderAction类的完整代码。
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
* @author Chao Wu
*
* Description:
* <p>RssReaderAction类处理的主要工作是根据用户输入的feed地址,调用RssParser中的方法得到所有的item,并将
* 结果返回到页面
*
* Copyright:
* <p>
*/
public class RssReaderAction extends Action {
/**
* 此方法得到form的address属性,并调用RssParser的parseFeed方法,将得到的List赋到form中之后,做页面跳转
* @param mapping
* @param form
* @param req
* @param res
* @return
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
//得到对应的RssReaderForm
RssReaderForm rssReaderForm = (RssReaderForm) form;
//得到用户输入的rss feed地址
String address = rssReaderForm.getAddress();
//调用RssParser的parseFeed方法,解析此feed,若此feed不存在,或者发生了异常错误,返回为空List;
//否则返回包含文章列表的List
List items = RssParser.parseFeed(address);
//将返回的item的列表赋到form中
rssReaderForm.setItems(items);
//跳转到list.jsp
return mapping.findForward("list");
}
}
下面是RssReaderForm类的完整代码。
import java.util.List;
import org.apache.struts.action.ActionForm;
/**
* @author Chao Wu
*
* Description:
* <p>此form包含的主要成员为feed的地址,以及得到的一组item
*
* Copyright:
* <p>
*/
public class RssReaderForm extends ActionForm {
private static final long serialVersionUID = 1L;
//从feed中得到的一组item
private List items;
//feed的地址
private String address;
//以下为items和address的get和set方法
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List getItems() {
return items;
}
public void setItems(List items) {
this.items = items;
}
}
(3)RssReaderAction处理完毕之后,就会前进到list.jsp页面,这张页面的主要作用就是显示解析出来的文章列表。页面上主要调用了以下的struts标签:
Logic:empty标签 处理当文章列表为空的情况。
Logic:notEmpty标签 当文章列表不为空的时候,显示文章列表。
Logic:iterate标签 循环显示文章列表中的内容。
Bean:write标签 显示文章的标题、链接、作者和内容。
List.jsp的内容如下所示。
<!-- 由于页面上采用中文,故需采用utf-8字符集 -->
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- 声明页面上使用struts的html, logic, bean标签库 -->
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<!-- 此页面显示feed中包含的文章列表 -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>在线RSS阅读器</title>
</head>
<body>
<!-- 若没有得到文章,则显示提示信息,使用logic:empty标签来实现此功能 -->
<logic:empty name="rssReaderForm" property="items">
<center><strong>此Feed内目前没有包含文章</strong></center>
</logic:empty>
<!-- 若文章列表不为空,则循环显示每篇文章的题目、作者、链接和内容 -->
<logic:notEmpty name="rssReaderForm" property="items">
<center><strong>文章列表:</strong></center>
<br>
<!-- 使用logic:iterate标签循环显示文章 -->
<logic:iterate indexId="index" id="item" name="rssReaderForm" property="items">
<table>
<tr>
<!-- 分别得到item的title, url和author信息 -->
<td noWrap class="allcapsCenter">
<strong>标题:</strong>
<A href="<bean:write name='item' property='url' />">
<bean:write name="item" property="title" />
</A>
(<strong>by: </strong><bean:write name="item" property="author" />)
</td>
</tr>
<tr>
<!-- 显示文章内容 -->
<td noWrap class="allcapsCenter">
<bean:write name="item" property="description" />
</td>
<tr>
</table>
<br>
</logic:iterate>
</logic:notEmpty>
</TABLE>
</body>
</html>
其中下面代码的作用是从form中取出的items列表,判断其是否为空,如果为空的话,则显示字符串“此Feed内目前没有包含文章”。
<logic:empty name="rssReaderForm" property="items">
<center><strong>此Feed内目前没有包含文章</strong></center>
</logic:empty>
显示效果如图12-10所示。
图12-10
若items列表不为空,则使用logic:iterate标签:
<logic:notEmpty name="rssReaderForm" property="items">
<center><strong>文章列表:</strong></center>
<br>
<!-- 使用logic:iterate标签循环显示文章 -->
<logic:iterate indexId="index" id="item" name="rssReaderForm" property="items">
在logic:iterate中嵌套的是每一篇文章的具体信息,iterate标签循环遍历form中的items集合,将集合中的对象命名为“item”。在嵌套的语句中,就可以用“item”的属性来得到需要显示的文章标题和作者等信息。
<A href="<bean:write name='item' property='url' />">
<bean:write name="item" property="title" />
</A>
(<strong>by: </strong><bean:write name="item" property="author" />)
在上面的代码中,文章的链接地址用bean:write标签得到,并且嵌入在<a>标签中作为链接地址,从中可以看出,struts的标签可以嵌套在普通的html标签中。
通过这种方式,就可以在页面上显示Feed中包含的文章,如图12-11所示。
图12-11
(4)RssParser类用来解析RSS格式的XML文件,将其中的文章列表返回。定义Item来存放文章信息,每一个Item对象,对应了Feed中的一篇文章。Item类是一个简单的JavaBean,其中包含了4个成员:
Title 文章标题。
Description 文章内容。
Author 作者。
Url 全文链接地址。
这些成员的getter和setter方法,代码如下所示。
/**
* @author Chao Wu
*
* Description:
* <p>Item类存放Feed中每一篇文章单元的内容,包括标题、作者、文章链接地址和文章内容
*
* Copyright:
* <p>
*/
public class Item {
private String title; //文章标题
private String description; //文章内容
private String author; //作者
private String url; //全文链接地址
//Item的构造函数
public Item(String title, String description, String author, String url)
{
this.title = title;
this.description = description;
this.author = author;
this.url = url;
}
//以下为title,description,author和url四个成员的get和set方法
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
RssParser类中提供了一个静态方法parseFeed()来解析Feed地址。
public static List parseFeed(String address)
此方法的主要思路为:RSS格式文件是标准的XML文件格式,所以可以通过标准的XML读取方式来访问其中的内容。在这里使用SAX方式来访问XML文件的内容。首先定义返回的文章列表。
List result = new ArrayList();
接着定义DocumentBuilderFactory,DocumentBuilder和Document,用以解析代表rss feed的XML文件,并通过DocumentBuilderFactory.newInstance()方法得到DocumentBuilderFactory对象。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
Document doc;
然后利用DocumentBuilderFactory对象的newDocumentBuilder方法得到DocumentBuilder对象,此DocumentBuilder对象的作用是根据xml文件的url地址生成Document对象。
db = dbf.newDocumentBuilder();
doc对象包含需要解析的feed的xml文件。
doc = db.parse(address);
feed的xml文件的组成单位是item,从doc中取出所有的item。
NodeList nl = doc.getElementsByTagName("item");
接着遍历这些item,取得其中的title, author, description和url等信息。
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
NodeList nl2 = node.getChildNodes();
Node nodeTitle = nl2.item(1);
Node nodeAuthor = nl2.item(2);
Node nodeUrl = nl2.item(3);
Node nodeDescription = nl2.item(4);
通过得到的title、author、description和url构造Item对象。
Item item = new Item(title, description, author, url);
最后将生成的item放到result中,以便返回。
result.add(item);
下面是此方法的完整代码。
/*
* Created on
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* @author Chao Wu
*
* Description:
* <p>RssParser类提供一个静态方法parseFeed()来解析某feed中的内容,得到其中包含的所有文章
*
* Copyright:
* <p>
*/
public class RssParser {
public static List parseFeed(String address) {
//result包含从feed中得到的一组Item对象
List result = new ArrayList();
//定义DocumentBuilderFactory,DocumentBuilder和Document,用以解析代表rss feed的XML文件
//通过DocumentBuilderFactory.newInstance()方法得到Document-
BzuilderFactory对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newIns-
tance();
DocumentBuilder db;
Document doc;
try {
//利用DocumentBuilderFactory对象的newDocumentBuilder方法得到DocumentBuilder对象
//此DocumentBuilder对象的作用是根据xml文件的url地址生成Document对象
db = dbf.newDocumentBuilder();
//doc对象包含需要解析的feed的xml文件
doc = db.parse(address);
//feed的xml文件的组成单位是item,从doc中取出所有的item
NodeList nl = doc.getElementsByTagName("item");
//遍历这些item,取得其中的title, author, description和url等信息
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
NodeList nl2 = node.getChildNodes();
Node nodeTitle = nl2.item(1);
Node nodeAuthor = nl2.item(2);
Node nodeUrl = nl2.item(3);
Node nodeDescription = nl2.item(4);
String title = nodeTitle.getFirstChild().getNodeValue();
String description = nodeDescription.getFirstChild(). getNodeValue();
String author = nodeAuthor.getFirstChild().getNode-
Value();
String url = nodeUrl.getFirstChild().getNodeValue();
//通过得到的title, author, description和url构造Item对象
Item item = new Item(title, description, author, url);
//将生成的item放到result中,以便返回
result.add(item);
}
} catch (ParserConfigurationException e) {
//处理ParserCOnfigurationException异常,输出异常信息
e.printStackTrace();
} catch (SAXException e) {
// 处理SAXException异常,输出异常信息
e.printStackTrace();
} catch (IOException e) {
// 处理IOException异常,输出异常信息
e.printStackTrace();
} finally {
//将结果返回,result数组可能为空
return result;
}
}
}
至此,整个开发过程就此完成。
最后将web.xml和struts-config.xml两个配置文件的内容展示如下。
Web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http: //java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>WebRssReader</display-name>
<!-- 指定使用struts的servlet -->
<servlet>
<!-- 当有请求发送到名为action的servlet时,使用org.apache.struts. action.ActionServlet来处理此请求 -->
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</ser-
vlet-class>
<init-param>
<!-- struts的配置文件struts-config.xml所在位置 -->
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- 将url结尾为.do的请求发送到action所在的servlet -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 初始页面为feed.jsp页面 -->
<welcome-file-list>
<welcome-file>feed.jsp</welcome-file>
</welcome-file-list>
<!-- 声明struts的bean, html, logic, nested标签库 -->
<taglib>
<taglib-uri>/tags/struts-bean</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-html</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-logic</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-nested</taglib-uri>
<taglib-location>/WEB-INF/struts-nested.tld</taglib-location>
</taglib>
</web-app>
Struts-config.xml:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<!--
NOTE: If you have a generator tool to create the corresponding Java classes
for you, you could include the details in the "form-bean" declarations.
Otherwise, you would only define the "form-bean" element itself, with the
corresponding "name" and "type" attributes, as shown here.
-->
<struts-config>
<!-- 在此定义FormBean,FormBean的位置为RssReaderForm,命名为rssReaderForm -->
<form-beans>
<form-bean name="rssReaderForm" type="RssReaderForm" />
</form-beans>
<!-- 定义Action的ActionMapping -->
<action-mappings>
<!—Action中定义RssReaderAction对应的FormBean为rssReaderForm -->
<action name="rssReaderForm" path="/feed" type="RssReaderAction">
<forward name="feed" path="/feed.jsp"></forward>
<forward name="list" path="/list.jsp"></forward>
</action>
</action-mappings>
</struts-config>
12.3 利用Hibernate完成RSS自动更新
本节单独使用Hibernate来操作数据库,通过这个实例,读者可以看到,Hibernate虽然一般用于Web应用的数据访问,但其功能是独立与前台的,无论是Web、Rich Client还是单机应用都可以利用Hibernate来做数据库操作。
本实例的功能是自动获取RSS的更新,系统的数据库中存放了一系列的RSS地址,程序定时地访问数据库,根据这些RSS地址,得到其中的文章列表。
系统主要包括了以下主要部分:
(1)Hibernate的配置文件:hibernate.cfg.xml。
(2)对应数据库feeds表的Feed对象,以及映射文件feed.hbm.xml。
(3)用于解析feed内容的RssParser类和Item类。
(4)用于自动更新的线程UpdateThread。
(5)测试类Test。
系统整体框架如图12-12所示。下面分析整个系统的各个组成部分。
(1)首先需要建立数据库,在MySQL中建立新的schema,命名为feed,并在其中建立表feeds,采用的ddl如下所示。
CREATE TABLE 'feed'.'feeds' (
'url' varchar(80) NOT NULL default '',
PRIMARY KEY ('url')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
图12-12
表feeds仅包含一个字段,即RSS Feed的地址Url。
(2)新建一个Java工程,下载Hibernate,将其中的包导入到工程中,并且配置Hibernate。建立Hibernate配置文件——hibernate.cfg.xml,代码如下所示。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="java:/hibernate/HibernateFactory">
<property name="show_sql">true</property>
<property name="connection.driver_class">
org.gjt.mm.mysql.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost/feed
</property>
<property name="connection.username"></property>
<property name="connection.password"></property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<mapping resource="Feed.hbm.xml" />
</session-factory>
</hibernate-configuration>
本工程只有一个映射文件Feed.hbm.xml。
(3)建立数据库feeds表对应的VO——Feed类,以及其映射文件。Feed类只包含一个成员,因为数据库对应的表也仅有一个字段。
/**
* @author Chao Wu
*
* Description:
* <p>Hibernate的VO类,每个Feed对象对应数据库feeds表中的一条记录
*
* Copyright:
* <p>
*/
public class Feed { //VO是一个普通的JavaBean
private String url; //Feed的地址
//以下为url的get和set方法
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Feed.hbm.xml配置了Feed类和feeds表之间的映射关系。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Feed" table="feeds">
<id name="url" column="url" />
</class>
</hibernate-mapping>
主键用id定义,在此处为url。
(4)RssParser类和Item类的功能与内容与前一个实例相同,在这里不再赘述。
(5)新建FeedUpdate类,此类的提供一个静态方法getFeedList()以更新某一个feed地址中的文章列表。
由于需要使用Hibernate进行数据库操作,所以首先要引入Hibernate所需要的包。
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
在getFeedList()方法中,首先根据hibernate.cfg.xml中的信息,生成SessionFactory对象,并利用SessionFactory对象生成到数据库的session连接。
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session session = sf.openSession();
接着定义一个事务transaction,将数据库操作包含在一个事务中。
Transaction tx = session.beginTransaction();
定义查询语句,从数据库中得到所有的Feed信息。
String sqlQuery = "select f from Feed f";
Query lQuery = session.createQuery(sqlQuery);
feedList = (ArrayList) lQuery.list();
最后将查询到的结果返回,完整的代码如下所示。
import java.util.ArrayList;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
* @author Chao Wu
*
* Description:
* <p>FeedUpdate类提供一个静态方法getFeedList()来取得数据库中Feed数据
*
* Copyright:
* <p>
*/
public class FeedUpdate {
//静态方法getFeedList(),从数据库中取出所有的Feed,并将结果作为一个List返回
public static List getFeedList() {
List feedList;
try {
//Configruation根据hibernate.cfg.xml中的信息,生成Sessio-
nFactory对象
SessionFactory sf = new Configuration().configure().bui-
ldSessionFactory();
//利用SessionFactory对象生成到数据库的session连接
Session session = sf.openSession();
//开始一个事务transaction,数据库操作包含在一个事务中
Transaction tx = session.beginTransaction();
//查询字符串,得到feeds表中所有的记录
String sqlQuery = "select f from Feed f";
//根据查询语句,生成Query对象
Query lQuery = session.createQuery(sqlQuery);
//得到查询结果
feedList = (ArrayList) lQuery.list();
//提交事务
tx.commit();
//关闭session连接
session.close();
//返回得到结果
return feedList;
} catch (HibernateException e) {
//若发生HibernateException,则显示异常信息,并返回null
e.printStackTrace();
return null;
}
}
}
(6)利用Java多线程的功能,新建一个线程类UpdateThread,代码如下所示。
import java.util.List;
public class UpdateThread extends Thread {
boolean keepRunning = true;
long lRefreshInterval = 10000;
public void run() {
while (keepRunning) {
try {
List feedList = FeedUpdate.getFeedList();
// 如果getFeedList方法中发生了异常,返回的feedList为null,则程序返回
if (feedList == null) {
return;
}
// 打印List中包含的feed数量
System.out.println("Size of feedList: " + feedList.size());
// 对每个Feed,得到其中的所有文章
for (int i = 0; i < feedList.size(); i++) {
// 得到每一个Feed对象
Feed feed = (Feed) feedList.get(i);
// 得到其url地址
String address = feed.getUrl();
// 取得feed中所有的文章
List items = RssParser.parseFeed(address);
// 打印feed中包含的文章数量
System.out.println("Items in feed of '" + address + "': "
+ items.size());
}
Thread.sleep(lRefreshInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void stopRunning() {
keepRunning = false;
}
}
其中UpdateThread类继承了Thread,所以可以作为单独的线程运行。
public class UpdateThread extends Thread {
在UpdateThread类中,定义了两个成员变量。其中keepRunning为线程运行的标志位,一开始设置为true,一旦希望线程停止,就将keepRunning设置为false。另一个变量lRefreshInterval制定了自动更新的时间间隔。
boolean keepRunning = true;
long lRefreshInterval = 10000;
UpdateThread类中重载了Thread类的Run方法。
public void run() {
……
}
Run方法的内容是当此线程运行之后要做的行为,所以将主要的操作都放置在Run方法中。在Run方法中,首先调用UpdateFeed的getFeedList方法,得到数据库中的Feed列表。
List feedList = FeedUpdate.getFeedList();
然后对列表中的每一个feed地址,调用RssParser的parseFeed()方法得到其中的文章列表。
for (int i = 0; i < feedList.size(); i++) {
// 得到每一个Feed对象
Feed feed = (Feed) feedList.get(i);
// 得到其url地址
String address = feed.getUrl();
// 取得feed中所有的文章
List items = RssParser.parseFeed(address);
这样就实现了自动对数据库列表中Feed包含文章的自动更新。
在完成更新操作之后,调用Thread.sleep()方法让线程睡眠一段时间,等睡眠时间结束之后继续下一次的更新操作。
Thread.sleep(lRefreshInterval);
stopRunning方法设置keepRunning为false,当keepRunning为false的时候,线程不在继续。
public void stopRunning() {
keepRunning = false;
}
(7)编写测试类,测试自动更新线程是否正常运行,代码如下所示。
import java.util.List;
/**
* @author Chao Wu
* Description:
* Copyright:
* <p>
*/
public class Test {
public static void main(String[] args) {
UpdateThread updateThread = new UpdateThread();
updateThread.start();
}
}
至此,完成了本实例。
http://book.csdn.net/bookfiles/377/10037714193.shtml
相关推荐
在RSS开发过程中,首先要了解RSS的基本结构。一个标准的RSS feed通常包括以下元素: 1. **频道(Channel)**:这是RSS文档的顶级元素,包含了关于整个RSS源的信息,如标题、描述、URL等。 2. **条目(Item)**:...
为了让开发者能够利用Android平台的便利性,本教程《android_RSS开发教程》将会详细介绍如何使用Android Developer Tools,进行RSS的读取、解析和显示。这不仅为Android平台提供了有效的信息获取方式,还对XML数据...
RSS阅读器开发实战是一个以Java语言为开发工具的项目,主要目标是实现一个能够解析、显示和管理RSS订阅源的应用程序。在这个项目中,开发者将深入理解RSS feed的结构和工作原理,同时掌握Java编程以及相关框架的使用...
在Laravel 5中,开发laravel-rss库是为了简化RSS feed的生成过程。这个库可能包含了以下关键知识点: 1. **Laravel基础知识**:理解Laravel框架的基础概念,如路由、控制器、模型、视图和数据库交互(Eloquent ORM...
10. **测试与调试**:在开发过程中,使用Flex的调试工具和模拟器进行测试,确保应用在不同平台和浏览器上的兼容性。 综上所述,"Rss.rar_flex_rss开发"项目涵盖了RSS聚合原理、Flex编程、XML解析、数据绑定、用户...
它提供了大量预定义类,如XML处理、数据库访问、网络通信等,简化了开发过程。 4. **RSS(Really Simple Syndication)**:RSS是一种XML格式,用于发布和订阅网站内容,如新闻标题、摘要和链接。RSS阅读器可以解析...
### android_RSS经典开发教程 #### 一、RSS与Android平台概述 RSS(Really Simple Syndication)作为一种标准化的格式,用于聚合网站上的内容,并让用户能够订阅这些内容更新。随着移动互联网的发展,RSS阅读器...
源码分析有助于开发者理解RSS订阅和解析的过程,以及如何在Android环境下构建一个功能完善的新闻阅读应用。以下是对该源码中涉及的关键知识点的详细说明: 1. **RSS(Really Simple Syndication)**: RSS是一种XML...
总之,"laravel-rss-feed"为Laravel开发人员提供了一种高效、灵活的方式来管理和提供RSS Feed,简化了与RSS源交互的过程。结合SimplePie的强大功能,这个包为构建功能丰富的RSS聚合应用提供了坚实的基础。通过深入...
在Android平台上,RSS阅读器是一种常见的应用,它允许用户订阅并查看来自不同网站的RSS feed。...通过这个实例,开发者可以学习到Android应用开发的基本流程和技巧,为构建更复杂的项目打下坚实基础。
Java开发的RSS系统源码是一个基于Java编程语言构建的新闻聚合和发布系统,它主要用于抓取、处理和展示RSS(Really Simple Syndication)格式的新闻 feed。RSS是一种XML格式,用于发布经常更新的内容,如博客文章、...
在实现RSS阅读器的过程中,开发者可能关注以下关键点: 1. **RSS解析**:首先,需要解析RSS源的XML结构,提取出标题、链接、描述、作者等信息。 2. **数据库设计**:设计合适的数据库模型,存储RSS源信息、用户订阅...
开发RSS在线阅读器涉及到以下几个关键技术: 1. **RSS格式**:RSS是基于XML的,遵循RSS 2.0标准。例如: ```xml <rss version="2.0"> <title>W3Schools Home Page <link>http://www.w3schools.com</link> ...
ASP.NET 2.0是微软公司推出的一种基于.NET Framework的Web应用程序开发平台,它极大地简化了Web应用的构建过程,提供了丰富的控件、数据绑定机制和内置的安全特性。在这个环境中,开发一个RSS阅读器是一种常见的实践...
在IT行业中,C#是一种广泛使用的编程语言,尤其在开发Windows桌面应用、Web应用以及游戏等领域。本项目涉及的是一个"C#编写...通过深入研究项目中的代码,新手可以提升自己的编程技能,并逐步理解软件开发的整个流程。