新闻管理系统设计与实现

基于MVC模式的新闻发布系统的

设计与实现

摘  要:新闻发布系统是公司内容管理系统的主要应用之一,是公司信息化建设和实现电子商务的重要途径。它的基本思想是分离新闻信息的内容和表现形式,以期提高新闻发布效率。本设计采用基于UML用例驱动对象建模的ICONIX项目管理方法,应用MVC三层设计模式,实现一个可以完成新闻栏目和新闻信息的添加、修改、删除以及新闻查看功能的新闻发布系统。

关键字:ICONIX;MVC;Servlet;JavaBean;新闻发布

Design and Implementation of the News Publishing System based on MVC model

Abstract: The news publishing system is the main application of Content Management System in a company, also it is an important approach of the companies’ information construction and the realization of E-Commerce. The separation of the contents and views of information in the news is it is the basic idea, so as to advance the efficiency of the news. Through applying the project management methods of ICONIX, which is based on use case driven object modeling with UML, and MVC design pattern, this paper implement a news publishing system with functions of adding, editing, deleting the category and news, and browsing news message.

KeywordsICONIX; MVC; Servlet; JavaBean; News Publishing


目  录

1  前言

2  系统概述

2.1 项目管理方法

2.1.1 项目管理方法比较

2.1.2 项目管理方法选择

2.2 设计模式

2.2.2 MVC模式基本原理

2.2.3 MVC Model1

2.2.4 MVC Model2

2.3 小结

3  需求分析

3.1 需求描述

3.2 角色识别

3.3 用例识别

3.4 用例文档

3.5 用例驱动分析

3.6 小结

4  系统设计

4.1 系统总体设计

4.1.1 系统构架

4.1.2 发现系统类

4.2 视图层设计

4.2.1 前台设计

4.2.2 后台设计

4.3 模型层设计

4.3.1 前台显示和用户登录

4.3.2 新闻管理

4.3.3 栏目管理

4.4 控制层设计

4.4.1 用户登录

4.4.2 新闻管理

4.4.3 栏目管理

4.5 数据库设计

4.5.1 数据库需求分析

4.5.2 数据库概念设计

4.5.3 数据库逻辑设计

4.5.4 数据库表设计

4.6 数据库连接池设计

4.6.1 传统的数据库连接

4.6.2 数据库连接池的必要性

4.6.3 数据库连接池工作原理

4.6.4 具体设计

4.7 小结

5  系统实现

5.1 视图层实现

5.1.1 公共页面

5.1.2 前台实现

5.1.3 后台实现

5.2 模型层实现

5.2.1 新闻显示

5.2.2 新闻管理

5.2.3 栏目管理

5.3 控制层实现

5.3.1 用户登录

5.3.2 新闻管理

5.3.3 栏目管理

5.4 数据库实现

5.4.1 数据库表实现

5.4.2 数据库表关系

5.5 数据库连接池实现

5.6 小结

6 系统运行测试

6.1 系统测试环境

6.1.1 系统测试硬件环境

6.1.2 系统测试软件环境

6.1.3 Tomcat的配置

6.2 系统测试

7 系统评价与改进

7.1 系统评价

7.2 系统改进

  

  

参考文献

附件

第1章  前言

伴随着网络的出现,网页逐渐融入人们的生活。快速及时的新闻浏览,五彩缤纷的网上信息,使网络与人们的生活息息相关,于是世界上出现了第三媒体——Internet。它打破了地域限制,真正使信息得以共享,改变了人们的工作和生活方式。人们对信息的需求有了更新,更高的要求,而网页由于本身所具有的信息量大,传递快速,没有时空限制等特点恰好满足这种要求。也正是由于网络实现网站的数据信息能够进行实时交互,保证网站数据的实时性。

随着Internet信息技术的高速发展,越来越多的企业想将自己企业的信息通过网络与全世界分享并最终实现电子商务,所以它们已经建立或计划建立自己的网站。但是,如果为了建立和维护自己的网站而聘请专职的网络技术人员,其成本对于一个中小型企业来说实在是太高了。对于上面这类企业来说,他们最需要的就是一个现成的可以自动发布信息的新闻发布系统,这样只要会打字,会上网就能利用新闻发布系统快速简洁地发布企业信息。

然而传统的信息发布方式已经不适应这个快速变化的信息时代,需要一个更高效,更简洁的方式进行信息发布。内容管理系统正是基于这样一个目的而诞生的,它是企业信息化建设和电子政务的新宠。它的基本思想是分离信息内容和表现形式,内容存储在数据库或独立的文件中,而表现形式存储在模版里。当用户请求页面时,各部分联合生成一个标准的HTML页面;当信息修改时,用户只需在一个可视化的界面对信息内容进行修改。大大缩短了信息的更新时间,提高了效率,并且简化了操作。

本设计便是基于内容管理思想的一个新闻发布系统,以下各章从系统概述、需求分析、系统设计、系统实现、系统运行测试和系统评价与改进依次展现系统开发过程。


第2章  系统概述

本章主要介绍在系统开发过程中所采用的软件项目管理方法和系统设计模式。

2.1 项目管理方法

2.1.1 项目管理方法比较

目前,面向对象软件开发的项目管理方法主要有RUP、XP和ICONIX。

RUP(Rational Unified Process)统一软件过程,是统一软件开发过程,强调文档、设计和代码的质量,采用动态适应变化的渐进式迭代周期,依靠需求和测试驱动,并积极鼓励客户参与的开发方法[1]。RUP是一个基于UML和构件式构架的迭代递增型开发过程,更适用于大、中型软件开发项目。

XP极限编程(Extreme Programming,XP)是一门针对业务和软件开发的规则,它将编码和设计活动融为一体,弱化了构架的概念[1]。要求先开发出系统中最重要的特性,迅速向客户提供所需功能,然后随着代码的演进通过重构来满足新的要求,从而使整个项目的风险降到最小。XP是一种渐进式的原型化开发方法,反映的是以编程为中心,节省资源的观念。它具有沟通高效,设计简单,反馈迅速等特点,是一种针对某些特定环境(需求变化快的小型开发团队)的具体过程实施模型和方法论。

ICONIX的规模大概在重量级的Rational Unified Process(RUP)和轻量级的极限编程(XP)之间[2]。和RUP一样,ICONIX过程也是用例驱动的,但不需要RUP使纪录延续到表中带来的大量开销;和XP一样,它相对较小,比较紧凑,但不像XP那样摒弃了分析和设计过程。因此,有助于使用统一建模语言(UML),同时对需求进行跟踪。该过程遵循了Ivar Jacobson的“用例驱动”的思想,能够获得有形、具体、易于理解的用例,可以使用这些用例来驱动开发工作。该过程的3个基本原则是:从用户需求向内进行;从问题域的关键抽象向外进行;从高级模型向下挖掘到详细设计[2]。

2.1.2 项目管理方法选择

本系统选择的项目管理方法是ICONIX,也许它并不是用于本系统开发最好的项目管理方法,当然它也有很多缺点。本系统选择它作为系统的软件项目管理方法,第一是因为系统本身较简单,采用ICONIX足以满足系统需求,并且由于时间限制,本人没有太多精力去学习更好的项目管理方法;第二是因为和别的软件方法不同的是,ICONIX更强调需求到设计之前的自然、有章可循的,同时也适合迭代的过渡,并且按照它自己的软件方法思想,它对UML符号集在可扩充的前提下作了一定的取舍。

本系统选择ICONIX项目管理方法,在系统设计和实现过程中,根据系统需要,对其进行了适当的取舍。图2-1是ICONIX项目管理方法过程的总图。

图 2-1 ICONIX总图[2]

2.2 设计模式

随着Web技术的发展,Web内容从一些静态页面发展到内容丰富的动态页面。目前,用于生成动态网页较为流行的技术有Microsoft的ASP、Tex的PHP和Sun的JSP。ASP只能工作在微软的IIS(Internet Information Server)和PWS(Personal Web Server)上及PHP模式,一些天生缺陷使得它们的使用受到了一定的制约。而JSP是一种完全与平台无关的开发新技术,它集极高的运行效率,较短的开发周期,超强的扩展能力,完全开放的技术标准,自由的开发方式等众多完美特性于一身。JSP+JavaBean+Servlet+JDBC+DBMS是一套能够实现动态网站的开发和维护的技术。DBMS数据库用于数据存储,JDBC用于连接数据库并对数据库进行存储,Servlet用于处理过程控制,JavaBean用于封装业务逻辑,JSP用于页面显示部分。而MVC正是这种设计模式代表。

2.2.2 MVC模式基本原理

MVC (Model-View-Controller),即把一个应用的输入、处理、输出流程按照Model, View, Controller的方式进行分离,这样一个应用被分成三个层——模型层、视图层、控制层,其三层之间的关系和功能如图2-2“MVC组件类型关系和功能图”。

图2-2 MVC组件类型关系和功能图[3]

MVC设计模式的典型流程[4]为:首先Controller接收用户的请求,并决定应该调用哪个Model来进行处理,然后Model用业务逻辑来处理用户的请求并返回数据,最后Controller用相应的View格式化Model返回的数据,并通过表示层呈现给用户。

控制层(Controller)可以理解为从用户接收请求,将模型与视图匹配在一起,共同完成用户的请求。划分控制层的作用也很明显,它清楚地告诉我们,它就是一个分发器,选择什么样的模型,选择什么样的视图,可以完成什么样的用户请求。控制层并不做任何的数据处理。例如,用户点击一个链接,控制层接受请求后,并不处理业务信息,它只把用户的信息传递给模型,告诉模型做什么,选择符合要求的视图返回给用户。因此,一个模型可能对应多个视图,一个视图可能对应多个模型。

