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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值