个人博客系统的设计与实现

更新时间:2024-01-20 05:43:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

个人博客系统的设计与实现

年级专业:

学 号:

姓 名:

计算机科学与技术学院

1

摘 要: 随着手机、平板等手持终端访问设备的普及,越来越多的用户希望通过网络平台进行互动交流,同时展现自己的个性,传播自己的思想,而通过个人博客发布信息是一个使用频率较高的方式。本课题建立一个交互简捷的博客系统,方便在校学生发布信息进行交流,可以将个人生活经验或学习笔记心得等发布到系统中,方便其他同学的查看讨论。这能极大地促进同学间思想交流和互动,扩大了同学的交际圈,并且在扩大获取信息的渠道的同时,还能提高学习兴趣,增加生活情趣。系统使用Java + JSP + Tomcat + MySQL技术实现。

关键词: 个人博客,Blog,Web应用,JSP,MySQL

随着手机、平板等手持终端访问设备的普及,普适计算越来越渗入人们的生活。跟随发展的就是个性化服务,如网络发布、签名、预约等都被极大地赋予了个人特色,越来越多的用户希望通过网络平台进行互动交流,同时展现自己的个性,传播自己的思想。著名的网站包括Facebook等。很多人对发生在自己身边的事以及对生活的一些感悟愿意用文字或图片的方式记录下来发到网络上与他人分享交流,其中通过个人博客发布是一个使用频率较高的方式。本课题拟建立一个交互简捷的博客系统,方便在校学生发布信息进行交流,可以将个人生活经验或学习笔记心得等发布到系统中,方便其他同学的查看讨论交流。

1 系统设计指导思想

由于系统需要具有普适的特性,因此建立以Web服务为中心的系统是最优的架构。使用传统的B/S架构能接纳多种终端设备的访问,如使用笔记本电脑、台式计算机、手机、平板电脑等设备。结合实际的需要,技术实现上将以普通Web结合Wap的方式实现系统功能的访问,并且这两种技术架构相近,可以统一到Web服务器中一起管理。

2 系统需求论述

根据前面的分析与定位,本博客系统主要用于校内同学的使用,因此需求的重点也反映在同学平时生活中的明显的和一些潜在的期望。就主要功能来说,核心在于创建自己的博客空间,在博客空间中方便的发表博文,支持他人在线评论互动,同时能方便地查阅他人的博文并添加评论。同时由于潜在的需求期望增加获取信息的渠道,系统中增加创建兴趣小组的功能,将小组的最新消息自动发布到组员,并提供小组讨论的页面空间。另外系统提供站内信功能,帮助简化互发消息的管理,这样系统能自主控制所有消息,并能保留消息的历史信息,方便消息维护。

系统的功能性需求如下图。

<>搜索<>查看博文登录系统评论博文登出系统浏览博客创建小组注册搜索小组<>搜索主题<>小组交流评论主题<>空间信息维护模块管理<>发表博文博主<>分类管理博文管理关键字管理 其中各功能性需求简要说明如下:

简单的系统登入登出及注册功能在这里不再详述。其他重要的功能主要集中在博客访问和博主访问这两个角色上,其中博主角色具有博客角色具备的所有的系统功能。

博客可以进入系统浏览查看某博主的博文并回复,或根据关键字搜索得到相关的博文信息,另外可以进入小组空间查看小组的最新信息,同样可以利用搜索功能查询小组中的相关信息。如果没有找到相关主题的小组信息,则可以创建新的小组并接纳成员访问。在小组中可以浏览发帖信息并回帖参与交流。

博主角色能操作的功能主要集中于自己的博客空间方面,主要包括:发布博文管理,空间信息管理,回复管理,空间模块管理,外观方案管理,设置头条或置顶管理,分类管理,关键字管理,好友管理,常用链接管理,背景音乐管理。这几个模块的访问一般是博客主人身份才能操作。