模型层(Model)就是业务流程/状态的处理以及业务规则的制定。业务流程的处理过程对其它层来说是黑箱操作,模型接受视图请求的数据,并返回最终的处理结果。业务模型的设计可以说是MVC最主要的核心,必须能够满足大多数客户的需求,包括保证应用程序各组件的事务整合、维护并快速获取应用数据,支持事务工作流的协调以及在已有应用程序中集成新的应用组件等。MVC并没有提供模型的设计方法,而只告诉我们应该组织管理这些模型,以便于模型的重构和提高重用性。

视图层(View)代表用户交互界面,对于Web应用来说,可以概括为HTML界面,但有可能为XHTML,XML和Applet。随着应用的复杂性和规模性,界面的处理也变得具有挑战性。一个应用可能有很多不同的视图,MVC设计模式对于视图的处理仅限于视图上数据的采集和处理,以及用户的请求,而不包括在视图上的业务流程的处理。业务流程的处理交予模型(Model)处理。

2.2.3 MVC Model1

在MVC模式的Model1体系中,JSP页面独立响应请求并将出理结果返回客户,所有的数据存取都是由JavaBean来完成。Model1体系十分适合简单应用需要,却不能满足复杂的大型应用程序的实现。MVC Model1的体系结构如图2-3所示。

图2-3 MVC Model1体系结构图[5]

2.2.4 MVC Model2

MVC模式的Model2体系结构是一种把JSP与Servlet联合起来实现动态内容服务的方法。它吸取了两种技术的优点,用JSP生成表达层的内容,让Servlet完成深层次的处理任务。这是一种有代表性的方法,它清晰地分离了表达和内容,明确了角色的定义及开发者与网页设计者的分工。本系统的设计模式选择的便是Model2。MVC Model2的体系结构如图2-4所示。

图2-4 MVC Model2体系结构图[5]

2.3 小结

本章首先介绍了目前面向对象的软件开发中所常用的几种项目管理方法,并最终根据系统需要选择了ICONIX作为系统项目管理方法。然后对MVC设计模式基本原理进行了详细阐述,并介绍了MVC的两种不同的模式Model1和Model2,并确定本系统的设计模式便是MVC Model2。


第3章  需求分析

需求分析在软件开发过程中,具有举足轻重的地位,它具有决策性,方向性,策略性的作用。需求分析的任务就是要解决“做什么”的问题,就是要全面地理解用户的各项需求,并准确地表达所接受的用户需求。

3.1 需求描述

新闻发布系统功能需求主要包括:前台显示功能和后台管理功能。

前台显示功能主要针对一般用户的,当一般用户在浏览新闻系统时,系统应该对新闻栏目和新闻条目的显示。另外,前台显示功能还应包括一个提供给系统管理员登录后台的登录入口。具体需求见表3-1系统前台显示需求表。

表3-1 系统前台显示需求表

用户

要求实现功能

一般用户

浏览新闻栏目

一般用户

浏览新闻

系统管理员

登录后台系统

后台管理功能是针对系统管理员的,当系统管理员登录系统后台时,系统后台提供给系统管理员的功能应该有:对新闻栏目的浏览、添加、修改和删除;对新闻条目的浏览、添加、修改和删除。具体需求见表3-2系统后台管理需求表。

表3-2 系统后台管理需求表

用户

要求实现功能

系统管理员

浏览新闻栏目

系统管理员

添加新闻栏目

系统管理员

修改新闻栏目

系统管理员

删除新闻栏目

系统管理员

浏览新闻

系统管理员

修改新闻

系统管理员

添加新闻

系统管理员

删除新闻

3.2 角色识别

角色识别的任务是找到所有可能与系统发生交互行为的外部实体、对象和系统。他们的行为不受系统控制,但是可以提供输入信息。

从系统描述可知,在前台显示模块中,系统主要对一般用户的浏览需求和管理员的登录需求做出响应;而在后台管理系统中,系统管理员可以对新闻栏目及新闻进行浏览、添加、修改和删除。所以本系统应包括两个角色:一般用户和系统管理员用户。而事实上这些人对于系统来说都是用户,只是当用户登录到后台便成了管理员而已。因此,系统角色可以统一为:用户。

3.3 用例识别

在UML文档中,用例(即Use Case)的定义是:在不展现一个系统或子系统内部结构的情况下,对系统或子系统的某个连贯的功能单元的定义和描述[6]。

用例识别的目标是在需求描述和系统角色识别的基础上,识别出角色相映的用例,从而可以得出系统的用例模型,如图3-1是“系统用例模型图”。

图3-1 系统用例模型图

3.4 用例文档

用例文档主要为了描述出用例的详细业务流程,本系统主要包括以下用例文档:

(1) 前台显示用例文档:

基本流程:当用户在前台浏览新闻系统时,系统默认显示给用户的是所有栏目和所有新闻条目(每页显示8条新闻,一页显示不完可以分页显示)。当用户点击某个栏目时,系统显示相应的新闻条目。

分支流程:如果某个栏目下没有任何新闻,系统将显示一条信息,以指出该栏目没有新闻可以显示。

(2)登录入口用例文档:

基本流程:用户在前台显示页面提供的登录后台系统的登录入口中输入用户信息,系统根据用户的登录信息进行检验,然后进入系统后台管理系统。

分支流程:如果用户取消登录,则系统将信息重置,用户回到前台显示页面。

如果用户输入的信息不正确,系统将控制权交给“登录错误”页面,用户可以在此重新输入用户名和密码进行登录。

(3)系统后台管理用例文档:

基本流程:用户在登录系统后台后,可以对新闻和栏目进行操作,根据用户的操作选择,进入扩展用例。

(4)新闻管理用例文档:

基本流程:用户进入系统后便可浏览到新闻条目,在浏览过程中,用户可以修改和删除新闻。用户在进行相应的操作后,系统存储新的信息,系统将控制权交给后台管理用例。

分支流程:如果用户放弃对新闻的相应操作,则系统直接将控制权交给后台管理用例。

如果用户选择添加新闻,系统将控制权交给添加新闻用例。

(5)添加新闻用例文档:

基本流程:用户填写新闻相关信息,并确定添加新闻时,系统将存储此新闻,并将控制权交给新闻管理用例。

分支流程:如果用户放弃新闻添加,系统将直接将控制权交回给新闻管理用例。

(6)栏目管理用例文档:

基本流程:用户在后台管理中选择栏目管理时,用户将浏览到系统已有栏目,并可对其进行修改删除操作,用户在进行相应操作后,系统会存储新的信息,控制权将回到栏目管理用例。

分支流程:如果用户放弃相应操作,控制权将直接回到栏目管理用例。

如果用户选择添加栏目,控制权将交给添加栏目用例。

(7)添加栏目用例文档:

基本流程:用户填写栏目相关信息,并确定添加栏目,系统将存储此栏目,并将控制权交给栏目管理用例。

分支流程:如果用户放弃栏目添加,控制权将直接交回到栏目管理用例。

3.5 用例驱动分析

通过以上对系统需求的分析已经定义了系统的角色和系统用例。系统根据用例模型可以对用例进行细化,从而展现整个用例的活动顺序。序列图则反映了用例各个类之间的具体调用过程[7],如图便是根据系统的角色分析和系统用例模型而得出的相应活动的顺序图如图3-2至图3-7。

图3-2 前台活动顺序图

图3-3用户登录活动顺序图

图3-4 后台新闻管理活动顺序图

图3-5 添加新闻活动顺序图

图3-6 栏目管理活动顺序图

图3-7 添加栏目活动顺序图

3.6 小结

本章从用户的角度,分析了系统的需求用例,画出了系统用例模型图,并得出了相应的用例文档;做出了用例驱动分析,并得出了相应的顺序图。本章的工作为系统的设计打下基础。


第4章  系统设计

根据上一章的需求用例分析,本章从先总体构架的角度对系统进行总体设计,然后根据MVC三层模式对系统进行详细设计,最后对系统数据库和数据库连接池进行了设计。

4.1 系统总体设计

4.1.1 系统构架

系统基于MVC Model2设计模式,设计出本系统自己的设计模式,在MVC Model2基础上加入数据库连接池模块层对数据库操作进行封装。具体模式图如图4-1。

图4-1 系统设计模式图

对于MVC设计模式,在本系统中具体实现方式是:Model由JavaBean完成,View由JSP完成,Controller由Servlet完成,再加上数据库连接池专门负责数据库连接和管理。本系统具体构架如图4-2。

图4-2 系统构架图

4.1.2 发现系统类

发现系统类是域建模的工作,其主要目的是根据系统需求用例及描述,找到代表与本新闻系统将要解决的问题有关的事务和概念的“对象”,即类[1]。

在本系统中,根据第3章中对系统需求用例的分析,可以总结出如下的需求集:

(1)系统应该分为前台和后台;

(2)系统前台应该可以显示新闻栏目和新闻以及用于管理员登录系统后台的登录界面;

(3)一般用户应该可以在前台自由浏览新闻,包括选择性地浏览新闻即先选择新闻栏目再浏览新闻栏目下的新闻条目;用户在浏览新闻时,系统应该可以将显示给用户一个包含新闻具体内容的HTML文件;

(4)系统管理员应该可以登录到系统后台;

(5)系统管理员应该可以对新闻栏目和新闻进行查看、修改、删除和添加操作。系统在添加新闻时,应该可以将添加的新闻保存为一个HTML文件。

由以上需求集进一步分析可知:

(1)词“系统”太模糊,不能成为一个对象的名称;同样,“前台”和“后台”为系统的两个不同的区域,亦不能成为对象名称;

(2)“新闻栏目”和“新闻”为系统的两个主要内容,所以应该分别作为一个类,而新闻栏目和新闻的显示需要管理类进行管理,系统管理员要对栏目和新闻进行查看、添加、修改和删除,也需要相应的管理类进行管理,所以,系统对于新闻栏目和新闻分别需要“栏目管理类”和 “新闻管理类”;

