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

来源:互联网 发布:mysql语句书写顺序 编辑:程序博客网 时间:2024/04/30 10:25

最近收到一个面试的小作业 :完成命令行模式的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();        }    }}

希望大家能多多给些建议。谢谢!

0 0
原创粉丝点击