您的位置:首页 > Web前端

自行完成命令行模式的RSS阅读器(只针对Feed源)

2015-10-03 18:33 447 查看
最近收到一个面试的小作业 :完成命令行模式的RSS阅读器

就想着做做,做完发现有好几处问题

以下代码只针对Feed源进行操作。

其中有几处Bug:

(1)错误提示:The type org.bson.conversions.Bson cannot be resolved. It is indirectly referenced from required .class files

网上没找到 org.bson.conversions 这个jar包,下载Bson.jar也不行,可能是编译器的问题。

(2)没有对content的保存进行优化,一旦内容过大,可能只会读取一部分内容。

(3)显示最新的20篇文章需要进行对日期排序,这里没有进行排序。

一、关于MongoDB数据库操作

1、连接MongoDB数据库(单例模式)

/**
* 数据库连接类
*
* @author yyp
*
*/
public class MongoDBUtil {

private static Mongo mongo = null;
private static String DBName = "mydb";// 数据库名
private static String hostName = "localhost";// 默认的主机名,可自行修改
private static int port = 27017;// 默认的端口号
private static int poolSize = 20;// 连接池大小

// 构造方法私有化,防止外界访问
private MongoDBUtil() {

}

// 静态方法,方便外界获取数据库连接
public static DB getDB() {
if (mongo == null) {
init();
}
return mongo.getDB(DBName);
}

// 初始化数据库
private static void init() {
try {
// 实例化Mongo
mongo = new Mongo(hostName, port);
MongoOptions opt = mongo.getMongoOptions();
// 设置连接池大小
opt.connectionsPerHost = poolSize;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}


2、设计DAO层接口

/**
* 基本操作接口
*
* @author yyp
*
*/

public interface DAO {

// 插入一条
public boolean add(String collectionName, BasicDBObject bean);

// 删除一条
public boolean delete(String collectionName, BasicDBObject bean);

// 查询全部
public DBCursor queryAll(String collectionName);

// 查询一条
public DBCursor query(String collectionName, BasicDBObject bean);

// 更新一条
public boolean update(String collectionName, BasicDBObject newbean, BasicDBObject oldbean);

}


3、实现CURD操作(增、改、查、删)

/**
* 实现CURD操作
*
* @author yyp
*
*/

public class CURD implements DAO {

public CURD() {

}

// 插入一条
@Override
public boolean add(String collectionName, BasicDBObject bean) {
// TODO Auto-generated method stub
DB mydb = MongoDBUtil.getDB();
mydb.getCollection(collectionName).insert(bean);
return false;
}

// 删除一条
@Override
public boolean delete(String collectionName, BasicDBObject bean) {
// TODO Auto-generated method stub
DB mydb = MongoDBUtil.getDB();
mydb.getCollection(collectionName).remove(bean);
return false;

}

// 查询全部
@Override
public DBCursor queryAll(String collectionName) {
// TODO Auto-generated method stub
DB db = MongoDBUtil.getDB();
// 找到表的数据项列表
DBCursor cursor = db.getCollection(collectionName).find();
return cursor;
}

// 查询一条
@Override
public DBCursor query(String collectionName, BasicDBObject bean) {
// TODO Auto-generated method stub
DB db = MongoDBUtil.getDB();
// 找到表的数据项
DBCursor cursor = db.getCollection(collectionName).find(bean);
if (cursor != null) {
return cursor;
}
return null;
}

// 更新一条
@Override
public boolean update(String collectionName, BasicDBObject newbean, BasicDBObject oldbean) {
// TODO Auto-generated method stub
DB db = MongoDBUtil.getDB();
// 找到表的数据项列表
db.getCollection(collectionName).update(oldbean, newbean);
return false;
}

}


二、下载Feed源并逐条保存

/**
* 下载保存Feed
*
* @author yyp
*
*         下载的content可能只有一部分
*/
public class GetFeed {

private boolean isFinished = false; // 下载是否完成
private int count = 0; // 当前标题与数据库已有标题不重复的次数
private int ID = 0;

public void download(String URL_PATH) {

HttpURLConnection feedconn = null;
try {

URL url = new URL(URL_PATH);
feedconn = (HttpURLConnection) url.openConnection();
feedconn.setReadTimeout(3000);
feedconn.setDoInput(true);
feedconn.setRequestMethod("GET");
int responsecode = feedconn.getResponseCode();
if (responsecode == 200) {
//设置通用的请求属性
feedconn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
// 实例化feed输入流
SyndFeedInput input = new SyndFeedInput();
// 读取feed
SyndFeed feed = input.build(new XmlReader(feedconn));
// 获取entry数量
int entriesSize = feed.getEntries().size();
// System.out.println(
// "News:" + entriesSize + " FeedType:" + feed.getFeedType() + "
// Title:" + feed.getTitle());
SyndEntry entry;
SyndContent content;
for (int i = 0; i < entriesSize; i++) {
// 实例化entry
entry = new SyndEntryImpl();
// 获取第i个entry
entry = (SyndEntry) (feed.getEntries()).get(i);
// 实例化content
content = new SyndContentImpl();
// 获取content描述
content = entry.getDescription();
CURD curd = new CURD();
DBCursor cursor = curd.queryAll("blogs");
while (cursor.hasNext()) {
if (entry.getTitle().trim() != cursor.next().get("title")) {
++count;
// 如果此标题没有与数据库的任何一篇文章的标题重复,则插入
if (count == cursor.count()) {
ID++;
Map<String, String> map = new HashMap<String, String>();

// 把数据转换为json格式,(注意:保存的ID为字符串格式)
map.put("id", Integer.toString(ID));
map.put("title", entry.getTitle().trim());
map.put("author", entry.getAuthor().trim());
String date = (entry.getPublishedDate() != null ? "日期:" + entry.getPublishedDate()
: "");
map.put("publishDate", date);
map.put("conent", content.getValue().trim());
DBObject obj = new BasicDBObject(map);
// 保存数据
curd.add("blogs", obj);
break;
}
} else {
System.out.print(entry.getTitle().trim() + "与数据库中某一篇文章的标题重复!");
}
}
}
isFinished = true;

} else {
System.out.println("请求失败!");
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
// 下载完关闭连接
feedconn.disconnect();
}

if (!isFinished) {
System.out.println();
System.out.println("同步Feed失败!");
}
}
}


三、实现小功能的命令行操作

注:只进行了数据的添加、查询功能

package com.rss.view;

import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.rss.load.GetFeed;
import com.rss.mongodb.CURD;

public class Cmd {

private static String URL_PATH = "http://www.ruanyifeng.com/blog/atom.xml";
private static GetFeed getFeed = new GetFeed();
private static CURD curd = new CURD();

// 命令清单
public static void showHelp() {
System.out.println("sync  \t\t同步Feed。\n" + "list  \t\t列出最近的20篇文章。\n" + "show number  \t查看文章ID为number的内容。\n"
+ "help  \t\t显示全部命令。\n" + "quit  \t\t退出命令行。");
}

// 列出最近的20篇文章
public static void list() {
System.out.println("最近保存的文章:");
System.out.println("--------------------------------------");
/*
* cursor.size()解释 : Counts the number of objects matching the query.
* this does take limit/skip into consideration.
*
* cursor.count()解释 : Counts the number of objects matching the query.
*/
// 超过20篇的话,只列20篇;否则全部列出
DBCursor cursor = curd.queryAll("blogs");
if (cursor.count() > 20) {
for (int i = 0; i < 20; i++) {
System.out.println("标题:" + cursor.next().get("title"));
System.out.print("作者:" + cursor.next().get("author") + "\t");
System.out.println("发布时间:" + cursor.next().get("publishDate"));
System.out.println("内容:" + cursor.next().get("content"));
System.out.println("--------------------------------------");
}
} else {
for (int i = 0; i < cursor.count(); i++) {
System.out.println("标题:" + cursor.next().get("title"));
System.out.print("作者:" + cursor.next().get("author") + "\t");
System.out.println("发布时间:" + cursor.next().get("publishDate"));
System.out.println("内容:" + cursor.next().get("content"));
System.out.println("--------------------------------------");
}
}
}

public static void main(String[] args) {

String cmd;
Scanner in = new Scanner(System.in);

// 先把数据下载保存到数据库
getFeed.download(URL_PATH);

System.out.print("User>");
// 会以空格为分割符,不建议使用
// cmd = in.next();

// 以enter键为分割键;删除命令首尾的空白,便于比较
cmd = in.nextLine().trim();
while (true) {
if (cmd.length() == 4) {
switch (cmd) {
case "sync":
getFeed.download(URL_PATH);
break;
case "list":
try {
list();
} catch (Exception e) {
e.printStackTrace();
}
break;
case "show":
System.out.println("请输入完整命令,如:show 32\n或者  输入help,查看全部命令");
break;
case "quit":
System.exit(0);
break;
case "help":
Cmd.showHelp();
break;
default:
break;
}
} else if (cmd.length() > 4 && cmd.substring(0, 4).equals("show")) {

String[] arr = cmd.split("\\s+");
Pattern pattern = Pattern.compile("[0-9]*");
// 判断命令的参数是否为数字字符串
if (arr.length == 2 && pattern.matcher(arr[1]).matches()) {
int count = 0;
// 设置查询条件
DBObject querycode = new BasicDBObject();
querycode.put("id", arg[1]);
// 查询一条
DBCursor cursor = curd.query("blogs", querycode);
if (cursor != null) {
while (cursor.hasNext()) {

// ID匹配则显示内容
System.out.println("标题:" + cursor.next().get("title"));
System.out.print("作者:" + cursor.next().get("author") + "\t");
System.out.println("发布时间:" + cursor.next().get("publishDate"));
System.out.println("内容:" + cursor.next().get("content"));
break;

}
} else {
System.out.println("找不到相关文章!");
}
} else {
System.out.println("命令格式错误!标准格式:show number\n或者  输入help,查看全部命令");
}
} else {
System.out.println("请输入help,查看全部命令");
}

System.out.print("User>");
cmd = in.nextLine().trim();
}
}
}


希望大家能多多给些建议。谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  rss 阅读器 小Demo