(3)要将添加的新闻保存为一个HTML文件,需要一个从表单中收集信息并将其转换为一个HTML文件的类;

(4)系统要保存信息,必须用到数据库,所以需要一个数据库连接的类;

(5)要将系统的各个功能执行成功,少不了相应的控制类。

因此,识别出系统主要的类:新闻类(News)和新闻管理类(NewsMgr),栏目类(Category)和栏目管理类(CategoryMgr),数据库连接池的连接对象类(ConnectionObject)和连接池管理类(ConnectionPool)以及各个Servlet类。

4.2 视图层设计

4.2.1 前台设计

当一个用户浏览新闻系统时,首先进入系统前台界面。如果把一个系统比作一个人,那么前台界面则是这个人的脸,因此系统的前台界面的设计是比较重要的,并且,前台界面应该被设计得比较简洁,方便。前台界面设计如图4-3所示。

图4-3 前台界面设计图

首先,在本系统的前台界面的顶部用户可以看到一个专为系统管理员用户提供的登录入口,为系统管理员提供了方便。而对于一般用户来说,他们也不会感觉这有何不妥,因为此登录界面比较简洁,并不会影响用户正常地阅读新闻。

其次,在登录界面的下方是新闻栏目的显示,显示系统新闻栏目数据库中已有的新闻栏目,一目了然,用户可以方便地找到自己喜欢和关心的新闻所在的栏目。

再次,在新闻栏目的下方则是新闻条目的显示,默认的新闻条目的显示方式是以表格的形式将系统新闻数据表中的新闻按发布时间进行列表(发布较早的新闻被放在列表的后面,而发布较迟的新闻被放在列表的前面,体现了新闻的“新”,即“时效性”)。新闻列表中仅显示新闻的标题,发布时间和新闻作者,如果想浏览整篇新闻,用户可以点击新闻标题(超链接),这时系统会将用户引导向一个包含新闻具体内容的HTML文件。

然后,用户可以对自己比较关心和感兴趣的新闻进行有选择性地浏览,这时新闻栏目便起作用了。当用户点击新闻所在的栏目时,系统在新闻列表中只显示本栏目的新闻条目。用户可以在此浏览自己关心和感兴趣的新闻。

4.2.2 后台设计

4.2.2.1 后台主页面设计

当用户登录到系统后台时,他便成为系统管理员,可以执行对新闻和栏目的查看、修改、删除和添加。此界面主要是面向管理员的,界面要设计得简洁方便,使得系统管理员在管理系统时容易操作。后台界面设计如图4-4所示。

图4-4 后台管理系统主界面设计图

当管理员用户登录到系统后台时,呈现到他眼前的是系统后台管理的主页面:

首先,系统后台主页面左上角是欢迎词(Welcome+管理员名),对于管理员,他可以感觉到系统的人性化;对于系统本身,系统可以识别此时登录的是哪个管理员,可以分配管理员的权限。

其次,欢迎词下方是系统管理的功能选择,一目了然,管理员可以在此选择要操作的模块进入,然后执行相应的操作。

再次,再往下就是系统新闻列表,与前台新闻显示类似,只是多了对新闻的操作(修改和删除)。管理员可以在此对系统已有的新闻进行修改和删除操作。

4.2.2.2 添加新闻设计

如果系统管理员在系统后台主页面中选择“添加新闻”,管理员会进入下图这样一个页面进行新闻的添加,添加完新闻标题和新闻正文内容后,还必须选择所添加新闻所属的新闻栏目。确认所有内容均已填好,点击“发表”按钮,新闻发布工作完成,如果点击“清除”按钮,则系统清除管理员刚才的所有输入,让管理员重新填写新闻的各项内容。管理员可以在系统后台主页面中看到刚刚发表的新闻,可以对其进行相关操作,如图4-5。

图4-5 发布新闻页面设计图

4.2.2.3 栏目管理设计

如果系统管理员在系统后台主页面中选择“栏目管理”,系统将链接到新闻栏目管理页面。栏目管理页面上有一些链接按钮,可以让管理员链接到其他页面。链接按钮下面是系统已有新闻栏目的列表,在此,管理员可以对新闻发布系统的栏目进行操作(编辑和删除栏目)。

如果管理员想要添加新闻栏目,只需点击“添加栏目”,就可以被链接到添加新闻栏目页面(因为此页面比较简单,所以并未给出具体设计图),添加栏目完成后,管理员可以在栏目管理主页面的栏目列表中找到新添加的栏目,并对其进行相关操作,如图4-6。

图4-6 栏目管理页面设计图

4.3 模型层设计

本系统模型层由JavaBean完成,模型层设计主要设计出完成各个功能模块中模型层的JavaBean类。模型层的类主要有新闻类News和新闻管理类NewsMgr以及栏目类Category和栏目管理类CategoryMgr。

4.3.1 前台显示和用户登录

在前台显示和用户登录模块中,充当模型层的是News和NewsMgr根据系统分析中的系统前台需求用例分析和上述的前台界面功能描述,对系统的前台的每一个流程、每一个模块进行详细功能设计。其相应的功能模型如下图4-7。

图4-7 系统前台显示和用户登录静态模型图

根据上面的系统前台模型,我们可以来说明各个类的责任和功能。

表4-1 前台类责任表

名称

类型

属性

责任(或操作)

Index page

边界

显示系统前台主页面,并提供管理员登录

News

实体

新闻条目的属性

新闻条目的抽象

NewsMgr

控制

根据新闻ID得到新闻对象,获得所有新闻和根据栏目ID得到该栏目的所有新闻

Login Form

边界

提供管理员登录,并负责客户端的登录完整性检验

main page

边界

系统后台管理主页面

4.3.2 新闻管理

管理员在系统后台主界面中可以对已有新闻进行管理(修改、删除和添加),新闻管理模块中充当模型层的仍然是News和NewsMgr。其静态模型如图4-8。

图4-8 新闻管理静态模型图

根据上面的新闻管理模型,我们可以对各个类的责任和功能进行说明。

表4-2 新闻管理类责任表

名称

类型

属性

责任(或操作)

Main page

边界

显示系统后台主页面,系统管理员可以在此对系统进行操作

表4-2 新闻管理类责任表(续)

NewsMgr

控制

对新闻条目进行操作,修改和删除

News

实体

新闻属性

对新闻实体的抽象

Addnews page

边界

添加新闻界面,以Form形式收集信息然后提交给控制器

AddNewsServlet

控制

在控制层设计

EditNewsServlet

控制

在控制层设计

DeleteNewsServlet

控制

在控制层设计

4.3.3 栏目管理

栏目管理中可以对已有栏目的编辑、删除以及添加新栏目,栏目管理静态模型如图4-9。

图4-9 栏目管理静态模型图

根据上面的栏目管理静态模型设计,我们可以对各个类的责任和功能进行说明。

表4-3 栏目管理类责任表

名称

类型

属性

责任(或操作)

ClassManage page

边界

显示系统既有栏目,管理员可以在此对栏目进行修改和删除操作

Addclass page

边界

添加栏目,提交给添加栏目控制器

Category

实体

ID和Name

新闻栏目的抽象

CategoryMgr

控制

实现对新闻栏目的操作

表4-3 栏目管理类责任表(续)

EditCategoryServlet

控制

在控制层中设计

DeleteCategoryServet

控制

在控制层中设计

AddCategoryServlet

控制

在控制层中设计

4.4 控制层设计

4.4.1 用户登录

当用户通过系统前台提供的登录入口登录后台系统时,系统将用户的登录信息提交给登录控制层处理。所以登录控制器必须对用户登录信息进行识别,判断其是否有权限登录到后台系统。用户登录控制器由LoginServlet完成,实现登录控制的静态类图如图4-10。

图4-10 登录控制静态模型图

根据图4-10登录控制静态模型设计,对各个类的责任和功能进行说明。

表4-4 用户等录控制类责任表

名称

类型

属性

责任(或操作)

LoginServlet

控制

控制用户登录

4.4.2 新闻管理

新闻管理中主要涉及到新闻信息的添加、删除和修改,所以其控制层由AddNewsServlet、DeleteServlet和EditServlet完成。新闻管理静态类图如图4-11。

图4-11 新闻管理静态模型图

根据图4-11新闻管理静态模型设计,对各个类的责任和功能进行说明。

表4-5 新闻管理控制层静态类责任表

名称

类型

属性

责任(或操作)

EditNewsServlet

控制

对已有新闻编辑的控制

DeleteNewsServlet

控制

对删除已有新闻的控制

AddNewsServlet

控制

对添加新闻的控制

4.4.3 栏目管理

栏目管理模块主要对新闻栏目进行修改、删除和添加,此功能模块控制层由EditCategoryServlet、DeleteCategoryServlet和AddCategoryServlet完成。栏目管理静态类图设计如图4-12。

图4-12 栏目管理静态模型图

根据图4-12栏目管理静态模型设计,对各个类的责任和功能进行说明。

表4-6 栏目管理控制层静态类责任表

名称

类型

属性

责任(或操作)

EditCategoryServlet

控制

对新闻栏目编辑的控制

DeleteCategoryServlet

控制

对删除新闻栏目的控制

AddCategoryServlet

控制

对添加新闻栏目的控制

4.5 数据库设计

4.5.1 数据库需求分析

由于本系统面向的对象有两个:一般用户和系统管理员。所以,数据库需求分析中就要考虑两方面因素。

对于一般用户来说,他们所关心的是新闻的浏览。通过系统功能分析,针对一般新闻用户的需求,总结出如下需求信息:

(1)每个新闻对应一个HTML文件;

(2)每个新闻只能对应一个新闻栏目;

(3)每个栏目下可以有多个新闻。

