下面小编就给大家带来一个基于JSP的RSS阅读器的设计与实现方法(推荐)。我觉得边肖挺好的。我现在就分享给你,给你一个参考。来和边肖一起看看吧。
阅读器访问地址:http://easyrss.tk/,欢迎体验!
阅读导览
一、 概述
二、 设计的基本概念和原理
三、 设计方案
四、 主要源代码
五、 阅读器使用说明
概述
获取信息是人类生活中的一个重要环节。如果今天的社会获取信息不迅速,那么这个社会就不会像现在这样发达和先进。在网络技术相当发达的今天,大量的信息充斥着互联网。现在网络越来越发达,用户可以在线工作和娱乐。当用户需要在网上浏览很多网站来获取自己需要的信息时,会觉得很累。因为现在每个网站都有很多信息,找到自己喜欢的不容易。这时候RSS阅读器的作用就体现出来了。
RSS是一种简单的订阅方式,可以聚合网络信息。就像订阅报纸杂志一样,你喜欢什么就订阅什么。在客户端,用户可以收集网站内容(新闻、博客等。)由支持RSS的网站提供,在支持RSS的新闻聚合软件的帮助下输出到RSS阅读器中,用户可以通过‘RSS阅读器’阅读这些内容,而无需登录各个提供信息的网站。
本设计是设计一个RSS阅读器。该阅读器的功能如下:
随时随地阅读:
通过注册和登录将用户信息保存到服务器,用户可以通过打开网页随时随地阅读他们的RSS提要。
RSS源的分组管理和结构化显示;
直观的分类展示用户的RSS订阅列表,简化操作,提升用户阅读体验。
添加、修改和删除RSS源:
用户可以方便地添加、修改和删除RSS源和组。
RSS源的分析和显示;
阅读器可以通过用户提供的URL来分析RSS feed的标题、文章列表、文章地址和文章更新时间,并能正确地以一定的格式显示出来供用户阅读。
设计的基本概念和原理
RSS与RSS阅读器概念
RSS:
RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,是使用最广泛的XML应用程序[1]。RSS为信息的快速传播搭建了一个技术平台,让每个人都成为潜在的信息提供者。发布一个RSS文件后,这个RSS Feed中包含的信息可以被其他网站直接调用,而且由于这些数据是标准的XML格式,所以也可以在其他终端和服务中使用,这是一种描述和同步网站内容的格式。RSS可以是以下三种解释之一:真正简单的聚合;RDF(资源描述框架)站点概要;Rich Site Summary【2】但实际上,这三种解释都指的是同一个Syndication技术。
目前,RSS广泛应用于在线新闻频道、博客和维基。主要版本有0.91,1.0,2.0。使用RSS订阅可以更快的获取信息,网站提供RSS输出,有助于用户获取网站内容的最新更新。借助支持RSS的聚合工具软件,网络用户无需打开网站内容页面,即可阅读支持RSS输出的网站内容。
RSS阅读器:
RSS阅读器基本上可以分为三类[3]:
第一类,大部分阅读器是运行在电脑桌面上的应用程序,可以通过订阅网站的新闻供应自动定时更新新闻标题。在这些阅读器中,有三个流行的阅读器,Awasu,FeedDemon和RSSReader,它们都提供免费试用版和付费高级版。
第二种类型的新闻阅读器通常嵌入在已经在计算机中运行的应用程序中。例如,NewsGator嵌入在Microsoft Outlook中,订阅的新闻标题位于Outlook的收件箱文件夹中。另外,Pluck是内嵌在Internet Explorer浏览器中的!
第三类是在线WEB RSS阅读器,它的优点是不用安装任何软件就可以获得RSS阅读的便利,可以保存自己的阅读状态,推荐和收藏自己感兴趣的文章。有两种网站提供这项服务。一类是专门提供RSS阅读器的网站,比如国外的feedly,国内的有道、鲜果、捕虾;另一类是提供个性化主页的网站,比如国外的netvibes和pageflakes,国内的优雅蛙和broadlands。
这个阅读器是一个基于JSP的WEB RSS阅读器。
阅读器实现原理
这个RSS阅读器主要使用JSP技术。它根据用户请求的Url,借助Rome和Jdom开源工具解析XML文件,获得相应的内容,然后将获得的内容以方便阅读的格式显示在网页上[4]。同时利用数据库和JSP的相应技术对阅读器的功能进行了扩展,如用户阅读列表的管理、显示效果的优化等。
设计方案
架构设计
网站前台使用JSP技术实现页面和功能,后台数据库使用SQLServer进行数据管理,阅读内容从RSS源获取,如下图所示:
数据库设计
使用数据库SQL Server 2008 R2,数据表设计如下:
为了保护系统安全,没有直接给出数据表结构。
界面设计
登录和注册:
登录界面Login
注册界面signup.jsp:
主页
Index.jsp(中间分割线可以拖)
首页设计有框架,上半部分是网站信息和当前用户信息;左侧为RSS源列表;右边是主框,用来显示阅读内容。左右边框大小可以随意拖动调整。
RSS树列表:
dtree
RSS提要以dtree树形列表[5]的方式显示,可以直观的一组一组的显示RRS提要。
文章列表:
以表格形式列出选定RSS源中的文章。
内容:
文章内容
文章内容是直接显示文章的原网页,保持原布局,防止被屏蔽。
添加和管理:
通过弹出窗口添加和管理,如下:
添加源
添加分组
管理分组
管理来源
修改接口类似于添加接口,不需要映射。
提示消息(tips.jsp):
大多数提示都显示在提示页面上,例如:
注册提示
没有登录提示
退出提示
……
提示页面会根据获取的参数显示提示信息。
功能设计
注册:
注册时,需要用户名、密码和确认密码。由于密码是不可见的,设置确认密码可以防止输入错误。昵称是可选的,用于更友好地显示用户名。如果为空,它将被用户名替换。注册后将注册信息添加到数据库中。同时需要注意的是,用户名不能与数据库中已有的用户名重复。
登录:
登录时,先获取用户名,连接数据库,查询用户是否存在。如果用户名不存在,跳转提示页面显示相应的提示,然后返回登录页面。如果找到,请确认密码输入是否正确。如果密码正确,用户的uid将被存储在会话中以备后用,然后跳转到用户的主页。
主页:
采用主页布局,主要包括三个部分:
上部:显示网站logo,当前用户信息等。信息用户根据会话中的uid从数据库中查询用户的详细信息。如果用户昵称列表不为空,则显示昵称;如果为空,将显示用户名。
左边部分:主要是RSS树列表,详见以下介绍;
右侧部分:主显示区,显示文章列表和文章的具体内容。详见下文介绍。
RSS树列表:
RSS提要显示采用开源的dtree项目进行二次开发。首先根据之前放入会话的uid获取当前用户的RSS包数据,每次获取时根据包的gid获取属于该组的RSS源数据,然后将数据放入dtree,依次循环,直到获取所有数据。最后,dtree根据树样式显示数据。单击用户列表中的一个项目将在右侧主框架中打开相应的文章列表。
主框架中的文章列表:
主框架从左框架发来的链接中提取feed参数中的url值,解析url得到对应的文章列表。Url和xml文件通过rss解析器(rome.jar和jdom.jar)解析得到相应的数据。
同时,为了解决部分文章不支持在框架中打开的问题,文章列表设计了在新窗口中打开的选项。主要方法是:用户改变选项‘在新窗口中打开’的状态后,js立即将选项的状态写入Cookie,并发送刷新请求。根据服务器的Cookies值,动态修改文章链接的目标属性,并向客户端发送新的页面。
文章显示:
直接显示原文,不做任何处理,简单方便。但是,有些文章不支持在框架中显示。此时,您需要选中“在新窗口中打开”选项,使文章显示在新的浏览器窗口中。
添加和管理RSS源:
添加分为添加源和添加分组。两个界面属于同一个弹出窗口,通过顶部选项卡切换,直观快捷。
添加来源时,需要提交:提要地址、标题和分组。提要地址要填写需要订阅的rss地址;可以从提要地址中提取标题(具体来说,服务器获取提要地址,根据提要地址解析订阅标题,然后将带有订阅标题的新页面发送给客户端);通过分组列表框选择用户的现有分组。客户端提交表单后,服务器获取相应信息并添加到数据库中,然后返回成功信息;用户可以再次添加新源。
添加组时,您只需提交要添加的组的名称。
管理界面属于一个新的弹出窗口,最初显示所有用户组,每个组包含三个菜单:“展开”、“修改”和“删除”。单击组名或“展开”菜单,跳转到该组下的RSS源列表。RSS源列表熟悉分组列表,每个分组都包含‘修改’和‘删除’菜单。
修改时,提交要修改的项目,服务器根据获取的gid、pd和修改信息更新相应的项目数据并返回相应的提示。
删除提交了相应群组的gid或RSS feed的pd,服务器根据获取的id信息输出相应的条目并返回提示。删除非空数据包将删除该数据包下的所有RSS源(提示)。
提示信息:
信息显示页面或根据获取的参数显示相应的提示信息,并在一定的时间延迟后跳转到相应的界面。当参数为空时,将显示“未知错误”并跳转到主页。
网络安全补充
为了保护网站和用户数据安全,采取了以下辅助安全措施:
输入注册限制:
用户名只能是字母和数字的组合。
密码长度太短
用户名限于字母和数字的组合,这使得用户无法在SQL注入的SQL语言中使用符号。密码长度限制在8~20位。太短,密码不安全;过长,用户可以通过密码框使用SQL注入攻击。
使用过滤器防止SQL注入:
仅仅通过形式上的输入限制来预防SQL注入是远远不够的。用户仍然可以使用URL参数来执行注入攻击。所以我在原来的项目中添加了一个过滤器来保护一些简单的SQL注入攻击。
该过滤器的原理是拦截所有用户的输入,检查是否包含特定的关键字,如果包含,则重定向到错误消息页面error。则过滤器不通过。
当然,仅使用过滤器并不能完全抵御SQL注入攻击。更有效的方法是,项目中的所有SQL语句都使用PreparedStatement的接口实现[6]。
面对日益复杂的网络安全环境,上述安全措施仅仅是一些防护,对于一个实际项目来说远远不够。在实际工程中应采取更加严格有效的措施。
具体方法参考本文:JSP使用过滤器防止SQL注入。
主要源代码
查看零件
/RSS reader/web content/RSS content . JSP:
% @页contentType='text/html'%
% @页page encoding=' UTF-8 ' import=' Java . text . simple date format ' %
超文本标记语言
脚本语言=javascript
函数setCheck(){
var new window=document . getelementbyid(' new window ')。价值;
if(newWindow==0)
{
document.getElementById('check ').选中=真;
}
其他
{
document.getElementById('check ').选中=假;
}
}
功能检查(){
var check=文档。getelementbyid(' check ').已检查;
var feed=文档。getelementbyid(“feed”).价值;
var url='rsscontent.jsp?饲料='饲料
如果(勾选)
{
document.cookie=' newWindow=0
}
其他
{
document.cookie=' newWindow=1
}
self.location=url
}
/脚本
body onload='setCheck()'
%
string page title=
字符串urlStr=请求。getparameter(“feed”);
string target=
cookie cookie[]=请求。获取cookie();//读出用户硬盘上的饼干,并将所有的饼干放到一个甜饼干对象数组里面
Cookie sCookie=null
for(int I=0;icoookies。长度;i ){ //用一个循环语句遍历刚才建立的饼干对象数组
SCO okie=cookies[I];//取出数组中的一个饼干对象
如果(史酷基!=null){
if(('newWindow ').equals(SCO okie。getname()){
页面上下文。设置属性('新窗口',SCO okie。getvalue());
系统。出去。println(pagecontext。get属性(' new window ');
}
}
}
if(pagecontext。获取属性('新窗口')!=空)
{
if(pagecontext。获取属性(“新窗口”).等于(' 0 '){
target=' _ blank
}
否则{
target=' _ self
}
}
尝试{
/* Java。util。属性系统设置=系统。获取属性();
系统设置。放(' http。代理主机',' myweb缓存。com’);
系统设置。放(' http。代理端口',' 8080 ');
系统。设置属性(系统设置);*/
如果(!urlStr.startsWith('http://'))
urlStr=' http://'请求。getparameter(“feed”);
//String urlStr=' http://提要。cn博客。' com/blog/u/249598/RSS ';
系统。出去。println(urlStr);
Java。网。URL连接提要URL=新Java。网。URL(urlStr).打开连接();
feedUrl.setRequestProperty('用户代理,' Mozilla/4.0(兼容;MSIE 5.0 windows NTDigExt)');
com。星期日辛迪加。io。syndfeedinput input=new com。星期日辛迪加。io。syndfeedinput();
com。星期日辛迪加。喂。synd。synd feed feed=输入。构建(新的com。星期日辛迪加。io。XML阅读器(提要URL));
页面标题=提要。gettitle();
%
div align='center '
h1 %=页面标题%/h1
输入类型=' hidden ' id=' feed ' value=%=urlStr %
输入类型=' hidden ' id=' new window ' value=%=pagecontext。获取属性('新窗口')%
输入类型=复选框名称=' check ' id=' check ' onclick=' check()'在新窗口中打开(部分网页不支持在框架中显示,请尝试勾选此项)/输入
表格边框=1单元格填充=3单元格间距="0"
tr
泰国(泰国)序号/th
泰国(泰国)标题/th
泰国(泰国)发布时间/th
/tr
%
字符串日期='无;
Java。util。列表列表=提要。getentries();
for(int I=0;我列出。size();i ) {
com。星期日辛迪加。喂。synd。synd entry entry=(com。星期日辛迪加。喂。synd。synd条目)列表。get(I);
SimpleDateFormat SDF=new SimpleDateFormat();
sdf.applyPattern('yyyy年缩写。毫米(毫米)月截止日期(截止日期的缩写)日HH:mm’);
if(entry.getPublishedDate()!=空)
{
日期=SDF。格式(条目。getpublisheddate());
}
%
tr
td%=i 1%/td
TDA id=' entry ' href=' %=entry。getlink()% ' target=%=target % %=entry。gettitle()%/a/TD
td %=日期%/td
/tr
%
}
} catch(异常e) {
//TODO自动生成的捕捉块
回应。发送重定向('提示。JSP?type=RSS内容失败’);
e。printstacktrace();
}
%
/表格
/div
英国铁路公司
/body
头
meta http-equiv=' Content-Type ' Content=' text/html;charset=UTF-8 '
title %=页面标题%/标题
/头
/html
/RSS阅读器/web内容/添加组。JSP:
% @ page language=' Java ' content type=' text/html;charset=utf-8 '
页面编码=' utf-8 ' import=' com .JDBConnection,java.sql.ResultSet,com.dataHelper,java.util.ArrayList'%
!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN ' ' http://www。w3。org/TR/HTML 4/loose。' DTD '
超文本标记语言
头
meta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8 '
标题添加分组/标题
link href=' CSS/tab。CSS ' type=' text/CSS ' rel=' style sheet '/
/表单
/div
div align='center '
/div
/div
/body
/html
/RSS阅读器/网页内容/删除。JSP:
% @ page language=' Java ' content type=' text/html;charset=utf-8 '
页面编码=' utf-8 ' import=' com .JDBConnection,java.sql.ResultSet'%
!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN ' ' http://www。w3。org/TR/HTML 4/loose。' DTD '
超文本标记语言
头
meta http-equiv=' Content-Type ' Content=' text/html;'' utf-8 '
标题编辑组/标题
/头
身体
div align='center '
%
字符串名称=(字符串)会话。get属性(“name”);
字符串昵称="";
if(name==null)
{
回应。发送重定向('索引。JSP’);
}
%
%
字符串GID=请求。getparameter(“GID”);
字符串lid=请求。getparameter(' lid ');
字符串类型=请求。getparameter(“type”);
字符串URL=
//删除自表名称在哪里列名称=值
字符串sSql=
如果(类型!=null){
如果(类型。等于(' g '){
sSql=' delete from RSS group where GID=' GID;
URL=' manage.jsp
}
如果(类型。等于(' r '){
sSql='从RSS列表中删除,其中lid=' lid
url='rssListOfGroup.jsp?GID=GID
}
}
系统。出去。println('组的RSS列表.SQL:' sSql);
JDBC连接JDBC=新JDBC连接();
if(JDBC.executeUpdate(sSql)){
out.print('删除成功');
}
否则{
out.print('删除失败');
}
%
/div
英国铁路公司
div align='center '
a href=%=url %返回/a
/div
/body
/html
Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)部分
/RSS阅读器/src/com/JDBC连接。Java 语言(一种计算机语言,尤用于创建网站)
包com
导入Java。SQL。*;
公共类JDBC连接{
私有最终字符串URL=' JDBC:SQL server://localhost:1433;DatabaseName=RSS reader ';
私有最终字符串用户名=' sa
私有最终字符串密码=' 123456 ';
专用连接con=空
//通过构造方法加载数据库驱动
静态{
尝试{
班级。forname(' com。微软。SQL server。JDBC。SQL server驱动程序’);
} catch (Exception ex) {
System.out.println('数据库加载失败');
}
}
//创建数据库连接
公共布尔creatConnection() {
尝试{
con=司机经理。getconnection(URL,用户名,密码);
con .设置自动提交(true);
} catch (SQLException e) {
系统。出去。println(e . getmessage());
系统。出去。println(' creatConnectionError!');
}
返回真实的
}
public void close(Connection con,Statement stmt,PreparedStatement pst,ResultSet rs){
如果(rs!=null){
尝试{
RS。close();
} catch (SQLException e) {
//TODO自动生成的捕捉块
e。printstacktrace();
}
}
如果(stmt!=null){
尝试{
stmt。close();
} catch (SQLException e) {
//TODO自动生成的捕捉块
e。printstacktrace();
}
}
如果(pst!=null){
尝试{
太平洋标准时间。close();
} catch (SQLException e) {
//TODO自动生成的捕捉块
e。printstacktrace();
}
}
如果(con!=null){
尝试{
con . close();
} catch (SQLException e) {
//TODO自动生成的捕捉块
e。printstacktrace();
}
}
}
public void closeConnection(){
如果(con!=null){
尝试{
con . close();
} catch (SQLException e) {
//TODO自动生成的捕捉块
e。printstacktrace();
}
}
}
//对数据库的增加、修改和删除的操作
公共布尔执行更新(字符串sql) {
if (con==null) {
创建连接();
}
尝试{
语句stmt=con . create语句();
int iCount=stmt。执行更新(SQL);
System.out.println('操作成功,所影响的记录数为字符串。(iCount)的值;
this.close(con,stmt,null,null);
返回真实的
} catch (SQLException e) {
系统。出去。println(e . getmessage());
返回错误的
}
}
//对数据库的查询操作
公共结果集executeQuery(字符串sql) {
结果集RS;
尝试{
if (con==null) {
创建连接();
}
语句stmt=con . create语句();
尝试{
RS=stmt。执行查询(SQL);
} catch (SQLException e) {
系统。出去。println(e . getmessage());
返回空
}
} catch (SQLException e) {
系统。出去。println(e . getmessage());
系统。出去。println(' executeQueryError!');
返回空
}
返回RS;
}
}
/RSS阅读器/src/com/SQL筛选器。Java 语言(一种计算机语言,尤用于创建网站)
包com
导入Java。io。io异常;
导入Java。util。枚举;
导入javax。servlet。过滤器;
导入javax。servlet。过滤链;
导入javax。servlet。过滤器配置;
导入javax。servlet。servlet异常;
导入javax。servlet。servlet请求;
导入javax。servlet。servlet响应;
导入javax。servlet。http。http servlet请求;
导入javax。servlet。http。http servlet响应;
//过滤结构化查询语言关键字的过滤器
公共类SqlFilter实现筛选器{
公共void do过滤器(servlet请求请求,Ser
vletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; //获得所有请求参数名 Enumeration params = req.getParameterNames(); String sql = ""; while (params.hasMoreElements()) { //得到参数名 String name = params.nextElement().toString(); //System.out.println("name===========================" + name + "--"); //得到参数对应值 String[] value = req.getParameterValues(name); for (int i = 0; i < value.length; i++) { sql = sql + value[i]; } } System.out.println("被匹配字符串:"+sql); if (sqlValidate(sql)) { res.sendRedirect("error.jsp"); } else { chain.doFilter(req, res); } } //效验 protected static boolean sqlValidate(String str) { str = str.toLowerCase();//统一转为小写 //String badStr = "and|exec"; String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|chr|mid|master|truncate|char|declare|sitename|net user|xp_cmdshell|or|like"; /*String badStr = "'|and|exec|execute|insert|create|drop|table|from|grant|use|group_concat|column_name|" + "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|" + "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#"; */ //过滤掉的sql关键字,可以手动添加 String[] badStrs = badStr.split("\\|"); for (int i = 0; i < badStrs.length; i++) { if (str.indexOf(badStrs[i]) !=-1) { System.out.println("匹配到:"+badStrs[i]); return true; } } return false; } public void init(FilterConfig filterConfig) throws ServletException { //throw new UnsupportedOperationException("Not supported yet."); } public void destroy() { //throw new UnsupportedOperationException("Not supported yet."); } } /RSSreader/src/dataCtrl/addGroup.java package dataCtrl; import com.JDBConnection; public class addGroup { private String gname; private String uid; public String getGname() { return gname; } public void setGname(String gname) { this.gname = gname; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public boolean doAddGroup(){ String sSql = "insert into rssGroup(gname,uid) values('"+gname+"',"+uid+")"; System.out.println(sSql); JDBConnection JDBC=new JDBConnection(); return JDBC.executeUpdate(sSql); } } /RSSreader/src/dataCtrl/addRss.java package dataCtrl; import java.sql.*; import com.JDBConnection; import javafx.beans.property.adapter.JavaBeanProperty; public class addRss { private String title; private String url; private String gid; 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; } public String getGid() { return gid; } public void setGid(String gid) { this.gid = gid; } public boolean doAddRss() throws SQLException{ //INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....); String sSql = "insert into rssList(title,url,gid) values('"+title+"','"+url+"',"+gid+")"; System.out.println(sSql); JDBConnection JDBC=new JDBConnection(); return JDBC.executeUpdate(sSql); } } /RSSreader/src/dataCtrl/dealaddGroup.java package dataCtrl; import java.io.IOException; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class dealaddGroup */ @WebServlet("/dealaddGroup") public class dealaddGroup extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public dealaddGroup() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String gname=request.getParameter("gname"); String sgname =new String(gname.getBytes("ISO8859_1"), "utf-8"); String uid=request.getParameter("uid"); addGroup adgp=new addGroup(); adgp.setGname(sgname); adgp.setUid(uid); if(adgp.doAddGroup()){ request.getRequestDispatcher("/addGroup.jsp?name="+gname+"&lastAdd=ture").forward(request,response); //response.sendRedirect("index.jsp"); } else{ request.getRequestDispatcher("/addGroup.jsp?name="+gname+"&lastAdd=false").forward(request,response); } doGet(request, response); } } /RSSreader/src/dataCtrl/dealAddRss.java package dataCtrl; import java.io.IOException; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class dealAddRss1 */ @WebServlet("/dealAddRss1") public class dealAddRss extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public dealAddRss() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //response.setContentType("text/html;charset=utf-8"); String title=request.getParameter("title"); String stitle =new String(title.getBytes("ISO8859_1"), "utf-8"); String url =request.getParameter("url"); String gid=request.getParameter("group"); addRss adrs=new addRss(); adrs.setTitle(stitle); adrs.setUrl(url); adrs.setGid(gid); try { if(adrs.doAddRss()){ request.getRequestDispatcher("/addRss.jsp?name="+title+"&lastAdd=ture").forward(request,response); //response.sendRedirect("index.jsp"); } else{ request.getRequestDispatcher("/addRss.jsp?name="+title+"&lastAdd=false").forward(request,response); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } doGet(request, response); } } /RSSreader/src/dataCtrl/getFeedTitle.java package dataCtrl; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sun.syndication.io.FeedException; /** * Servlet implementation class getFeedTitle */ @WebServlet("/getFeedTitle") public class getFeedTitle extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public getFeedTitle() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String urlStr =request.getParameter("url"); String title=""; String gid=request.getParameter("group"); String lid=request.getParameter("lid"); String Lastgid=request.getParameter("Lastgid"); String from=request.getParameter("from"); if (!urlStr.startsWith("http://")) urlStr = "http://"+request.getParameter("feed"); //String urlStr = "http://feed.cnblogs.com/blog/u/249598/rss"; System.out.print(urlStr); java.net.URLConnection feedUrl = new java.net.URL(urlStr).openConnection(); feedUrl.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); com.sun.syndication.io.SyndFeedInput input = new com.sun.syndication.io.SyndFeedInput(); com.sun.syndication.feed.synd.SyndFeed feed; try { feed = input.build(new com.sun.syndication.io.XmlReader(feedUrl)); title=feed.getTitle(); } catch (IllegalArgumentException | FeedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(from.equals("addRss")){ response.sendRedirect("addRss.jsp?title="+title+"&url="+urlStr+"&group="+gid+"&Lastgid="+Lastgid+"&lid="+lid); } if(from.equals("editRss")){ response.sendRedirect("editRss.jsp?title="+title+"&url="+urlStr+"&group="+gid+"&Lastgid="+Lastgid+"&lid="+lid); } doGet(request, response); } } /RSSreader/src/loginCtrl/checkUser.java package loginCtrl; import java.sql.ResultSet; import java.sql.SQLException; import com.JDBConnection; public class checkUser { private int uid=0; private String name=" "; private String pwd=" "; public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public boolean check() { String sPwd=""; String sSql = "select * from users where uname='"+name+"'"; System.out.println(sSql); try { JDBConnection JDBC=new JDBConnection(); ResultSet rs =JDBC.executeQuery(sSql); System.out.println(rs.isBeforeFirst()); if(rs.next()) { System.out.println("?"); sPwd=rs.getString("upwd"); uid=rs.getInt("uid"); //System.out.println(sPwd); JDBC.closeConnection(); } } catch (SQLException e) { // TODO Auto-generated catch block System.out.println(e.getMessage()); System.out.println("ConnectError!"); } System.out.println(name+"-"+pwd+"-"+sPwd); if(pwd.equals(sPwd)) { return true; } else { return false; } } } /RSSreader/src/loginCtrl/dealsignup.java package loginCtrl; import java.io.IOException; import java.sql.Connection; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Servlet implementation class dealsignup */ @WebServlet("/dealsignup") public class dealsignup extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public dealsignup() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setContentType("text/html;charset=utf-8"); String name =request.getParameter("account"); String url =request.getParameter("url"); String nickname =request.getParameter("nickname"); if (nickname==null||nickname=="") nickname=null; else nickname=new String(request.getParameter("nickname").getBytes("ISO8859_1"), "utf-8"); String pwd= request.getParameter("password"); String enpwd= request.getParameter("ensurepassword"); signup snp=new loginCtrl.signup(); System.out.println("dealsingnup:"+name+"-"+nickname+"-"+pwd+"-"+enpwd); if(!pwd.equals(enpwd)) { response.sendRedirect("tips.jsp?type=signupwithwrongpwd"); System.out.println("两次密码不一致"); } else { snp.setName(name); snp.setNickname(nickname); snp.setPwd(pwd); Connection conn=snp.connect(); if(snp.signupcheck(conn)) { if(snp.dosignup(conn)) { response.sendRedirect("tips.jsp?type=signupsuccess&str="+name); System.out.println("注册成功"); } else { response.sendRedirect("tips.jsp?type=sinupfail"); System.out.println("未知错误"); } } else { response.sendRedirect("tips.jsp?type=usernamevalid"); System.out.println("用户名已被注册"); } snp.closeConnection(conn); } doGet(request, response); } } /RSSreader/src/loginCtrl/loginCheck.java package loginCtrl; import java.io.IOException; import java.sql.ResultSet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.JDBConnection; /** * Servlet implementation class loginCheck */ @WebServlet("/loginCheck") public class loginCheck extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public loginCheck() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String name =request.getParameter("account"); String pwd= request.getParameter("password"); checkUser uc=new loginCtrl.checkUser(); System.out.println(name+"-"+pwd); uc.setName(name); uc.setPwd(pwd); if(uc.check()) { HttpSession session=request.getSession(); session.setAttribute("name", name); session.setAttribute("uid", uc.getUid()); response.sendRedirect("index.jsp"); } else { response.sendRedirect("tips.jsp?type=logfail"); } doGet(request, response); } } /RSSreader/src/loginCtrl/signup.java package loginCtrl; import java.sql.*; public class signup { private String name=" "; private String nickname=""; private String pwd=" "; private Connection conn; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public Connection connect() { try { String JDriver="com.microsoft.sqlserver.jdbc.SQLServerDriver";//SQL数据库引擎 String connectDB= "jdbc:sqlserver://localhost:1433;DatabaseName=RSSreader";//数据源 try { Class.forName(JDriver);//加载数据库引擎,返回给定字符串名的类 }catch(ClassNotFoundException e) { //e.printStackTrace(); System.out.println("加载数据库引擎失败:"+e); System.exit(0); } System.out.println("数据库驱动成功"); String user="sa"; String password="123456"; conn=DriverManager.getConnection(connectDB,user,password);//连接数据库对象 System.out.println("连接数据库成功"); } catch(Exception e) { System.out.println("链接数据库失败:"+e); } return conn; } public boolean signupcheck(Connection conn) { try{ Statement stmt=conn.createStatement(); ResultSet rs=stmt.executeQuery("select * from users where uname='"+name+"'"); if(!rs.next()) return true; } catch(Exception e) { System.out.println("查询失败"+e); return false; } return false; } public boolean dosignup(Connection conn) { try { PreparedStatement ps = conn.prepareStatement("insert into users (uname,nickname,upwd) values(?,?,?)"); ps.setString(1, name); ps.setString(2, nickname); ps.setString(3, pwd); int num =ps.executeUpdate(); System.out.println(num); if (num==0) return false; ps.close(); } catch(Exception e) { System.out.println("添加失败"+e); return false; } return true; } public boolean closeConnection(Connection conn) { try { System.out.println("关闭链接成功"); conn.close(); } catch(Exception e) { System.out.println("关闭链接失败"+e); return false; } return true; } } 阅读器使用说明注册与登录
使用阅读器之前需要注册用户并登录,服务器会保存用户的RSS列表数据。未登录之前阅读器会推荐阅读阅读列表,并指导用户寻找RSS源,如下图:
注册时输入为空或输入错误会有相应提示
注册成功后会提示用户记住用户名,然后跳转登录页面:
登录后来到主页,同样阅读器会引导新用户寻找RSS源,点击"寻找RSS源"会跳转到下面这样一个神奇的页面:
然后就是添加自己需要订阅的RSS源了。
添加与管理RSS源
注册登录后,就可以添加自己喜爱的RSS源了。点击添加,弹出添加对话框,这是我们需要先添加分组再添加RSS源。我们先添加两个测试分组,如下图:
添加成功会有提示:
添加好分组后再来添加RSS源,我们测试添加一个"知乎每日精选"的订阅:www.zhihu.com/rss 直接在浏览器中打开是这样的:
这个当然看不懂,我们将url粘贴到阅读器中,标题可以不用自己填,点击"从Feed中获取",阅读器会根据url从RSS源中解析出RSS源的标题。选择"测试分组1",保存。
第一个源已经添加成功了,接下来再添加几个源用作测试。
添加完成后,关闭对话框,左边列表会自动刷新,点击展开显示已添加的RSS源:
这样我们就完成了RSS源的添加。如果有些源名字、分组有错或者源失效了、自己不想再订阅了,我们可以对其进行编辑或者直接删除。点击"管理",弹出管理对话框:
此时我们可以修改分组名或者将其删除:
注意:删除分组会删除该组内的所有RSS源。修改之后:
点击展开,可以显示该分组下的所有RSS源:
同样我们可以修改RSS源或者将其删除,方法与对组的操作类似,修改后:
修改完成后,关闭对话框,同样左边列表会自动刷新:
阅读文章
点击其中一个RSS源,会在右边显示出该订阅的文章列表:
然后点击文章的标题就会显示文章的具体内容:
如果勾选了"在新窗口中打开",文章将会在新的浏览器窗口中打开。
好了基于JSP的RSS阅读器的介绍就到这里,阅读器访问地址:http://easyrss.tk/
以上这篇基于JSP的RSS阅读器的设计与实现方法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。