0602 播客框架分析

来源:互联网 发布:综艺节目 字幕 软件 编辑:程序博客网 时间:2024/04/28 23:34

1 前言

这是一个个人播客的项目
其实想做一个个人博客吧, 很早就有想法了, 但是一直没有精力去做, 最近没找到工作, 就闲下来了, 自己仿照着一位网友的播客[http://lvkun.github.io/] 自己写了一个

基本信息请详见 : “06 最近做的一个播客站点, 请大家没事的时候’玩儿’一下”

站点首页效果如下
1 首页
这里写图片描述

2 简历页
这里写图片描述

3 播客详情页
这里写图片描述

4 发帖页
这里写图片描述

2 介绍

先放上两张框架图
服务器端
这里写图片描述

站点资源结构
这里写图片描述

数据库

先简单扯一下涉及的表, 不多两张, blogList, commentList
create table if not exists blogList(
id integer primary key autoincrement,
path varchar(256),
tag varchar(64),
createTime varchar(32),
good integer,
notGood integer,
visited integer
);
这里写图片描述
这张blogList表主要存放的是blog的基本数据 [blogId, path[播客内容存放的位置], 标签, 创建的日期, 顶踩, 访问数 ]


create table if not exists commentList(
id integer primary key autoincrement,
blogIdx integer,
floorIdx integer,
commentIdx integer,
name varchar(64),
email varchar(64),
headImgIdx integer,
date varchar(64),
toUser varchar(64),
privilege varchar(64),
comment varchar(256)
);
这里写图片描述
这张commentList表主要存放的是comment的基本数据 [commentId, 播客id, 楼层id, 当前评论在该楼层中的id, 评论用户昵称, 评论用户邮箱, 用户选择的头像, 用户评论的日期, 用户评论的对象, 权限, 评论的内容 ]


action

这里我们主要谈的是服务器端的action, 以及业务逻辑的处理
< servlet-name>blogConfigAction< /servlet-name>
< servlet-name>blogResumeAction< /servlet-name>
< servlet-name>blogListAction< /servlet-name>
< servlet-name>blogReviseAction< /servlet-name>
< servlet-name>blogPublishAction< /servlet-name>
< servlet-name>blogGetAction< /servlet-name>
< servlet-name>blogDeleteAction< /servlet-name>
< servlet-name>blogLoginAction< /servlet-name>
< servlet-name>blogLogoutAction< /servlet-name>
< servlet-name>blogSenseAction< /servlet-name>
< servlet-name>blogCommentAction< /servlet-name>
< servlet-name>blogCheckCodeAction< /servlet-name>

1 blogConfigAction : 获取顶部的配置
这里写图片描述
这个当然是谁来请求都给了, 对于是否登录的用户有一些区别
基本配置 : blog, resume, github, csdn, 博主昵称, 个性签名 [基本配置存在为/com/hx/config/config.json中]
    对于登录用户 服务器端需要提供登出配置, 以及发帖配置
    对于未登录用户 服务器端需要提供登陆配置

2 blogResumeAction : 获取博主的简历
这里写图片描述
这个不多说, 简历配置文件为[/com/hx/config/resume.json中]

3 blogListAction : 获取当前标签的当前, 的所有播客列表 [每页显示多少数据在 Constants配置] [为了简单, 我就没有将其单独拿出到一个配置文件了]
这里客户端需要传入两个参数进来, 一个是tag, 一个是pageNo, 该action首先校验这两个参数, 如果不合法将其设置为默认数据, 然后剩下的业务委托给BlogManager, 然后封装数据, 回传给客户端

4 blogGetAction : 获取给定标签下面选中的给定播客的信息, 获取选中播客的数据[标题, 标签, 内容, 顶踩, 访问量, 关联当前标签下当前播客的上一页, 下一页]
这里客户端需要传入两个参数, tag, blogId, 首先校验blogId是否合法[是否为数字, 该blogId对应的blog是否存在], 然后 校验是否访问过当前播客[是否访问的数据存在cookie][更新访问量], 获取当前播客的数据[BlogManager], 然后获取当前播客的评论[CommentManager], 根据是否登录返回对应的权限按钮, 然后获取当前标签下的上一页下一页的播客的blogId, 填充到响应的数据中返回

5 blogPublishAction : 发布一条播客信息
这里客户端需要传入四个数据, title, blogContnet, tags, checkCode, 首先校验用户是否登录, 然后校验校验码, 然后对播客相关数据进行校验, title, tags, content 如果均校验通过, 则发布播客信息, 以及响应对应的回执信息给客户端

6 blogReviseAction : 修改播客的信息
这里客户端需要传入五个数据, blogId, title, blogContnet, tags, checkCode, 首先校验用户是否登录, 在校验校验码, 然后在对播客相关数据进行校验, id, title, tags, content进行校验, 如果校验均通过
     则判断是否修改了播客的名字
          如果修改了则需要写出更新content, 并更新播客的名字了[持久化的html, 以及 内存中缓存的播客数据, 数据库]
          否则 直接写出更新的content, 并修改缓存在内存中的播客数据
以及响应对应的回执信息给客户端

7 blogDeleteAction : 删除一条播客
这里客户端需要传入一个blogId, 首先校验用户是否登录, 然后校验blogId是否合法, 删除该blog在内存中的信息, 并删除该blog对应的持久化的内容文件, 以及响应对应的回执信息给客户端

8 blogLoginAction : 登录的action
这里用户需要传入两个数据, userName, password, 校验用户名密码的规范, 校验用户名密码的正确性, 如果校验通过, 则向session中存储一个userName, 一个token, 用于验证用户是否登录, 并存放管理员的用户偏好信息[评论的时候就不用填写userName & email & headImage 鸟], 根据是否登录成功, 跳转到播客首页, 或者登录页面

9 blogLogoutAction : 登出的action
校验用户是否登录, 如果登录了则为合法用户, 删除sessioin中的userName & token & 用户偏好信息[其实这个应该存放在cookie中..], 否则记录其信息, 写日志

10 blogSenseAction : 顶踩系统
用户需要传入一个数据, 顶 或者踩, 服务器端校验用户是否顶踩过, 如果没有 则更新该blog的顶踩数, 存放该用户的顶踩信息到cookie,
     如果该用户顶踩过, 判断传来的顶踩是否和之前的顶踩相同, 如果相同则取消该用户的顶踩, 否则则 去掉之前的顶踩, 更新为现在的顶踩

11 blogCommentAction : 用户评论系统
这里用户需要传入8个数据, blogId, floorId, commentId, userName, email, headImageIdx, toUser, commentBody

评论分为两种
一种是评论当前播客 : 对于这种blogId, 以及commentId确定, 服务器端需要确定floorIdx
另一种是评论某一个评论的用户[楼中楼] : 对于这种blogId, 以及floorId确定, 服务器端需要确定comentIdx

首先 校验blogId, floorId, commentId, 然后在校验userName, email, toUser, commentBody, 如果都都校验通过了, 则校验blogId对应的blog是否存在, 如果以上校验均通过, 则添加该评论, 返回客户端回执信息, 以便于客户端处理”是否添加楼层”

12 blogCheckCodeAction : 生成验证码
随机生成四个长度的数字, 以及部分干扰线, 绘制成Image返回给客户端

日志, 刷新更新的数据到db

当当前应用加载到tomcat的时候, 会启动一个InitAndCheckUpdateListener的Listener, 这个listener的作用是干什么的呢 ?
第一 : 初始化播客数据, 从db中获取所有的播客数据
第二 : 启动一个定时任务, 隔一段时间定时检查是否存在更新的blog, 或者评论, 如果存在, 则将其持久化到数据库, 检查是否存在日志, 如果存在则将其刷出到日志文件

对于更新的blog, 评论, 日志, 当更新的数据达到一定的阈值的时候, 会直接将其持久化 [详见 各个模块的注释]

线程同步

主要集中在BlogManager, CommentManager, 中因为各个action的核心业务处理主要是委托给了这二位
先说BlogManager吧
// blogList, tagList, tag到tag对应的博客数的集合
// 增加的播客的集合, 更新的播客的集合, 更新sense, visited的播客集合, 删除的播客的集合
// 同步用的对象 [initLock 用于操作数据库, updateLock 用户维护addedList, updatedList, deletedList的获取以及更新]

private static Map< Integer, Blog> blogList = new ConcurrentHashMap< >();private static Map< String, List< Integer>> tagList = new ConcurrentHashMap< >();private static Set< TagToBlogCnt> tagToBlogCnt = new TreeSet<>();private static List<Blog> addedList = new ArrayList<>();private static Map<Integer, Blog> updatedList = new HashMap<>();private static List<Blog> deletedList = new ArrayList<>();private static Map<Integer, Blog> visitSenseUpdatedList = new ConcurrentHashMap<>();public static Object initLock = new Object();public static Object updateLock = new Object();// TagToBlogCnt临时对象 [所有的使用场景均为同一个对象的同步快中, 线程安全]// 当前blogId的计数器 [unsafe 线程安全]private static TagToBlogCnt tagToBlogCntTmp = new TagToBlogCnt();private static AtomicInteger curBlogId = new AtomicInteger(0);

对于CommentManager
// 缓存的评论 [一定的个数], 缓存的播客评论的id的结合
// 播客的id到访问次数的映射
// 缓存的所有增加的评论, 缓存的增加评论的播客的评论的集合, 增加评论的各个播客id的集合
// 同步用的对象[updateCacheLock用于维护cachedComments & cachedCommentsBlogId, updateAddCommentsLock用于维护addComments, updateAddBlogsCommentLock用于维护addBlogsComments & addBlogsId, deleteCommentsLock用于维护deleteCommentsByBlogIdx & deleteCommentsByFloorIdx & deleteCommentsByCommentIdx]

private static Queue< CommentEntry> cachedComments = new PriorityQueue<>(Constants.cachedComments);private static Set< Integer> cachedCommentsBlogId = new HashSet<>();private static Object updateCacheLock = new Object();private static Map<Integer, Integer> blogGetFrequency = new ConcurrentHashMap<>();private static List<Comment> addComments = new ArrayList<>(Constants.addedCommentsListSize);private static Object updateAddCommentsLock = new Object();private static List<CommentEntry> addBlogsComments = new ArrayList<>(Constants.addedCommentsListSize);private static Map<Integer, Integer> addBlogsId = new HashMap<>();private static Object updateAddBlogsCommentLock = new Object();private static Object dbLock = new Object();private static List<Integer> deleteCommentsByBlogIdx = new ArrayList<>(Constants.addedCommentsListSize);private static Map<Integer, List<Integer>> deleteCommentsByFloorIdx = new HashMap<>(Constants.addedCommentsListSize);private static Map<Integer, List<Integer>> deleteCommentsByCommentIdx = new HashMap<>(Constants.addedCommentsListSize);// 这里为了简单, 就将这三个更新的对象关联在一起了..private static Object deleteCommentsLock = new Object();

从上面可以看出对于BlogManager, 缓存了所有的播客的信息
CommentManager 维护了一定数量的播客的评论[cachedComments], 还维护了一定数量的更新了播客评论的播客的评论[addBlogsComments]
至于更加详细的情况, 请详见代码!

3 代码

https://github.com/970655147/HXBlog
[请注意引用依赖的包哦, 详细需求的包详见上面的资源框架图的/WebRoot/WEB-INF/lib]

依赖的jar包 : http://download.csdn.net/detail/u011039332/9273869

这里放出代码的目的是为了相互学习, 以及多点朋友来发现这个系统中的bug, 然后来完善其, 切勿用作作业!

使用截图
1 评论
这里写图片描述

2 各个头部功能
这里写图片描述

3 更新播客
这里写图片描述

======================= add at 2016.03.20 =======================
今天, 更新了一下界面, 看起来更加充实了些。。
这里写图片描述


参考
servlet 乱码问题处理
http://blog.csdn.net/xiazdong/article/details/7217022 –2015.10.30

sql 增加, 删除多条记录
http://zhidao.baidu.com/link?url=pmKIkW6gd7Wl3WGgsWA_NF3ODY-YbVaoYfggR7snSdiqRWumV6AM7FwAFinUT-GRWcL2JOZg4aVl6uq3UqGTGa
http://www.cnblogs.com/qanholas/archive/2011/07/19/2110716.html –2015.11.03

myeclipse 发布项目到tomcat上面不编译.class
http://blog.sina.com.cn/s/blog_9965673001014ymu.html
http://www.iteye.com/problems/55598
http://blog.csdn.net/eminem2011/article/details/6634563
http://zhidao.baidu.com/link?url=E0BRJQ1irEPxI6QK8wsWZWf6OL0y5SdwI7ar8HXI-gd5MBXoEyLHxlhp4WN1g6D-Yz_1ac6dVMaZUoZ3szIU63BRXRfMeIfb2n_URt-IqAu
http://bbs.csdn.net/topics/390110785 –2015.11.03

ueditor 上传图片
http://blog.csdn.net/lucherr/article/details/7680518
http://anyhole.blog.51cto.com/2003910/1281359 –2015.11.10

模态框问题参考
http://www.jb51.net/article/32590.htm
http://www.runoob.com/bootstrap/bootstrap-v2-modal-plugin.html
http://zhidao.baidu.com/link?url=HaczrnaC8N4xNSKYSiclCm6moCrGGJceOKtfjiMukdBzTa-Rb7VSWpMCnTr6r1wi8ivacyVE4TniKVcQcO-dh_ –2015.11.10

0 0