(4)每个新闻除了包含新闻的基本信息之外,还得包含新闻所对应的HTML路径信息。

对于系统管理员来说,他们所关心的是如何对新闻栏目和新闻的添加、修改和删除。通过分析,针对系统管理员,总结出如下需求信息:

(1)管理员可以对新闻栏目进行增、删、改;

(2)管理员可以对新闻条目进行增、删、改。

4.5.2 数据库概念设计

根据上面的数据库需求分析,就可以构造出各种实体,以及并根据它们的关系绘制出实体间的E-R图[8],为以后的逻辑设计打下基础。如图4-13为本新闻发布系统实体间的E-R图。

图4-13 实体之间关系的E-R图[8]

4.5.3 数据库逻辑设计

根据数据库需求分析和数据库概念设计,设计如下所示的数据项和数据结构:

管理员表(用户名,密码),用户名为主码;

栏目表(栏目编号,栏目名称),栏目编号为主码;

新闻表(新闻编号,新闻标题,新闻内容,管理员名,所属栏目,发布时间),新闻编号为主码,管理员名和所属栏目为外码;

4.5.4 数据库表设计

数据库逻辑设计完毕后,现在可以将上面的数据库概念结构转化为某种数据库系统所支持的实际数据库模型。本系统使用SQL Server2000数据库。

新闻发布系统的数据库中各表的设计结果如下面几个表所示。

表4-7 管理员Master表

序号

字段名

字段含义

类型

宽度

是否非空

备注

1

UserName

管理员用户名

char

12

Y

Key

2

Password

管理员密码

char

12

Y

表4-8 新闻News表

序号

字段名

字段含义

类型

宽度

是否非空

备注

1

newsId

新闻编号

int

4

Y

Key

2

Title

新闻标题

char

50

N

3

Content

新闻内容

char

5000

N

4

UserName

新闻作者

char

12

Y

外码

5

Compose_date

新闻发布时间

datetime

8

Y

6

categoryId

新闻栏目编号

int

4

Y

外码

表4-9 栏目Category表

序号

字段名

字段含义

类型

宽度

是否非空

备注

1

categoryId

新闻栏目编号

int

4

Y

Key

2

categoryName

新闻栏目名称

char

20

Y

4.6 数据库连接池设计

4.6.1 传统的数据库连接

传统的数据库连接模式基本上是按以下步骤进行:①在主程序(如Servlet、Beans)中建立数据库连接;②进行SQL操作,取出数据;③断开数据库连接[9]。

4.6.2 数据库连接池的必要性

传统的数据库连接模式开发,存在很多问题。首先,要为每次web请求(例如客户浏览一件商品信息)建立一次数据库连接。当有多个用户连接系统的时候,在同一时间有可能会不止一个用户需要数据库连接,在这种情况下,系统开销也是相当大的。连接数据库不仅要开销一定的通讯和内存资源,还必须完成用户验证、安全上下文配置这类任务;同时应用程序还要管理每一个连接,确保这些连接在被使用完后能被正确关闭。这些操作往往成为最耗时的操作,很多时候,一个网站的速度瓶颈可能就在于此,因而对数据库的连接的管理显得特别重要。

本系统是一个新闻发布和管理的系统,新闻系统是面向广大阅读新闻的用户的,用户需要阅读新闻时,系统需要从新闻数据库中调出用户需要的新闻条目。如果采用传统的数据库链接模式,那么对于每一个阅读新闻的用户,当他读取新闻时,系统都要为他建立一次数据库连接,而当他退出新闻阅读时,系统释放数据库链接,那么,系统的数据库连接是非常频繁的。这样也会产生上面提到的种种问题,但是,如果采用数据库链接池就方便得多,本系统采用的便是数据库链接池模式对数据库进行连接。

4.6.3 数据库连接池工作原理

数据库连接池实际上是在一个容器对象中建立一定数目的数据库连接对象。当需要使用数据库连接的时候,直接从连接池中取出空闲对象供用户使用。当用户使用完后再把连接对象放回连接池中,以节省重新建立连接对象所花费的时间。工作原理如图4-14所示。

图4-14 连接池工作原理图[10]

当连接池工作时,首先,在连接池中应当初始化内含一定数量的连接对象;在使用过程中,如果池中的连接对象不够,可根据需要逐渐加入新的连接对象,但池中的连接对象也不能是无限的,当达到最大连接对象数量时,便不能再往池中添加新的连接对象,如果此时连接对象数量仍然不够,就只能等待别的连接对象释放后再使用,即定义连接池中连接对象的上下界和连接超时时间。定义上下界可根据客户端的情况动态地使用资源,以提高系统的效率。另外,同一个连接对象如果被使用的次数太多,可能会导致该连接对象的不稳定。所以需要设定一个连接对象可使用的最大次数。当使用次数达到最大次数后就将该连接对象关闭并从池中删除。

4.6.4 具体设计

根据连接池的工作原理,本文设计了一个的连接池组件。该连接池组件由两个Java类——ConnectionObject和ConnectionPool和一个数据库连接配置文件(dbconfig.txt)构成。其中:ConnectionObject称为连接对象类,用来实现对一个连接对象状态的管理,并为连接池管理类提供服务;ConnectionPool称为连接池管理类,用来实现对连接池的管理和调度;dbconfig.txt称为数据库连接配置文件,存放数据库连接所需要的配置信息,供连接池工作时使用。连接池内部联系类图如图4-15所示。

图4-15 连接池内部主件联系图

4.7 小结

本章首先进行了系统总体设计,接着按照MVC设计模式的三层结构根据系统需求用例对新闻发布系统功能进行设计,最后设计出系统的数据库并对数据库连接进行了相应的设计。通过本章,系统设计出了用来完成系统用例的业务功能模型以及完成各个用例的类。


第5章  系统实现

根据上一章的设计思路设计用来完成系统用例的业务功能,整个系统按照MVC模式的三个部分以及数据库连接池进行编码实现,分为视图层、控制层、模型层和数据库连接池。由于系统实现的代码量较大限于篇幅,文中仅显示部分代码,具体实现代码参见附件。

5.1 视图层实现

在系统其它视图层部分实现之前,先对那些常用的公共页面模块部分实现。

5.1.1 公共页面

include.jsp是一个包含页面,它包含了一些其它页面可能经常用到的JavaBean包以及一些在其它页面中常用到的参数。具体代码如下:

<%@ page contentType="text/html;charset=UTF-8"%>

<!--开始导入packages-->

<%@ page import="java.io.*,java.util.*,java.sql.*"%>

<%@ page import="mybean.*"%>

<!--导入结束-->

<%

String title = "筱筱新闻管理系统";

String placebgcolor = "#EEEEEE";

String tablebgcolor = "#336699";

String trbgcolor = "#336699";

String tdbgcolor = "#FFFFFF";

String tablebgcolor2 = "#6699CC";

String trbgcolor2 = "#EEEEEE";

String trbgcolor3 = "#FFFFFF";

String tdbgcolor2 = "#6699CC";

String tdbgcolor3 = "#DDDDDD";

String tdbgcolor4 = "#EEEEEE";

String tablewidth = "100%";

String tablewidth2 = "100%";

%>

session.jsp的设置主要是方便系统对管理员权限的判定。因为,如果一个用户登录到系统,系统便会给他设定一个session,这个session在他退出系统之前均有效。系统可以通过session来判定用户是否登录,并且,如果某个用户要执行系统某些功能时,系统也可以通过一个session对其进行操作权限的判定。具体代码如下:

<%

String userName = (String) session.getAttribute("username");

if (userName==null){

response.sendRedirect("error.jsp");

}

%>

foot.jsp中包含了其它页面常用到的页面尾部的设计。具体代码如下:

<%@ page contentType="text/html;charset=UTF-8"%>

<TABLE bgColor=#eeeeee border=0 width=100% align=center>

<TBODY>

<TR>

<TD align=center><BR>新闻管理系统 Copyright(c)Elven 2007       <A HREF="../index.jsp">新闻首页</A></TD>

</TR>

</TBODY>

</TABLE>

</BODY>

</HTML>

本系统的CSS设计了一个CSS样式表(css.css)它主要设置页面中显示的Body结构的样式、超链接A的样式、页面中表格Table样式等的设置。CSS样式表可以使系统整体风格一致。

5.1.2 前台实现

系统前台视图层由index.jsp实现。index.jsp仅负责显示新闻栏目和系统已有新闻以及为管理员用户提供一个登录入口。index.jsp页面显示截图如图5-1。

图5-1 index.jsp页面实现截图

5.1.3 后台实现

系统后台视图层主要由mian.jsp、addnews.jsp、classmanage.jsp和addclass.jsp组成。

mian.jsp是系统后台主页面,是管理员登录到系统所看到的第一个页面。其实现显示截图如图5-2。

图5-2 main.jsp实现截图

addnews.jsp实现新闻的添加。当用户在后台主页面中选择添加新闻按钮时,管理员便进入此页面。其实现截图如图5-3。

图5-3 addnews.jsp实现截图

classmanage.jsp实现新闻栏目的管理,管理员可以在此对进行新闻栏目的相关操作。其实现截图如图5-4。

图5-4 classmanage.jsp实现截图

addclass.jsp是classmanage.jsp的一个子页面,它实现栏目的添加功能。其实现截图如图5-5。

图5-5 addclass.jsp实现截图

5.2 模型层实现

模型层实现中主要给出了实现功能模块中的各类的功能函数,具体代码见附件。

5.2.1 新闻显示

在前台页面中显示系统已有新闻,需要新闻类News和新闻管理类NewsMgr。在此模块中主要实现将新闻数据库中的新闻显示到前台页面中。实现新闻显示的功能函数如下:

public Collection getAllNews()//查询所有的新闻;

public Collection getAllByCategory(int categoryId)// 根据CategoryId得到某栏目所有的新闻;

