【优化】命令行模式的RSS阅读器

通过最近两天的优化,已经解决了上次的全部Bug。

【新增模块及特性如下】:

1、手动输入URL,输入次数限制在5次(各自由更改)。

2、CheckURL类:判断URL是否有效。

3、CURD类:新增一次查询20条的功能。

4、Blog类:获取博客相关信息。

5、每次根据数据保存的文章数量,对插入的文章设置ID。

6、容错性能明显提高。

代码参考如下:

一 、判断输入的URL是否有效

/**
 * 检查URL是否有效
 * @author yyp
 *
 */

public class CheckURL {

    public static HttpURLConnection feedconn = null;

    public static boolean isConnected(String URL_PATH){

        if((URL_PATH!=null)&&(URL_PATH.length()>0)){
            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){
                    return true;
                }
            }catch(Exception ex){
                //ex.printStackTrace();
            }
            finally{          
                //手动选择关闭连接
            }
        }      
        return false;
    }
}

二 、关于MongoDB数据库操作

1、连接MongoDB数据库(单例模式)。(参考上次代码,未做优化)

2、设计DAO层接口(新增一次查询20条的功能)

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

public interface DAO {

    // 插入一条
    public boolean add(String collectionName, Document doc);

    // 删除一条
    public boolean delete(String collectionName, Document doc);

    // 查询全部
    public FindIterable<Document> queryAll(String collectionName);

    // 查询20条
    public FindIterable<Document> queryTwenty(String collectionName);

    // 查询一条
    public FindIterable<Document> query(String collectionName, Document doc);

    // 更新一条
    public boolean update(String collectionName, Bson bson, Document newdoc);

}

3、实现CURD操作(增、改、查、删)。(实现一次查询20条的功能)

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

public class CURD implements DAO {



    public CURD() {

    }

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

    // 删除一条
    @Override
    public boolean delete(String collectionName, Document doc) {
        // TODO Auto-generated method stub
        MongoDatabase mydb = MongoDBUtil.getDB();
        mydb.getCollection(collectionName).deleteMany(doc);
        return false;

    }

    // 查询全部
    @Override
    public FindIterable<Document> queryAll(String collectionName) {
        // TODO Auto-generated method stub
        MongoDatabase mydb = MongoDBUtil.getDB();
        // 找到表的数据项列表
        FindIterable<Document> blogs  = mydb.getCollection(collectionName).find();
        return blogs;
    }

    //查询20条
    @Override
    public FindIterable<Document> queryTwenty(String collectionName) {
        // TODO Auto-generated method stub
        MongoDatabase mydb = MongoDBUtil.getDB();
        // 找到表的数据项列表
        FindIterable<Document> blogs  = mydb.getCollection(collectionName).find().limit(20);
        return blogs;
    }

    // 查询一条
    @Override
    public FindIterable<Document> query(String collectionName, Document doc) {
        // TODO Auto-generated method stub
        MongoDatabase mydb = MongoDBUtil.getDB();
        // 找到表的数据项
        FindIterable<Document> blogs  = mydb.getCollection(collectionName).find(doc);
        if (blogs != null) {
            return blogs;
        }
        return null;
    }

    // 更新一条
    @Override
    public boolean update(String collectionName, Bson bson, Document newdoc) {
        // TODO Auto-generated method stub
        MongoDatabase mydb = MongoDBUtil.getDB();
        // 找到表的数据项列表
        mydb.getCollection(collectionName).replaceOne(bson, newdoc);
        return false;
    }


}

三 、Blog数据实体类

/**
 * 博客实体类
 * @author yyp
 *
 */

public class Blog {

    //private String id; //插入数据库时进行赋值
    private String title;
    private String author;
    private String publishedDate;
    private String content;

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getPublishedDate() {
        return publishedDate;
    }
    public void setPublishedDate(String publishedDate) {
        this.publishedDate = publishedDate;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }

}