对于系统管理员角色的操作,主要侧重于系统的运营与维护方面的功能。主要包括系统级别的用户管理、系统级别的博客与小组信息维护、系统属性设置、系统状态检查与监测、系统数据的导出与导入、系统的启动与关闭,具体如下面的用例图所示。

启动系统用户维护关闭系统管理员系统属性设置博客信息维护小组信息维护系统状态检查与监测系统后台数据维护 3 系统分析与设计

基于系统的需求,这个章节主要陈述分析得出系统的分析模型和设计模型,从逻辑上理解系统的实现方式和操作方式。下面叙述中没有严格按分析和设计划分小节,而是大体按照几个主题进行了陈述,将分析结果与设计结果大体连贯起来,后续的章节将介绍具体的实现。

3.1 系统的总体分析

本系统使用常见的三层架构,即界面表示层、业务逻辑层、数据持久层。其中表示层

的职责主要集中于处理Web页面的数据显示、接收用户输入和各类操作,属于整个系统的最前端,但其中没有系统的操作逻辑,仅仅包含简单的页面交互方面的处理逻辑,一般使用JS脚本来生成浏览器端的交互逻辑,并使用脚本将输入数据或操作结果反馈到后台业务逻辑层。

3.2 分析类的获取

确定了主要的系统用例,接下来需要得出分析类模型,用于评估整个系统,也起到了承接分析与启下设计的作用。归纳一下系统的功能,并综合操作特性,得到如下几个综合的操作界面类型(这里统一以UI为后缀,表示用户界面):

主页面(MainUI):是系统的首页面,主要呈现登录模块、搜索模块、所有博客空间最新更新情况统计、所有小组更新情况统计、推荐的博客与小组的内容展示、讨论热烈的话题汇总、博客和小组排行榜、广告模块等信息。

个人主页面(UserMainUI):用于用于个人有关的信息设置与管理,包括个人博客汇总信息(一个用户可以有多个博客空间)、创建小组管理、参与小组的最新情况、书签管理(用于记录一些常用链接)、个人信息管理模块、搜索模块、登录模块。

博客页面(BlogUI):即个人博客空间,包括个人信息模块、搜索模块、登录模块、标题模块、书签模块、访客模块、发帖信息模块、近况模块、推荐小组模块、推荐博客模块、通告模块、广告模块(系统内用户发布、非商业广告)。

博客管理主页面(BlogMgmtUI):用于对当前博客空间进行设置,包括标题设置、界面设置、模块设置、访问性设置、发帖设置、回复设置、访客信息管理模块。

小组主页面(GroupUI):主要呈现某小组的信息,包括标题、简介、空间发帖、成员、搜索模块、登录模块、提示栏个人信息显示模块、近况模块、推荐小组模块、推荐博客模块、通告模块、广告模块(系统内用户发布、非商业广告)。

小组管理主页面(GroupMgmtUI):用于小组内的信息管理。包括标题设置、界面设置、成员及访问性设置、发帖设置、回复设置。

搜索页面(SearchUI):主要用于站内的信息搜索,包括用户、博客空间、小组、主题、关键字、一般包含信息的搜索及其结果。

系统管理页面(AdminUI):汇总了系统的管理功能,包括系统开关机模块、系统属性设置模块、系统数据管理模块、系统用户管理模块、状态显示模块、统计信息模块。

控制类的作用集中体现了系统的业务逻辑,因此最终的控制类大部分都映射到了业务逻辑层,根据用例模型中的系统功能性描述,经过统筹安排,得出系统中的控制类如下:

登录控制类(LoginWorkflow):专门负责登录的控制逻辑。

登出控制类(LogoutWorkflow):针对登出系统专门进行处理。虽然网页型访问一般设有30分钟会话有效期,但这里还是单独进行处理,保证数据的一致性。

注册控制类(RegisterWorkflow):专门处理新用户注册的问题。