public News getById(int id)// 根据ID得到新闻;

public int getTotal()//计算新闻的总数;

public int getTotalByCategoryId(int categoryId)// 计算某类别新闻的总数。

5.2.2 新闻管理

新闻管理模块是在系统后台对已有新闻进行编辑和删除以及添加新闻。在新闻管理类中如此实现新闻管理:

public News getById(int id)// 根据ID得到新闻;

public void modify(News news)// 修改新闻;

public void delete(int id)// 删除新闻;

public void add(News news)// 添加新闻。

5.2.3 栏目管理

栏目管理模块中,主要实现新闻栏目的添加、编辑和删除。栏目类Category和栏目管理类CategoryMgr如下实现栏目管理功能:

public Category getById(int id)// 根据ID得到栏目;

public void add(Category category)// 添加新的栏目;

public void modify(Category category)// 修改栏目名称;

public void delete(int id)// 删除栏目。

5.3 控制层实现

本系统的控制层由Servlet实现。这些作为控制层的Servlet接收用户的请求,并调用作为Model的JavaBean来进行处理,然后Model用业务逻辑来处理用户请求并返回数据,最后Servlet用相应的View来格式化Model返回的数据,通过表示层呈现给用户。

在实现Servlet之前,首先要在Tomcat中配置好Servlet运行的环境,并配置本应用程序的web.xml配置文件,其Servlet在web.xml配置的基本格式如下:

<!-- Define servlets -->

 <servlet>

    <servlet-name>XXServlet</servlet-name>

    <servlet-class>ClassPath.XXServlet</servlet-class>

 </servlet>

<!-- Define servlets mapping -->

 <servlet-mapping>

    <servlet-name>XXServlet</servlet-name>

    <url-pattern>/XXServlet</url-pattern>

 </servlet-mapping>

在使用Servlet之前都必须在web.xml中定义好Servlet才可以正常使用。下面具体实现每个Servlet。

5.3.1 用户登录

在此用户登录功能中,最重要的就是LoginServlet的实现。它不仅调用数据库数据,还控制页面流向。

当用户在前台中提供的登录入口输入用户名和密码时,index.jsp通过Form将信息提交给LoginServlet,LoginServlet获得此信息,调用数据库连接池组件查找数据库对照看是否有与LoginServlet收集到的信息匹配记录,如果有则成功登录到系统后台(main.jsp),如果没有与之匹配的记录则将页面定位到登录错误页面(loginerror.jsp)重新登录。同样也会用到LoginServlet对登录信息进行判断。(LoginServlet代码见附件)

5.3.2 新闻管理

新闻管理功能模块中主要实现新闻的添加、修改和删除,在控制层中它们分别是由AddNewsServlet、EditNewsServlet和DeleteNewsSevlet实现。

添加新闻控制层是由AddNewsServlet实现。管理员在添加新闻页面addnews.jsp填写完需要填写的内容点击“发表”按钮时,将内容通过Post方法提交给AddNewsServlet。AddNewsServlet调用JavaBean——News和NewsMgr对新闻信息进行处理,然后将新闻信息保存到新闻数据表。

修改新闻控制层是由EditNewsServlet实现。管理员在浏览新闻时可以对其进行修改(editnews.jsp)。当管理员提交修改后的新闻信息时,editnews.jsp通过Post方法提交给EditNewServlet处理,EditNewsServlet处理后,用修改后的新闻信息去更新新闻数据表。

删除新闻控制层是由DeleteNewsServlet实现。当管理员删除新闻时,用Get方法将新闻ID传递给DeleteNewsServlet,经过处理后更新新闻数据表信息。

5.3.3 栏目管理

栏目管理功能模块中主要实现了新闻栏目的添加、修改和删除,在控制层中它们分别是由AddCategoryServlet、EditCategoryServlet和DeleteCategoryServlet实现。

栏目的添加由AddCategoryServlet实现,当管理员在addcateogry.jsp中添加新闻栏目后,将信息通过Post方法提交给AddCategoryServlet处理,更新栏目表中的信息。

栏目的修改由EditCategoryServlet实现,当管理员在editcategory.jsp中修改某个栏目后,将修改信息通过Post方法提交给EditCategoryServlet,EditCategoryServlet用修改后的信息去更新栏目数据表。

栏目的删除由DeleteCategoryServlet实现,当管理员删除某个栏目时,通过Get方法将栏目的ID传递给DeleteCategoryServlet,经过处理后更新栏目数据表信息。

5.4 数据库实现

5.4.1 数据库表实现

管理员表Master:

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Master]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)

drop table [dbo].[Master]

GO

CREATE TABLE [dbo].[Master] (

[UserName] [char] (12) COLLATE Chinese_PRC_CI_AS NOT NULL ,

[Password] [char] (12) COLLATE Chinese_PRC_CI_AS NOT NULL

) ON [PRIMARY]

GO

栏目表Category:

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)

drop table [dbo].[Category]

GO

CREATE TABLE [dbo].[Category] (

[categoryId] [int] NOT NULL ,

[categoryName] [char] (20) COLLATE Chinese_PRC_CI_AS NOT NULL

) ON [PRIMARY]

GO

新闻表News:

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[News]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)

drop table [dbo].[News]

GO

CREATE TABLE [dbo].[News] (

[newsId] [int] NOT NULL ,

[Title] [char] (50) COLLATE Chinese_PRC_CI_AS NULL ,

[Content] [char] (5000) COLLATE Chinese_PRC_CI_AS NULL ,

[Author] [char] (12) COLLATE Chinese_PRC_CI_AS NULL ,

[Compose_date] [datetime] NULL ,

[categoryId] [int] NULL

) ON [PRIMARY]

GO

5.4.2 数据库表关系

categoryId为栏目表Category的主码,为新闻表News的外码,Category和News通过categoryId建立关联。而管理员表Master与News通过UserName字段建立关联。

图5-6  数据库表关系图

5.5 数据库连接池实现

根据第4章中对数据库连接池的设计,数据库连接池组件主要通过Connectionpool和ConnectionObject实现数据库的连接和对连接的管理。

1.ConnectionObject功能函数包括:

public ConnectionObject(String url,String username,String password) ;

public Connection getConnection();

public void setConnection(Connection connection);

public boolean isIsUse();

public void setIsUse(boolean isUse);

public void setUseCount(int useCount);

public int getUseCount();

public void addUseCount()。

2.ConnectionPool功能函数包括:

private void loadProp();

private void initPool();

public ConnectionPool();

public void finalize();

private int findconnectionID(Connection conn);

private void realse(Connection conn);

private ConnectionObject getFreeConnection();

public Connection getConnection();

public void realse(Connection conn)。

5.6 小结

本章从MVC三层模式入手,通过代码的编写,基本实现了系统设计中所设计的业务功能,从而完成了系统用例所要求的功能。


第6章 系统运行测试

6.1 系统测试环境

系统测试需要相应的环境,所以在系统测试之前,进行系统硬件和软件环境的配置。

6.1.1 系统测试硬件环境

因为本系统仅在本机上运行,所以需要一台PC机即可。为了系统可以正常运行,PC机配置最低配置:CPU 1.5GHz,内存256M,硬盘40G。

6.1.2 系统测试软件环境

PC机操作系统为Windows XP或Windows Server 2003均可。

PC机上必须安装并配置java运行环境——JDK,本人用的JDK是j2sdk1.4.2_12。

PC机上必须安装并可以运行JSP应用程序web服务器。本人用的web服务器是Tomcat5.0。

6.1.3 Tomcat的配置

在运行JSP应用程序之前,还必须对Tomcat进行配置。

首先,为了方便管理系统应用程序,在Tomcat中为系统应用建立虚拟目录。具体做法:本机存放系统应用程序的文件夹为F:\mypub,所以在\Tomcat 5.0\conf目录下的server.xml如此配置:<Context path="/mypub" docBase="F:\mypub" debug="0"  reloadable="true" />

其次,对应用程序目录中的web.xml进行配置以便可以正常运行Servlet。

6.2 系统测试

因为系统比较简单,所以本人采用黑盒测试法对系统各个功能模块需求进行测试[11]。在IE浏览器中输入http://127.0.0.1:8080/mypub。具体测试见表6.1。

表6-1 测试用例表

测试用例ID

输入

预期结果

实际结果

测试结论

OA-1

进入系统前台主页浏览新闻

若成功,则显示新闻列表

显示新闻列表,并可以阅读新闻

部分成功

表6-1 测试用例表(续)

OA-2

选择新闻栏目

应该列出该新闻栏目的所有新闻,若没有则提示

选择有新闻的栏目,可以看到新闻列表,没有新闻的栏目,显示“该栏目没有任何新闻”

成功

OA-3

在登录入口输入用户名和密码

若输入正确的用户名和密码,则登录到系统后台,否则进入登录错误页面

输入“admin,admin”进入系统后台,输入其它,进入登录错误页面,提示重新登录

成功

OA-4

进入后台浏览新闻

若成功,在浏览期间可以修改和删除新闻,返回更新后的新闻信息

实现预期结果

成功

OA-5

点击“添加新闻”

可以进行新闻信息的录入,完成后在新闻列表可以看到新添加的新闻

实现预期结果

成功

OA-6

点击“栏目管理”

可以添加、修改和删除栏目

实现预期结果

成功


第7章 系统评价与改进

7.1 系统评价

系统的开发采用了目前国际流行的MVC(模式-视图-控制器模式)中的model2进行系统设计,整个系统的实现体现了MVC开发模式将输入、处理、输出分离开来的思想,使整个系统代码功能一目了然,易于维护和扩展。系统的开发过程中运用了ICONIX项目管理方法,通过用例驱动对象建模的方式对系统建模。系统的开发很好地结合了这两种技术的优点对系统进行了开发。