四 、下载Feed源并逐条保存

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

    private boolean isFinished = false; // 下载是否完成
    int ID = 0;

    public void download(String URL_PATH) {
        if(CheckURL.isConnected(URL_PATH)){
            try{
                // 实例化feed输入流
                SyndFeedInput input = new SyndFeedInput();
                // 读取feed
                XmlReader reader = new XmlReader(CheckURL.feedconn);
                SyndFeed feed = input.build(reader);
                // 获取entry数量
                int entriesSize = feed.getEntries().size();
                SyndEntry entry;
                SyndContent content;
                //SyndImage img;

                for (int index = 0; index < entriesSize; index++) {
                    // 实例化entry
                    entry = new SyndEntryImpl();
                    // 获取第i个entry
                    entry = (SyndEntry) (feed.getEntries()).get(index);

                    //实例化content
                    content = new SyndContentImpl();
                    content = (SyndContent) entry.getContents().get(0);

                    //实例化img
                    //img = new SyndImageImpl();
                    //img = entry.getContents();

                    //获取blog数据
                    Blog blog = new Blog();
                    blog.setTitle(entry.getTitle().trim());
                    blog.setAuthor(entry.getAuthor().trim());
                    //设置日期格式
                    Format formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String date = (entry.getPublishedDate() != null ? formatter.format(entry.getPublishedDate())
                    : "");
                    blog.setPublishedDate(date.trim());
                    blog.setContent(content.getValue().trim());

                    //打印文章
                    /*System.out.println("----------------------");
                    System.out.println(blog.getTitle());
                    System.out.println(blog.getAuthor());
                    System.out.println(blog.getPublishedDate());
                    System.out.println(blog.getContent());
                    System.out.println("----------------------");*/


                    MongoDatabase mydb = MongoDBUtil.getDB();
                    //获取数据库保存的文章数量
                    long blogcount = mydb.getCollection("blogs").count();
                    //根据数据库的保存数量来设置ID
                    ID = (int)blogcount+1;

                    //当前文章与数据库的文章对比,不重复则插入
                    CURD curd = new CURD();
                    Document data = new Document();                     
                    MongoCollection<Document> collection = mydb.getCollection("blogs");
                    if(collection.count()==0){
                        System.out.println("正在同步第1篇......");                        
                        data.append("id", Integer.toString(ID))
                            .append("title", blog.getTitle().trim())
                            .append("author", blog.getAuthor().trim())
                            .append("publishedDate", blog.getPublishedDate().trim())
                            .append("content", blog.getContent().trim());
                        // 保存数据
                        curd.add("blogs",data);
                    }
                    else{                                       
                        int count = 0; // 统计当前标题与数据库已有标题不重复的次数
                        FindIterable<Document> docs = curd.queryAll("blogs");
                        for(Document doc : docs){                           
                            if(!(blog.getTitle().equals(doc.get("title")))){

                                ++count;
                                if(count==blogcount){                                   
                                    data.append("id", Integer.toString(ID))
                                        .append("title", blog.getTitle().trim())
                                        .append("author", blog.getAuthor().trim())
                                        .append("publishedDate", blog.getPublishedDate().trim())
                                        .append("content", blog.getContent().trim());
                                    // 保存数据
                                    curd.add("blogs",data);
                                    System.out.println("正在同步第"+ID+"篇......");
                                }
                            }else{
                                ++flag;
                                break;
                            }
                        }                                                   
                    }                   
                }
                isFinished = true;
            }catch(Exception ex){

            }
            finally{
                //同步完关闭连接
                CheckURL.feedconn.disconnect();
            }

        }else {
            System.out.println("请求失败!");
        }

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

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

/**
 * 命令行模式
 * @author yyp
 *
 */

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("------------------------------------");
        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退出命令行。");
        System.out.println("------------------------------------");
    }

    // 列出最近的20篇文章
    public static void list() {
        MongoDatabase mydb = MongoDBUtil.getDB();
        long blogcount = mydb.getCollection("blogs").count();
        if(blogcount==0){
            System.out.println("最新文章:0篇");
        }else{
            System.out.println("最新文章:"+blogcount+"篇");
            System.out.println("--------------------------------------");

            //对publidhedDate进行降序排序,把最近的文章排到最上面,方便一次性顺序输出
            Document sortcode = new Document();
            sortcode.put("publishedDate", -1);
            MongoDatabase db = MongoDBUtil.getDB();

            //System.out.println(db.getCollection("blogs").count());

            db.getCollection("blogs").find().sort(sortcode);

            // 只列20篇
            FindIterable<Document> blogs = curd.queryTwenty("blogs");
            blogs.forEach(new Block<Document>() {

                @Override
                public void apply(Document blog) {
                    // TODO Auto-generated method stub
                    System.out.println("标题:" + blog.get("title"));
                    System.out.print("作者:" + blog.get("author") + "\t");
                    System.out.println("发布时间:" + blog.get("publishedDate"));
                    System.out.println("内容:" + blog.get("content"));                
                    System.out.println("--------------------------------------");
                }
            });
        }

    }

    public static void main(String[] args) {

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

        //方便测试,每次开始先把数据全删除
        curd.delete("blogs", new Document());

        //手动输入网址,错误5次自动退出
        System.out.print("请输入Feed源网址:");
        URL_PATH = in.nextLine().trim();
        if(CheckURL.isConnected(URL_PATH)){
            System.out.println("网址有效!即将进入命令行模式...");
            System.out.println();
            //判断完网址,关闭连接 
            CheckURL.feedconn.disconnect();
        }else{
            int input_num = 5;
            while(input_num>0){         
                if(CheckURL.isConnected(URL_PATH)){
                    System.out.println("网址有效!即将进入命令行模式...");
                    System.out.println();
                    //判断完网址,关闭连接 
                    CheckURL.feedconn.disconnect();
                    break;
                }
                System.out.print("网址无效!请重新输入Feed源网址:");
                URL_PATH = in.nextLine().trim();
                --input_num;
                if(input_num==0){
                    System.out.print("系统已经退出!");
                    System.exit(0);
                }
            }
        }


        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()) {
                    // 设置查询条件
                    Document querycode = new Document();
                    querycode.put("id", arr[1]);
                    // 查询一条
                    FindIterable<Document> blogs = curd.query("blogs", querycode);
                    Document blog = blogs.first();
                    if(blog!=null){
                        System.out.println("--------------------------------------");
                        System.out.println("标题:" + blog.get("title"));
                        System.out.print("作者:" + blog.get("author") + "\t");
                        System.out.println("发布时间:" + blog.get("publishedDate"));
                        System.out.println("内容:" + blog.get("content"));        
                        System.out.println("--------------------------------------");
                    }else{
                        MongoDatabase mydb = MongoDBUtil.getDB();
                        long blogcount = mydb.getCollection("blogs").count();
                        System.out.println("温馨提示:只保存了"+blogcount+"篇文章!");
                        System.out.println("很抱歉!找不到相应编号的文章,请重新查找!");    
                    }   
                } else {
                    System.out.println("命令格式错误!标准格式:show number(number必须是正整数)\n或者  输入help,查看全部命令");
                }
            } else {
                System.out.println("请输入help,查看全部命令");
            }

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

至此,命令行模式的RSS阅读器已经完成。

有兴趣的话,再把它做成 ★Web前端★ 的模式,那就更漂亮了!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值