查找功能在各个对象上都有体现,最终界面将分类显示,因此查找功能这样组织: 综合查找控制类(FindWorkflow):用于统一各类查询及汇总各查询结果。 小组查询(FindGroupWorkflow):针对小组进行筛选查询的控制类。 用户查询(FindUserWorkflow):用于对用户进行各类信息进行筛选查询。 博客空间查询(FindBlogWorkflow):基于输入值查询满足条件的博客空间。 发帖查询(FindItemWorkflow):针对发帖回帖进行筛查,可以对博客空间和小组内的发帖同时筛选。

针对发帖管理的控制类组织为发帖、显示、回复三个控制类。

创建新帖控制类(CreateItemWorkflow):博客空间和小组空间里面使用相同的控制逻辑,因此统一为CreateItemWorkflow控制类,不同的就是发往的空间不同而已。

显示发帖控制类(ListItemWorkflow):针对显示自定义的要求较多,因此单独设计显示控制逻辑,在博客空间和小组空间中使用相同的控制类,最终显示在界面类中加工生成不同的页面风格。

回帖控制类(ReplyItemWorkflow):用于管理回帖的过程控制,与创建新帖很相近,但地位不同。

另外几个控制类集中于管理功能,包括:

发帖条目的管理控制类(ItemMgmtWorkflow):对空间中所有的发帖进行管理的控制类,体现在对条目的增删改查,对回复的管理,附加信息以及状态的管理。

博客管理控制类(BlogMgmtWorkflow):对博客空间的信息进行配置,对各模块进行配置与显示,以及置顶发帖、管理链接关键字、背景音乐处理等。

小组管理控制类(GroupMgmtWorkflow):针对小组的各管理功能,包括设置小组状态、批复加入请求、任命管理者、发帖管理等。

用户管理控制类(UserMgmtWorkflow):针对用户自身进行管理,包括更改信息,管理好友等操作。

系统管理控制类(SysMgmtWorkflow):所有针对系统的管理和操作都纳入这个控制类中,当然设计阶段可以对设计类进行调整,划分出分角色的管理类实现。

3.3 系统关键抽象概念的获取与分析

下面分析系统的领域模型。在这个系统中领域模型的重要作用是显而易见的,所有用

户都围绕着这个模型在工作。匿名用户可以浏览系统中的各种信息,包括浏览博客空间和小组空间的信息;普通博客可以查看其它博客空间的信息,并能够进入小组进行讨论;而博主则可以在自己的博客空间发布博文并进入小组讨论,所有人都在围绕领域模型浏览信息或操作信息。因此根据前面的假设和扩展,初步得出下面的领域模型结构。

根据前述需求,一个用户可以创建多个博客空间,并可以发布多条博文,每条博文具有一个特定的主题,并且可以具有多个分类关系,可以包含多条回复的评论,并且具有一个特定的状态。用户可以创建一个小组,并且小组可以加入多个用户,小组中可以发帖、回帖。

由于博客空间和小组内的消息发布在操作和结构的性质上是一致的,不同之处在于小组内任何人都可以发帖,而博客空间内只允许博主发帖,这在设计实现中只要检查当前是博客还是小组,操作者是否拥有当前博客空间即可解决权限问题,因此在系统设计中将两者统一处理,将消息发布对象统称为发帖条目(PostItem),回复统一为回帖条目(ReplyItem)。每个发帖条目关联一个主题(Subject),并具有零到多个关键字(分类)(Keyword)。当然发帖条目有不同的状态(Status),如草稿、扣留发布、正常发布、置顶发布、隐藏、删除、允许回复、禁止回复。另外博客博主仅仅在检查操作时有区分权限的关系,因此将两者统一为用户(User)。

用户新建发帖后,键入的内容自动保存,此时发帖属于草稿状态;编辑完成点击发布后,发帖进入待发布状态;进入待发布状态的帖子由系统自动判断是否有违规定的地方,进入审批状态,结果若通过则进入发布状态,若未通过则进入待发布状态,此时用户可以继续编辑或丢弃帖子,因此在待发布状态下的帖子都是没有审核通过的帖子;处于发布状态的帖子是可以显示在空间里面的,当然如果用户选择隐藏则不显示在空间内;超过时限的帖子则进入存档状态,存档状态下的帖子都将被移到到备份库中压缩存储。