从客户的角度看,系统分为前台和后台。系统前台面向所有用户,实现新闻显示,栏目关联显示和登录后台的功能;系统后台面向管理员用户,实现新闻和栏目的管理。从系统测试来看,系统基本可以运行。

本新闻发布系统是本人所学web开发技术的一次实践,也是本人第一次系统开发,因此系统在各方面均存在或多或少的不足:

系统页面设计主要是系统页面色彩和结构布局上不尽如人意;

新闻发布系统的某些重要功能还未实现,比如前台新闻搜索和新闻评论;

7.2 系统改进

对于本系统,个人认为急需改进的地方是:(1)系统在前台设置搜索引擎,能够搜索站内新闻;(2)用户在浏览新闻时,可以对新闻内容作出评论;(3)系统管理员可以在后台设置前台版面显示格式和内容;(4)新闻添加时界面改为所见即所得的编辑管理界面,并且应设置可以添加图片;(5)系统可以添加多个管理员并设置他们的权限;(6)最后实现新闻信息通过模版生成HTML页面供用户阅读。

但介于本人实践经验的不足和时间的限制,本文主要对系统后台功能进行详细的设计和实现,而对前台显示功能各方面还需要改进。


结  论

本文通过采用基于UML的用例驱动对象建模的ICONIX软件项目管理方法,运用MVC三层设计模式,设计并实现了一个新闻发布系统。本新闻发布系统主要实现了新闻的后台管理,例如新闻的添加、修改和删除等功能;同时也实现了新闻栏目的管理,例如栏目的添加、修改和删除等功能。通过系统测试用例分析,达到了既定的系统设计目标。但由于时间关系和个人各方面因素,系统仍存在一定缺陷,并且有一些Java开发的新技术和思想没有加入到本系统开发中,希望在今后的学习和工作中,提高系统开发能力,做出更好的系统。


致  谢

本文是我在XX老师的悉心指导下完成的,从论文的选题、系统的开发到论文的撰写都得到了彭老师极大的帮助。他所具有的精湛的学术造诣、勤恳的工作作风和对学生认真负责的态度使我深受感动,终生难忘。在此向彭老师表示深深的敬意和衷心的感谢。同时,非常感谢学校、学院各位老师和领导对我各方面的关心与支持。

感谢我的室友们对我的帮助和指点,感谢他们与我交流经验,解决一道道心理上和技术上的难关。

感谢我的父亲、母亲和妹妹对我的理解、支持和帮助。尽管与他们为我付出的一切相比,所有的语言都显得苍白无力,我仍要真诚地说一声:谢谢!


参考文献

[1] 陈涵生,郑明华编著.基于UML的面向对象建模技术[M].科学出版社.2006.

[2] Doug Rosenberg Kendall Scott著.徐海,周靖,陈华伟译.UML用例驱动对象建模[M].清华大学出版社,2003.

[3] 计磊,李里,周伟.精通J2EE整合应用案例[M].人民出版社,2006.

[4] 孙福振,李艳,李业刚.基于J2EE的MVC设计模式的研究与实现[J].山东理工大学学报(自然科学版).2006.20(2):49-56.

[5] 万峰科技.JSP网站开发四“酷”全书[M].北京:电子工业出版社.2005.

[6] 施昊华,张朝辉编著. UML面向对象结构设计与应用[M].国防工业出版社.2003.

[7] 徐锋,陈暄等编著.UML面向对象建模基础[M].中国水利水电出版社.2006.

[8] 何玉洁编著.数据库原理与应用教程[M].机械工业出版社.2005.

[9] 王晓路,卢建军,马莉.基于JAVA的连接池优化Web数据库连接[J].西安科技大学学报.2005.

[10] 肖捷,肖正新.基于Java的通用数据库连接池组件的设计与实现[J].东莞理工大学学报.2006.

[11] 张海藩.软件工程导论(第四版)[M].清华大学出版社.2003.

[12] 贾广宇.MVC设计模式下Web开发框架的研究与应用[D].大连海事大学.2006.3:1-2.

[13] 陈彦,沙莎.基于MVC架构的Web应用程序的分析与实现[J] .湖南科技学院学报.2006.27(11):238-240.

[14] 张黎明,龚琪琳.基于MVC模式的Java Web应用设计[J] .计算机与现代化.2007(2):22-24.

[15] David Harms.JSP, Servlets, and MySQL[M] .Feb 21, 2006.

[16]Sun Microsytems, Inc.JDBC Techneology[EB/OL] .http://java.sun.com/products/jdbc.

[17] 欧阳君,赵 霁.对JDBC连接性能的分析[J].信息技术.2006.4:124-127.

[18] The MVC Design Pattern[J] .Beginning Apache Struts.Publish by Apress 2006.11.22:56-60.

[19] 王树杰.MVC框架的研究及M-Struts实现[D].首都经济贸易大学信息学院.2006.3:14.

[20] 江莎.基于Java的数据库连接池的研究[D].武汉理工大学信息工程学院.2006.4:34.

[21] 商杰,朱战立.JSP数据库连接池的设计与实现[J].电脑知识与技术2006.9:13-14.


附件

Category代码:

/**

 *  栏目表中所使用的一些字段

 */

package mybean;

public class Category {

private String name;

private int id;

public Category() {

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

News代码:

/**

  *  新闻表中所使用的一些字段

 */

package mybean;

import java.text.SimpleDateFormat;

import java.util.Date;

public class News {

private int id;

private String title;

private String content;

private String author;

private String compose_date;

private int categoryid;

public News(){

}

public int getCategoryid() {

return categoryid;

}

public void setCategoryid(int categoryid) {

this.categoryid = categoryid;

}

public String getContent() {

return content;

}

public void setContent(String content) {

this.content = content;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getAuthor() {

return author;

}

public void setAuthor(String author) {

this.author = author;

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

public String getCompose_date(){

return compose_date;

}

public void setCompose_date(){

SimpleDateFormat simpledate = new SimpleDateFormat(

"yyyy-MM-dd HH:mm:ss");

String strCompose_date = simpledate.format(new Date());

compose_date=strCompose_date;

}

public void setCompose_date(String strTime){

compose_date=strTime;

}

}

CategoryMgr代码:

/**

 *  对news_category表的一些增,删,改,查询操作

 */

package mybean;

import java.sql.*;

import java.util.ArrayList;

import java.util.Collection;

import mybean.Category;

import mybean.DatabaseConnection;

public class CategoryMgr {

ConnectionPool conpool=new ConnectionPool();

Connection con=null;

Statement stmt = null;

ResultSet rs = null;

public CategoryMgr() {

}

/*

* 修改栏目名称

*/

public void modify(Category category) {

con= conpool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="update Category set name='"+category.getName()+"' where id="+category.getId();

stmt.executeUpdate(sql);

/*

 * 删除栏目

 */

public void delete(int id) {

con= conpool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="delete from Category where id="+id;

stmt.executeUpdate(sql);

/*

 * 添加新的栏目

 */

public void add(Category category) {

con= conPool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String selectsql="select top 1 * from Category order by id DESC";

rs=stmt.executeQuery(selectsql);

rs.beforeFirst();

rs.next();

int id=rs.getInt("id");

String sql="insert into Category values("+(id+1)+",'"+category.getName()+"')";

stmt.executeUpdate(sql);

/*

* 得到所有栏目

*/

public Collection getAll() {

Collection c = new ArrayList();

con=conPool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="select * from Category order by id ASC";

rs=stmt.executeQuery(sql);

Category category=null;

while(rs.next()){

category=new Category();

category.setId(rs.getInt("id"));

category.setName(rs.getString("name"));

c.add(category);

category=null;

}

return c;

}

/*

 * 根据ID得到栏目

 */

public Category getById(int id) {

con= conPool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="select * from Category where id="+id+"order by id ASC";

rs=stmt.executeQuery(sql);

if(rs.next()){

Category category=new Category();

category.setId(rs.getInt("id"));

category.setName(rs.getString("name"));

return category;

}

return null;

}

/*

 * 计算栏目的总数

 */

public int getTotal() {

int count = 0;

con= conPool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="select * from Category";

rs=stmt.executeQuery(sql);

while(rs.next()){

count+=1;

}

return count;

}

NewsMgr代码:

/**  

 * NewsMgr主要对news表的一些增,删,改,查询操作

 */

package mybean;

import java.sql.*;

import java.util.ArrayList;

import java.util.Collection;

import mybean.News;

import mybean.DatabaseConnection;

public class NewsMgr {

ConnectionPool conpool=new ConnectionPool();

Connection con=null;

Statement stmt = null;

ResultSet rs = null;

/*

 * 添加新闻

*/

public void add(News news) {

con=conpool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String selectsql="select top 1 * from News order by id DESC";

rs=stmt.executeQuery(selectsql);

rs.beforeFirst();

rs.next();

int id=rs.getInt("id");

String sql="insert into News values("+(id+1)+",'"+news.getTitle()+"','"+news.getContent()+"','"+news.getAuthor()+"','"+news.getCompose_date()+"',"+news.getCategoryid()+")";

stmt.executeUpdate(sql);

}

/*

* 修改新闻

*/

public void modify(News news) {

con= conpool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="update News set title='"+news.getTitle()+"',content='"+news.getContent()+"',author='"+news.getAuthor()+"',class="+news.getCategoryid()+" where id="+news.getId();

stmt.executeUpdate(sql);

}

/*

* 删除新闻

 */

public void delete(int id) {

con= conpool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="delete from News where id="+id;

stmt.executeUpdate(sql);

}

/*

 * 根据CategoryId得到某栏目所有的新闻

 */

public Collection getAllByCategory(int categoryId) {

Collection c = new ArrayList();

con= conpool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="select * from News where class="+categoryId+"order by id desc";

rs=stmt.executeQuery(sql);

News news=null;

while(rs.next()){

news=new News();

news.setId(rs.getInt("id"));

news.setTitle(rs.getString("title"));

news.setContent(rs.getString("content"));

news.setAuthor(rs.getString("author"));

news.setCompose_date(rs.getString("compose_date"));

news.setCategoryid(rs.getInt("class"));

c.add(news);

news=null;

}

return c;

}

/*

 * 根据ID得到新闻

 */

public News getById(int id) {

con= conpool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="select * from News where id="+id;

rs=stmt.executeQuery(sql);

if (rs.next()){

News news=new News();

news.setId(rs.getInt("id"));

news.setTitle(rs.getString("title"));

news.setContent(rs.getString("content"));

news.setAuthor(rs.getString("author"));

news.setCompose_date(rs.getString("compose_date"));

news.setCategoryid(rs.getInt("class"));

return news;

}

return null;

}

/*

 * 查询所有的新闻

 */

public Collection getAllNews() {

Collection c = new ArrayList();

con= conpool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="select * from News order by id DESC";

rs=stmt.executeQuery(sql);

News news=null;

while(rs.next()){

news=new News();

news.setId(rs.getInt("id"));

news.setTitle(rs.getString("title"));

news.setContent(rs.getString("content"));

news.setAuthor(rs.getString("author"));

news.setCompose_date(rs.getString("compose_date"));

news.setCategoryid(rs.getInt("class"));

c.add(news);

news=null;

}

return c;

}

/*

* 计算某类别新闻的总数

 */

public int getTotalByCategoryId(int categoryId) {

int newsCount = 0;

con= conpool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="select * from News where class="+categoryId+"order by id DESC";

rs=stmt.executeQuery(sql);

while(rs.next()){

newsCount+=1;

}

return newsCount;

}

/*

 * 计算新闻的总数

 */

public int getTotal(){

int newsCount = 0;

con= conpool.getConnection();

stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="select * from News ";

rs=stmt.executeQuery(sql);

while(rs.next()){

newsCount+=1;

}

return newsCount;

}

ConnectionObject代码:

package mybean;

import java.io.*;

import java.sql.*;

import java.util.*;

public class ConnectionObject

{

private Connection connection; //数据库连接属性:连接对象标识和句柄

private boolean isUse; //连接使用状态属性:连接对象当前是否被使用

private int useCount; //连接使用次数属性:纪录连接对象的使用次数

/*

*构造方法:建立与某个数据源的连接,产生一个连接对象,

*并初始化该连接对象的属性。*/

public ConnectionObject(String url,String username,String password){

try{

if(username.equals("")){

connection=DriverManager.getConnection(url);

}

else{ connection=DriverManager.getConnection(url,username,password);

}

}

catch(SQLException e){

System.err.print(e.getMessage());

}

isUse=false; //初始化连接对象的使用状态为空闲

useCount=0; //初始化连接对象的使用次数为0

}

public Connection getConnection(){

return connection;

}

public void setConnection(Connection connection){

this.connection=connection;

}

public boolean isIsUse(){

return isUse;

}

public void setIsUse(boolean isUse){

this.isUse=isUse;

}

public void setUseCount(int useCount){

this.useCount=useCount;

}

public int getUseCount(){

return useCount;

}

public void addUseCount(){ //连接对象使用次数加1的函数

useCount+=1;

}

}

ConnectionPool代码:

package mybean;

import java.io.IOException;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.SQLWarning;

import java.sql.Statement;

import java.util.Date;

import java.util.Vector;

public class ConnectionPool

{

private String driver=""; //数据库驱动程序

private String url=""; //数据库url

private String username=""; //数据库用户名

private String password=""; //数据库用户密码

private Vector pool=new Vector(); //使用Vector对象作为连接池

private int connectionPoolSize; //初始化时,连接池中建立的连接对象数目

private int connectionPoolMaxSize; //连接池上限:至多建立的连接对象数目

private int connectionMaxUseCount; //一个连接对象至多能被使用的次数

private int timeout; //设置连接超时时间

private void loadProp(){ //从dbconfig.txt文件中读取数据库连接配置信息,初始化9个属性

String str;

int count=0;

FileReader fr=new FileReader("dbconfig.txt");

BufferedReader bufr=new BufferedReader(fr);

while((str=bufr.readLine())!=null){

count++;

System.out.println(str);

}

bufr.close();

fr.close();

}

/*

 *初始化连接池函数:首先从dbconfig.txt配置文件中读取配置信息,

 *然后初始化连接池的各种属性,最后在连接池中创建初始连接对象。

 *该方法被类的构造函数调用。*/

private void initPool(){ //创建连接对象,并初始化连接池

//从dbconfig.txt配置文件中读取数据库配置信息,初始化9个属性

loadProp();

try{

Class.forName(driver);

}

catch(ClassNotFoundException e){

System.err.print(e.getMessage());

}

//创建connectionPoolSize个空闲的连接对象,并把它们加入连接池中

while(pool.size()<connectionPoolSize){

ConnectionObject newConn=new ConnectionObject(url,username,password);

pool.add(newConn);//将连接对象加入连接池中

}

}

public ConnectionPool(){ //构造函数

initPool();

}

/*析构函数:释放连接池中所有的连接对象,并清空连接池。

 *该函数在连接池被销毁时自动调用,以释放所占用的系统资源。*/

public void finalize(){ //析构函数,释放所有的连接对象,清空连接池

for(int i=0;i<pool.size();i++){

ConnectionObject co=(ConnectionObject)pool.elementAt(i);

try{

co.getConnection().close();//关闭连接对象

}

catch(SQLException e){

System.err.print(e.getMessage());

}

co=null;//释放连接对象

}

pool=null;//清空连接池

}

private int findonnectionID(Connection conn){//查找连接对象在连接池中的序号

int index=0;

for(int i=0;i<pool.size();i++){

ConnectionObject co=(ConnectionObject)pool.elementAt(i);

if(co.getConnection()==conn){

index=i;

break;

}

}

return index;

}

private void realse(Connection conn){ //释放占用连接对象的函数

}

private ConnectionObject getFreeConnection(){//查找连接池,返回一个空闲连接

}

/*申请空闲连接对象函数:在申请空闲连接对象时,根据连接池管理机制

 *和调度策略,从连接池中申请空闲的连接对象,若申请成功,则返回申请

 *到的连接对象并置该连接对象的使用状态为占用状态,否则等待timeout时间

 *后重新申请,若仍未成功,则返回null值,否则返回申请到的连接对象

 *并置该连接的使用状态为占用状态。*/

public Connection getConnection(){ //申请空闲连接的对象的函数

//调用getFreeConnection方法,申请空闲连接对象

ConnectionObject connectionobj=getFreeConnection();

//若连接池中无空闲连接对象并且连接池没有达到上限,则创建一个新的连接对象

if(connectionobj==null&&pool.size()<connectionPoolMaxSize){

ConnectionObject co=new ConnectionObject(url,username,password);

pool.addElement(co);

connectionobj=getFreeConnection();

}

//若成功申请,则返回申请到的连接对象并置该连接对象的使用状态为占用状态,否则进入等待状态

if(connectionobj!=null){

connectionobj.setIsUse(true);

connectionobj.addUseCount();

return connectionobj.getConnection();

}

else{/*等待timeout时间后重新申请空闲连接对象,若申请成功

则返回申请到的连接并置该连接对象的使用状态为占用状态,否则返回null值*/

try{

java.lang.Threed.sleep(timeout);

}

catch(Exception e){

System.err.print(e.getMessage());

}

connectionobj=getFreeConnection();

if(connectionobj!=null){

connectionobj.setIsUse(true);

connectionobj.addUseCount();

return connectionobj.getConnection();

}

return null;

}

}

/*释放占用连接对象函数:在释放占用连接对象时,根据连接池管理机制,

 *若连接对象的使用次数超过连接池规定的使用上限,则将连接对象从连接池中

 *删除,否则释放占用的连接对象,并置连接对象的使用状态为空闲*/

 public void realse(Connection conn){

  int index=findConnectionID(conn);

  if(index==-1){

  return ;

  }

  ConnectionObject co=(ConnectionObject)pool.elementAt(index);

  //若连接使用次数超过connectionMaxUseCount,则将此连接对象从连接池中删除

  if(co.getUseCount()>=connectionMaxUseCount){

  pool.remove(index);

  }

  else{

  co.setIsUse(false);//置连接对象的使用状态为空闲

  }

 }

}

Dbconfig.txt:

#数据库连接配置文件

#数据库驱动程序

db.driver= com.microsoft.jdbc.sqlserver.SQLServerDriver

#数据库url(hrp-server:数据库服务器名或IP地址,thin:数据源名)

db.url= jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mypub

#数据库用户名

db.user=admin

并数据库用户密码

db.password=admin

#最小连接数

db.minconnection=10

井最大连接数(连接池上限)

db.maxconnection=20

#每个连接最大使用次数

db.connectionmaxusecount=100

#设置连接超时时间,单位毫秒

db.timeout=60000;

Loginservlet代码:

protected void doPost(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

Connection con=null;

Statement stmt = null;

ResultSet rs = null;

// 获取提交的用户名:

String strUserName = request.getParameter("username");

// 获取提交的密码:

String strPassword = request.getParameter("password");

try {

ConnectionPool conpool=new ConnectionPool ();

con=conpool.getConnection();

stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql="select * from Master where mastername='"+strUserName+"' and masterpassword='"+strPassword+"'";

rs=stmt.executeQuery(sql);

if(rs.next()){

request.getSession(true).setAttribute("username", strUserName);

request.getSession(true).setAttribute("password", strPassword);

response.sendRedirect("admin/main.jsp");

}

else{

response.sendRedirect("admin/loginerror.jsp");

}

} catch (Exception e) {

System.err.println(e);

} finally{

try{

rs.close();

stmt.close();

con.close();

}

catch(SQLException sqlex){

sqlex.printStackTrace();

}

}

}

AddCategoryServlet代码:

protected void doPost(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

if(request.getSession(true).getAttribute("username")==null){

response.sendRedirect("admin/loginerror.jsp");

}

String strName=request.getParameter("classname");

strName=new String(strName.getBytes("ISO8859_1"),"UTF-8");

Category category=new Category();

category.setName(strName);

CategoryMgr categoryMgr=new CategoryMgr();

categoryMgr.add(category);

response.sendRedirect("admin/saveclass.jsp");

}

AddNewsServlet代码:

protected void doPost(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException { if(request.getSession(true).getAttribute("username")==null){

response.sendRedirect("admin/loginerror.jsp");

}

String strTitle=request.getParameter("title");

strTitle=new String(strTitle.getBytes("ISO8859_1"),"UTF-8");

String strContent=request.getParameter("Content");

strContent=new String(strContent.getBytes("ISO8859_1"),"UTF-8");

int categoryId = Integer.parseInt(request.getParameter("classid"));

String strAuthor=(String)request.getSession(true).getAttribute("username");

strAuthor=new String(strAuthor.getBytes("ISO8859_1"),"UTF-8");

SimpleDateFormat simpledate = new SimpleDateFormat(

"yyyy-MM-dd HH:mm:ss");

String strCompose_date = simpledate.format(new Date());

News news=new News();

news.setTitle(strTitle);

news.setContent(strContent);

news.setCategoryid(categoryId);

news.setAuthor(strAuthor);

news.setCompose_date(strCompose_date);

NewsMgr newsMgr=new NewsMgr();

newsMgr.add(news);

response.sendRedirect("admin/savenews.jsp");

}

DeleteCategoryServlet代码:

protected void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException { if(request.getSession(true).getAttribute("username")==null){

response.sendRedirect("admin/loginerror.jsp");

}

String strId=request.getParameter("ID");

int id = Integer.parseInt(strId);

CategoryMgr categoryMgr=new CategoryMgr();

categoryMgr.delete(id);

response.sendRedirect("admin/classmanage.jsp");

}

DeleteNewsServlet代码:

protected void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException { if(request.getSession(true).getAttribute("username")==null){

response.sendRedirect("admin/loginerror.jsp");

}

String strId=request.getParameter("ID");

int id = Integer.parseInt(strId);

NewsMgr newMgr=new NewsMgr();

newMgr.delete(id);

response.sendRedirect("admin/main.jsp");

}

EditCategoryServlet代码:

protected void doPost(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException { if(request.getSession(true).getAttribute("username")==null){

response.sendRedirect("admin/loginerror.jsp");

}

String strName=request.getParameter("classname");

strName=new String(strName.getBytes("ISO8859_1"),"UTF-8");

int categoryId = Integer.parseInt(request.getParameter("ID"));

Category category=new Category();

category.setId(categoryId);

category.setName(strName);

CategoryMgr categoryMgr=new CategoryMgr();

categoryMgr.modify(category);

response.sendRedirect("admin/classmanage.jsp");

}

EditNewsServlet代码:

protected void doPost(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException { if(request.getSession(true).getAttribute("username")==null){

response.sendRedirect("admin/loginerror.jsp");

}

String strTitle=request.getParameter("title");

strTitle=new String(strTitle.getBytes("ISO8859_1"),"UTF-8");

String strContent=request.getParameter("Content");

strContent=new String(strContent.getBytes("ISO8859_1"),"UTF-8");

String strAuthor=(String)request.getSession(true).getAttribute("username");

strAuthor=new String(strAuthor.getBytes("ISO8859_1"),"UTF-8");

int categoryId = Integer.parseInt(request.getParameter("classid"));

int newsId = Integer.parseInt(request.getParameter("ID"));

String strDate=request.getParameter("Date");

strDate=new String(strDate.getBytes("ISO8859_1"),"UTF-8");

News news=new News();

news.setTitle(strTitle);

news.setContent(strContent);

news.setCategoryid(categoryId);

news.setAuthor(strAuthor);

news.setId(newsId);

news.setCompose_date(strDate);

NewsMgr newsMgr=new NewsMgr();

newsMgr.modify(news);

response.sendRedirect("admin/main.jsp");

}

新闻条目分页显示代码:

<%

int intPageSize;//一页显示的记录数

int intRowCount;//记录总数

int intPageCount;//总页

int intPage;//待显示页码

String strPage;

intPageSize=8;//设置一页显示的记录数

strPage=request.getParameter("page");//取得待显示页码

if(strPage==null){//表明在QueryString中没有page这个参数,此时显示第一页数据

intPage=1;

}else{//将字符串转换为整型

intPage=Integer.parseInt(strPage);

}

intRowCount=newsMgr.getTotal();//获得记录总数

intPageCount=(intRowCount+intPageSize-1)/intPageSize;//计算总页数

if(intPage<1)intPage=1;

if(intPage>intPageCount)intPage=intPageCount;//调整待显示的页码

int startRow=(intPage-1)*intPageSize+1;

int endRow;

if(intPage!=intPageCount){

endRow=intPage*intPageSize;

}else{

endRow=intRowCount;

}

%>

<TR>

<TD bgColor=<%=tdbgcolor2%> colspan=2 width=100%>

当前页是第<%=intPage%>页 从第<%=startRow%>条新闻到第<%=endRow%>条新闻

</TD>

</TR>

<TR>

<TD bgColor=<%=tdbgcolor4%> width=60%>新闻标题</TD>

<TD bgColor=<%=tdbgcolor4%> width=20%>操作</TD>

</TR>

<%

Collection c= newsMgr.getAllNews();

Iterator iterator=c.iterator();

int i=0;

while(iterator.hasNext()){

News news=(News)iterator.next();

if(i<(intPage-1)*intPageSize || i>intPage*intPageSize-1){i++;continue;}

i++;

%>

<TR>

<TD bgColor=<%=tdbgcolor4%>><%=news.getTitle()%></TD>

<TD bgColor=<%=tdbgcolor4%>>

<a href="editnews.jsp?ID=<%=news.getId()%>">编辑</a>

<a href="../DeleteNewsServlet?ID=<%=news.getId()%>">删除</a>

</TD>

</TR>

<%}%>

</TBODY>

</TABLE>

<div align="center">

<%

if(intPage>1){

%>

<a href="main.jsp?page=<%=intPage-1%>">上一页</a>

<%}%>

第<%=intPage%>页 共<%=intPageCount%>页

<%

if(intPage<intPageCount){

%>

<a href="main.jsp?page=<%=intPage+1%>">下一页</a>

<%}%>

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
一整套毕业设计!代码论文调研报告齐全!同学上学期的毕设! 一、课题来源及意义 随着我国社会主义市场经济的快速发展,各行各业的竞争日趋激烈。传统的全静态的新闻,由于自动化程度低,运行中需要大量的网页制作人员,已经被淘汰。而全动态的新闻,自动化程度高,而被广泛采用。 通过使用动态和静态结合的新闻发布系统,使我们能够全身心地投入到网站运营上去。随着Internet的普及,网页逐渐融入人们的生活,快速及时地浏览新闻,获取五彩缤纷的网上信息,已成为人们日常生活的一部分,与此同时越来越多的企业建立了自己的WWW网站,企业通过网站可以展示产品,发布最新动态,与用户进行交流和沟通,与合作伙伴建立联系,以及开展电子商务等。其中,新闻管理系统是构成企业网站的一个重要组成部分,它担负着双层作用,一方面可以用来动态发布有关新产品或新开发项目,另一方面又可以及时向顾客公告企业经营业绩、技术与研发进展、特别推荐或优惠的工程项目、产品和服务,从而吸引顾客,扩大顾客群。 信息时代的高速发展,传统的报纸杂志已经远远满足不了人们的需求,人们更加希望能够在网上了解更多的新闻和信息,于是我们就很有必要在网上创建一个新闻发布管理信息系统了。大部分网站都是采用静态的方式来发布和管理信息的,可是网站需要更新的信息量也越来越大,所以这很不利于网站管理人员的工作。为了更加方便的管理网站,于是我们就很迫切的需要利用动态技术创建一个新闻发布管理信息系统了。 信息技术的发展使得整个世界越来越小,这也意味着企业的竞争环境由区域化向全球化发展,尤其是中国加入了WTO后,经济全球化是大趋势,企业所处的宏观环境实际上已经不仅仅是通过信息技术员连接起来狭义的网络,而应该将技术环境与经济环境结合在一起考虑,形成一种大网络的概念。企业对信息的掌握程度、信息获取是否及时、信息能否得到充分利用、对信息的反应是否敏感准确,已越来越成为衡量一个企业市场竞争能力的重要因素。所以建立动态的新闻发布系统适应企业发展的要求,其意义是具大的。新闻系统是一个比较典型的文档系统,掌握了新闻系统的开发,对于开发其它的文档系统都有很大的帮助。 二、国内外的发展状况 新闻发布系统,在国内外早已有着成熟的研究成果和广泛的社会应用.国内众多大型门户网站,如网易(http://www.163.com),新浪(http://www.sina.com.cn),搜狐(http:// www.sohu.com),首都在线(http://www.263.net),人民日报网(http://www.people.com.cn),中国新闻网(http://www.chinanews.com.cn)等,每天甚至时刻进行海量信息的维护,以保持网站内容及时更新,内容管理系统,起着绝对重要的作用,是当今动态网站内容更新的主要手段。国外也有很多这样的大型门户网站,如CNN(www.CNN.com),美国之音(www.voanews.com),新加坡联合早报网(www. zaobao.com)等。 三、本课题的研究目标
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等天晴i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值