3.4 分析类交互

下面选取一个简单的登录过程和发布帖子这两个用例来说明分析类的交互过程分析。 登录过程在所有系统中都有体现。一般在操作的设计中,首次登录的时候只需要输入用户标识和密码即可登录,当用户名或密码不正确时,在后续的界面上加入验证码来防止破解攻击,多次无效后(一般控制在10次)账户便被锁定。本系统中由于没有太大的安全性需求,因此即使多次登录失败账户也不需要锁定,只需加入验证码即可。

下面分析发布帖子的交互过程。界面中使用CKEditor控件可以完成文字修饰、上传图片及编排版式的功能,最终在浏览器上生成一个HTML的描述文本,提交后服务器端接收这个HTML描述文本,设计中将这个描述文本直接存入数据库中即可。浏览帖子的时候只要取出此描述文本放入页面中即可显示原先编辑好的效果。提交此数据后,首先确认并检查用户权限,是否可以发帖,通过后将发帖内容交给系统检查,这里由ItemChecker接口来完成检查工作,最终设计中只要实现这个接口就可以完成多种检查方法。检查通过后,发帖内容存入数据库,同时用户可以浏览最终的效果。

4 系统设计

整个系统使用Java语言作为开发的基础语言,Web界面部分搭配使用HTML、CSS、J送JS以及JSP技术来实现。最终发布的系统对平台没有特别大的强制要求,因为基于Java开发的Web型服务项目,可以选用流行的Tomcat服务器搭建,这些都是开源免费的平台。数据库可以使用MySQL数据库,它也是免费使用的数据库,很多大型网站都选用了MySQL作为自己的数据库支持平台。开发过程中,选择平台搭建于Windows系统下,当然发布时可以选择Windows平台或Linux平台,两者的环境下都有上述的开源软件。硬件平台没有强制性要求。

4.1 系统数据库的结构设计

根据前面的需求描述及领域模型的系统关键数据抽象,分析得出系统的数据库表结构如下面的关系图所示,其中基本表(Table)用于记录底层的核心的信息。

另外,必须基于基本表在其上层创建一些视图(View)以方便某些角度的数据的操作。 整体的逻辑结构如图所示:

数据库表的总体关系图

5 系统实现

系统实现中,主要是根据设计模式实现其中定义的方法和功能即可。在软件项目中实现的工作量比设计要轻很多,这里选取之前的介绍的登录实现与发帖相关部分的实现来介绍具体实现过程。

5.1 登录的实现

登录页面的实现首先是判断登录名和密码是否为空,如果都不为空,提交给UserServlet处理,并且连接数据库并判断post传过来的数值内容是否与数据库中的内容一致,如果一致就允许用户登录相应界面。

页面组件HTML代码组织如下:

用户登录

<% String message = (String)request.getAttribute(\ If (message != null){

out.print(\

} %>

后台操作代码为:

public class UserServlet extends HttpServlet {

private static final long serialVersionUID = 2796904463414937664L;

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); }

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String method = request.getParameter(\ if(method == null){ method = \ }

else if(method.equals(\ login(request,response);

}else if(method.equals(\ logout(request,response);

}else if(method.equals(\ changePassword(request,response); } }

// 登录

public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

request.setCharacterEncoding(\

String username = request.getParameter(\String password = request.getParameter(\

String sql=\

+ \

String params[] = {username, password}; QueryRunner qr = DbHelper.getQueryRunner(); User user = null; List list = null; try{

list = (List)qr.query(sql, new BeanListHandler(User.class),params); }catch(SQLException e){ e.printStackTrace(); }

If (list.size() > 0){

user=(User)list.get(0);

HttpSession session = request.getSession(); session.setAttribute(\

request.getRequestDispatcher(\ }else{

request.setAttribute(\用户名或密码不正确\

request.getRequestDispatcher(\ } }

// 退出

public void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session=request.getSession(); session.invalidate();

response.sendRedirect(\}

//修改密码 public void changePassword(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String oldPassword = request.getParameter(\ String newPassword = request.getParameter(\ String reNewPassword = request.getParameter(\ HttpSession session = request.getSession(); User user = (User)session.getAttribute(\ if (!user.getPassword().equals(oldPassword)){

request.setAttribute(\您输入的原密码错误\

request.getRequestDispatcher(\ } else if (newPassword.equals(reNewPassword)){

String sql = \

}

String params[]={newPassword,user.getId().toString()}; QueryRunner qr = DbHelper.getQueryRunner(); try{

qr.update(sql,params); }catch(SQLException e){ e.printStackTrace(); }

response.sendRedirect(\ } else {

request.setAttribute(\两次输入密码不一致\

request.getRequestDispatcher(\ } }

5.2 发帖的实现

帖子的基本信息设置项分为几部分内容,核心包括如下部分。

private int id;

private String title; private String content; private Date createDate; private String categoryName; private Integer categoryId;

发帖前的验证工作由下面代码实现。

public class PreAddBlogServlet extends HttpServlet {

private static final long serialVersionUID = -4836172756151206293L;

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { list(request,response); }

public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session=request.getSession(); if (session == null){

response.sendRedirect(\ }else{

String sql = \id,content,rank from t_keyword order by rank desc,id desc\ QueryRunner qr = DbHelper.getQueryRunner(); List list = null; try {

list = (List) qr.query(sql, new BeanListHandler(Category.class)); } catch (SQLException e) {

}

} }

e.printStackTrace(); }

request.setAttribute(\

request.getRequestDispatcher(\ request, response);

具体发帖操作由如下代码实现。

public class AddBlogServlet extends HttpServlet { private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doPost(request, response); }

protected void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding(\ HttpSession session=request.getSession(); if (session == null){

response.sendRedirect(\ } else {

String title = request.getParameter(\ String content = request.getParameter(\ Log.println(title); Log.println(content); int result = 0;

String sql = \

+ \

String params[] = { title, content };

QueryRunner qr = DbHelper.getQueryRunner(); try {

result = qr.update(sql, params); // query() } catch (SQLException e) { e.printStackTrace(); }

String message = \ if (result == 0){

message=\添加帖子失败\ } else {

message=\添加帖子成功\ }

request.setAttribute(\

request.getRequestDispatcher(\

} } }

5.3 查看帖子模块

查看发帖包括查看所有发帖和按发帖编号查看一篇帖子,相关操作提交给HomeServlet执行。

public class HomeServlet extends HttpServlet {

private static final long serialVersionUID = -481044148316500873L;

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncod ing(\

String method = request.getParameter(\ if (method == null){

main(request,response);

request.getRequestDispatcher(\ } else if(method.equals(\ main(request,response); get(request,response);

request.getRequestDispatcher(\

.forward(request, response);

} }

//根据id读取一篇帖子

public void get(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id=request.getParameter(\

QueryRunner qr = DbHelper.getQueryRunner();

String sql = \id=\ //根据id读取一篇帖子 PostItem item = null; try {

List list=(List)qr.query(sql, new BeanListHandler(PostItem.class)); item = (PostItem)list.get(0);

} catch (SQLException e) { e.printStackTrace(); }

//根据id读取帖子所有评论

sql = \

+ \

List commentList = null; try{

commentList = (List) qr.query(sql, new BeanListHandler(Comment.class)); }catch(SQLException e){ e.printStackTrace(); }

request.setAttribute(\

request.setAttribute(\}

//读取所有帖子

public void main(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

String cid = request.getParameter(\ String sql = null; if (cid == null){

sql = \

+ \+ \+ \

} else {

sql = \

+ \+ \+ \

}

// DButils中核心类,生成对象时传递数据源对象 QueryRunner qr = DbHelper.getQueryRunner(); List items = null; try {

items =(List)qr.query(sql, new BeanListHandler(PostItem.class)); }catch(SQLException e){ e.printStackTrace(); }

sql = \ List categorys = null; try{

categorys=(List)qr.query(sql, new BeanListHandler(Category.class)); }catch(SQLException e){ e.printStackTrace(); }

// 帖子类别

sql = \ +\ List comments = null; try{

comments=(List)qr.query(sql, new BeanListHandler(Comment.class));

}

}

}catch(SQLException e){ e.printStackTrace(); }

request.setAttribute(\

request.setAttribute(\request.setAttribute(\

结 论

通过此次个人博客系统的设计,我对Java Web程序设计有了进一步的了解,更重要的是对数据库的相关操作也有了切身的体会。对系统设计及开发有了比较全面的理解。首先,通过对系统进行需求分析,确定各个功能和非功能需求;然后一个个具体地对其进行分析设计,并且仔细检查看是否有矛盾或错误;在完成这一步之后再开始编写实现程序,最终通过对象协作和对象中的方法操作把各个系统功能表现出来。

在实际编程过程中遇到了各种不同类型的错误,有时候是一些很明显的语法错误,这些一般编译器有提示,或者编译过程中会报告错误所在,还有一些不明显的隐性错误却让我很头痛,只好仔细核对分析和设计模型,并对照实现代码利用断点调试来一步步检查错误。同时也翻阅了大量的书籍,尽管大部分书都只是翻看了其中一部分而已,却给了我非常有价值的经验和知识。

参考文献

[1]维科中文[EB/OL]. http://zh.wikipedia.org/wiki/Blog

[2]陈丹丹,王国辉,朱晓. 实战突击:Java Web项目整合开发[M].北京:电子工业出版社,2011.

[3]郭克华. Java Web程序设计[M]. 北京:清华大学出版社,2011.

[4]李德兵,尹战文,王洪明. Java EE基于Hibernate的ORM框架[J].电子技术,2010(2),7-8

[5]王国辉,王毅,王殊宇.Java Web开发典型模块大全[M]. 北京:人民邮电出版社,2009. [6](美)Paul DuBios.MySQL权威指南[M].北京:机械工业出版社,2004.

}

}

}catch(SQLException e){ e.printStackTrace(); }

request.setAttribute(\

request.setAttribute(\request.setAttribute(\

结 论

通过此次个人博客系统的设计,我对Java Web程序设计有了进一步的了解,更重要的是对数据库的相关操作也有了切身的体会。对系统设计及开发有了比较全面的理解。首先,通过对系统进行需求分析,确定各个功能和非功能需求;然后一个个具体地对其进行分析设计,并且仔细检查看是否有矛盾或错误;在完成这一步之后再开始编写实现程序,最终通过对象协作和对象中的方法操作把各个系统功能表现出来。

在实际编程过程中遇到了各种不同类型的错误,有时候是一些很明显的语法错误,这些一般编译器有提示,或者编译过程中会报告错误所在,还有一些不明显的隐性错误却让我很头痛,只好仔细核对分析和设计模型,并对照实现代码利用断点调试来一步步检查错误。同时也翻阅了大量的书籍,尽管大部分书都只是翻看了其中一部分而已,却给了我非常有价值的经验和知识。

参考文献

[1]维科中文[EB/OL]. http://zh.wikipedia.org/wiki/Blog

[2]陈丹丹,王国辉,朱晓. 实战突击:Java Web项目整合开发[M].北京:电子工业出版社,2011.

[3]郭克华. Java Web程序设计[M]. 北京:清华大学出版社,2011.

[4]李德兵,尹战文,王洪明. Java EE基于Hibernate的ORM框架[J].电子技术,2010(2),7-8

[5]王国辉,王毅,王殊宇.Java Web开发典型模块大全[M]. 北京:人民邮电出版社,2009. [6](美)Paul DuBios.MySQL权威指南[M].北京:机械工业出版社,2004.

本文来源:https://www.bwwdw.com/article/09bo.html

Top