
1 需求分析
1.1 系统概述
本系统是一个简单的投票系统,主要提供以下功能:系统首页上显示所有投票选项的列表,用户可以通过选中某个选项并点击“投票”按钮进行投票操作。另外,还提供查看投票详细信息的超链接,用户点击后可在另一页面上看到各个投票选项目前的投票情况,主要包括各选项所得的票数、占总票数的百分比等信息,并且以柱形图显示各选项的得票率,可以让用户从直观上看到各项的得票情况。最后,还提供系统维护功能,当用户以合法的管理员身份登录后,可以利用该功能来添加、删除投票选项。
1.2 系统运行环境
1. 硬件环境
●处理器: Inter Pentium 166 MX 或更高
●内存: 32M
●硬盘空间:1GB
●显卡: SVGA显示适配器
2. 软件环境
●操作系统: Windows 98/ME/2000/XP
●Web服务器:Tomcat 4.1.2或以上版本
●数据库: Access
●客户端: IE 5.0 或以上版本
●开发语言: JSP、Java
1.3 功能需求描述
投票系统主要是为用户提供一个方便易用的投票界面,同时还具有查看投票、添加和删除投票选项的功能。
投票系统主要需要实现以下一些基本功能:
1. 投票:用户在投票系统首页上可以通过选中每个投票项前面的单选按钮并单击“投票”按钮来进行投票。
2. 查看投票情况:用户在投票系统首页上可以通过点击“查看投票”超链接来查看当前的最新投票情况,包括各投票项的得票数、得票率等。
3. 管理员登录:当用户在投票系统首页上点击“投票系统维护”超链接时,需要用户输入合法的用户名和密码,成功登录后,可以使用系统维护功能。
4. 删除投票选项:用户做为管理员进入系统维护页面后,可以通过单击显示在每个投票项右边的“删除”超链接来删除对应的投票选项。
5. 添加投票选项:用户做为管理员进入系统维护页面后,可以通过在文本框中输入新的投票项名称并点击“提交”按钮来添加新的投票选项。
2 总体设计
2.1 开发与设计的总体思想
现在在许多网站都提供用户投票功能,本系统可做为一个子模块链入到任何一个需要投票功能的网站中,因此系统界面的设计应该尽量做到简洁友好,方便用户的使用。
系统采用B/S模式,使用JSP进行服务器端动态网页的开发。
2.2 系统模块结构图
依据需求分析结果,投票系统可以分为三个模块:数据库访问模块、投票功能模块和系统维护模块。如图2-1所示:
图2-1 系统模块结构图
2.3 模块设计
1. 数据库访问模块:提供连接、访问数据库的功能,利用JavaBean实现,当JSP页面中需要访问数据库时直接调用这个JavaBean。模块功能树如图2-2所示:
图2-2 数据库访问模块
2. 投票功能模块:提供投票功能以及查看投票功能,用户通过“投票”按钮对选中项进行投票操作,还可以通过“查看投票”链接查看各个投票选项目前的得票情况。模块功能树如图2-3所示:
图2-3 投票功能模块
3. 系统维护模块:包括管理员的登录、投票选项的添加、删除功能。系统维护模块功能树如图2-4所示:
图2-4 系统维护模块
2.4 系统流程描述
系统的流程图如图2-5所示:
图2-5 系统流程图
2.5 界面设计
界面设计应遵循简洁美观、方便易用的基本原则,具体设计如下:
1.投票系统主页面设计,具体设计效果图如图2-6所示:
图2-6 投票系统主页面设计效果图
2.查看投票情况页面设计,具体设计效果如图2-7所示:
图2-7 查看投票情况页面设计效果图
3.管理员登录页面设计,具体设计效果如图2-8所示:
图2-8 管理员登录页面设计效果图
4.系统维护页面设计,具体设计效果如图2-9所示:
图2-9 系统维护页面设计效果图
2.6数据库设计
本系统采用Access数据库,在数据库vote中使用的数据表结构设计如下:
(1)名称:投票信息表
表名称标识:vote
数据表vote用来存储所有投票选项的id号、名称、得票数等信息,表的结构如表2-1所示:
表2-1数据表vote的结构
| 名称 | 字段名称 | 数据类型 | 主键 | 非空 | 
| 投票项id号 | id | 数字(自动编号) | Yes | Yes | 
| 投票项名称 | item | 文本 | No | No | 
| 投票项的得票数 | count | 数字 | No | Yes | 
图2-10 数据表vote中的测试数据
(2)名称:管理员信息表
表名称标识:admin
数据表admin来存储管理员的用户名和密码信息,表的结构如表2-2所示:
表2-2 数据表admin的结构
| 名称 | 字段名称 | 数据类型 | 主键 | 非空 | 
| 管理员id号 | id | 数字(自动编号) | Yes | Yes | 
| 管理员用户名 | name | 文本 | No | No | 
| 管理员口令 | password | 文本 | No | No | 
图2-11 数据表admin中的测试数据
本系统采用JDBC-ODBC桥的方式连接数据库,因此要首先配置一个ODBC数据源,数据源名定为vote。
3 详细设计
基于系统需求分析与系统总体设计的结论,下面按照模块的划分来分别阐述系统的详细设计和实现过程。
3.1 应用部署图
投票系统对应于一个名为vote的Web应用,具体的部署情况及目录结构如图2-12所示:
图2-12 应用部署图
3.2 访问数据库的JavaBean
本系统使用一个JavaBean来专门完成数据库的连接、访问等操作,当在某几个JSP页面中需要访问数据库时,就可以直接调用这个JavaBean而不是把重复的代码都重写一遍,这样使得整个程序变得更加简洁、清晰。接下来,我们来实现访问数据库JavaBean。
1.模块描述
负责完成与数据库的连接、访问、关闭等操作。
2.类的设计与实现
(1)名称:DBBean.java
(2)功能:负责完成与数据库的连接、访问、关闭操作。
(3)属性设计:如表2-3所示。
表2-3 类属性定义表
| 属性名 | 属性类型 | 访问控制 | 描述 | 
| driverStr | String | 私有(private) | 要加载的驱动程序类名 | 
| ConnStr | String | 私有(private) | 连接得数据库url | 
| Conn | Connection | 私有(private) | 驱动程序和指定数据库之间的连接对象 | 
| Stmt | Statement | 私有(private) | 语句对象 | 
1)方法定义:public DBBean()
2)IPO图:
输入:无。
处理:加载由属性driverStr指定的驱动程序,若加载中出现异常,则显示异常描述信息。
输出:无。
3)程序清单:
public DBBean()
{
try {
//加载驱动程序
Class.forName(driverStr);
}
catch(ClassNotFoundException ex) {
System.out.println(ex.getMessage());
}
}
(5)主要方法设计
方法一:executeQuery方法
1)方法定义:public ResultSet executeQuery(String sql)
2)IPO图:
输入:要执行的SQL语句。
处理:创建驱动程序和指定数据库间的连接对象,建立语句对象,利用语句对象的executeQuery()方法执行SQL语句,并将执行结果存放于局部变量rs中。
输出:查询结果集rs。
3)程序清单:
//执行查询SQL语句,返回值是一个满足查询条件的结果集
public ResultSet executeQuery(String sql)
{
ResultSet rs = null;
try {
//获取驱动程序对象和指定数据库之间的连接对象
conn = DriverManager.getConnection(connStr);
//建立语句对象
stmt = conn.createStatement();
//执行SQL语句,返回一个结果集对象
rs = stmt.executeQuery(sql);
}
catch(SQLException ex) {
System.out.println(ex.getMessage());
}
return rs;
}
方法二:executeUpdate方法
1)方法定义:public int executeUpdate(String sql)
2)IPO图:
输入:要执行的SQL语句。
处理:创建驱动程序和指定数据库间的连接对象,建立语句对象,利用语句对象的executeUpdate()方法执行SQL语句,并将执行结果存放于局部变量result中。
输出:更新的记录个数result。
3)程序清单:
//执行添加、修改和删除SQL语句,返回值是受到此次操作影响的记录个数
public int executeUpdate(String sql)
{
int result=0;
try{
conn = DriverManager.getConnection(connStr);
stmt = conn.createStatement();
result = stmt.executeUpdate(sql);
}
catch(SQLException ex){
System.out.println(ex.getMessage());
}
return result;
}
方法三:close方法
1)方法定义:public void close()
2)IPO图:
输入:无。
处理:调用Connection对象和Statement对象的close()方法,关闭语句对象和连接对象。
输出:无。
3)程序清单:
//关闭方法
public void close()
{
try{
//关闭语句对象
stmt.close();
//关闭连接对象
conn.close();
}
catch(SQLException ex){
System.out.println(ex.getMessage());
}
}
(6)编译和部署JavaBean
编写好的JavaBean,可以使用JDK中的javac命令进行编译,需要注意的是,不带参数的javac命令没有生成目录的能力,需要使用带-d参数的命令进行编译:
javac DBBean.java –d .
其中的“.”代表当前目录,编译成功后,会在当前目录下生成一个名为dbBean的目录,在该目录中有编译好的字节码文件DBBean.class。
然后,将dbBean子目录以及该目录中的字节码文件复制到“Tomcat安装目录\\webapps\\vote\\WEB-INF\\classes”中(vote为投票系统对应的Web应用名),重启Tomcat服务器即可在vote应用中的各个JSP页面里使用该JavaBean。
3.3 投票功能模块
投票功能模块主要提供用户投票功能、查看投票信息功能,涉及到的几个JSP页面中均需要连接、访问数据库,因此使用了刚刚实现并发布好的DBBean来完成数据库连接及访问操作。
1.模块描述
提供投票功能、查看投票情况功能。
2. 源文件定义
(1)index.jsp
名称:投票系统首页
功能:主要负责把数据表vote中的所有记录读出并显示在页面上供用户投票。另外,还提供“查看投票”超链接供用户查看当前的所有投票情况。
输入:无。
处理:在vote表中查找所有记录,并显示各投票项的名称。
输出:投票项显示及操作界面。
程序清单:
<%--设置页面字符集,保证能够正确显示中文--%>
<%@ page contentType="text/html;charset=gb2312" import="java.sql.*"%>
<%--声明和创建数据库访问Bean的对象db,生存时间设为session--%>
<%--设置db对象的connStr属性值为“jdbc:odbc:vote”,即所连接的数据库的url--%>
(2)info.jsp
名称:查看投票情况页面
功能:主要负责显示目前的得票情况,包括投票项名称、得票数、总投票数、得票百分比和柱形图片。
输入:无。
处理:从vote表中查找每一项的得票数,计算总的投票数,并计算二者比值即每一项的得票率,根据得票率设置每一项的柱形图片width属性。
输出:各个投票项的得票情况及得票率柱形图。
程序清单:
<%@ page contentType="text/html;charset=gb2312" import="java.sql.*"%>
<%--继续使用在index.jsp中声明和创建的JavaBean对象db--%>
| 选项 | 得票数 | 比例 | 
|---|---|---|
| "+rs.getString("item")+""); | 得:"+num+"票 共:"+totalNum+"票"); | |
| 得票率:"); ");//按得票数的比例计算柱形图片的长度 out.println(""); //显示得票百分比 out.println(num*100/totalNum+"% | 
(3)vote.jsp
名称:投票处理页面
功能:主要负责处理投票,对用户在index.jsp中选中的投票项的得票数进行增1操作,并重定向回info.jsp,让用户可以查看当前最新的得票情况。
输入:用户要为之投票的投票项id号。
处理:在vote表中查找id号为输入值的记录,在其count字段当前值基础上增1,并更新表中相应的记录。
输出:重定向到查看投票页面。
程序清单:
<%@ page contentType="text/html;charset=gb2312" import="java.sql.*"%>
<%
String id=request.getParameter("id");
//查询id号等于用户所选中的投票项的id值的记录
ResultSet rs=db.executeQuery("select * from vote where id="+id);
int num=0;
//取出该投票项的当前得票数
if(rs.next())
num=rs.getInt("count");
//投票数增1
num++;
rs.close();
//在vote表中更新该投票项的得票数这一字段的值
db.executeUpdate("update vote set count="+num+" where id="+id);
db.close();
%>
<%--重定向到查看投票页面,让用户看到投票后的最新投票情况--%>
3.4 系统维护模块
1.模块描述
提供管理员登录、投票添加、删除功能。
2.源文件定义
(1)login.jsp
名称:管理员登录页面
功能:显示管理员登录表单,包括用户名和密码两项,并且当输入的信息不正确时,显示错误提示信息。
输入:出错提示信息。
处理:获取出错提示信息,若不是null则显示。
输出:管理员登录表单、错误提示信息。
程序清单:
<%@ page contentType="text/html;charset=gb2312"%>
<%
//获取错误提示信息
String warning=request.getParameter("warning");
if(warning!=null)
{
//转换字符编码,处理中文问题
warning=new String(warning.getBytes("8859_1"));
//输出错误提示信息
out.println("
}
%>
(2)process.jsp
名称:验证管理员身份页面
功能:验证登录用户是否为合法的管理员。
输入:在登录页面输入的信息(用户名和密码)。
处理:获取login.jsp中的表单提交过来的信息,验证是否为合法的管理员。若验证成功,则在session中写入标志变量并重定向到manage.jsp让用户进行系统维护操作;若验证失败则重定向回login.jsp并显示出错信息。
输出:根据验证结果重定向到不同页面。
程序清单:
<%@ page contentType="text/html;charset=gb2312" import="java.sql.*"%>
<%
//获取用户提交的用户名和密码信息
String user=request.getParameter("user");
String pw=request.getParameter("pw");
//在admin表中查找有无匹配的记录
String sql="select * from admin where name='"+user+"' and password='"+pw+"'";
ResultSet rs=db.executeQuery(sql);
//如果存在匹配的记录
if(rs.next())
{
//关闭结果集和连接Bean对象
rs.close();
db.close();
//将标志变量admin写入到session中
session.setAttribute("admin
%>
<%--重定向到manage.jsp页面让用户进行维护操作--%>
        
<%
}
else
{
rs.close();
db.close();
%>
//重定向到login.jsp页面,并传递一个参数warning,其值为错误提示信息
                     
<%
}
%>
(3)check.jsp
名称:验证是否成功登录页面
功能:验证用户是否做为管理员成功登录过。
输入:无。
处理:判断session中是否存储了标志变量admin,若不存在则说明该用户没有使用管理员身份在本次会话连接中登录过系统。
输出:若验证不同不过,重定向到登录页面。
程序清单:
<%
/*判断session中是否存有标志变量admin,若没有,表示该用户没有成功登录,则重定向回login.jsp页面*/
if(session.getAttribute("admin")==null)
response.sendRedirect("login.jsp");
%>
(4)manage.jsp
名称:系统维护首页
功能:主要负责对数据表vote中的所有记录进行显示,并且在每条记录的右边都显示一个“删除”超链接,当用户单击时,可以删除相应的记录。另外,还显示添加投票项的输入表单,用于获取用户输入的新增投票项信息。
输入:无。
处理:查询vote表,显示其中的所有记录。
输出:投票管理界面。
程序清单:
<%@ page contentType="text/html;charset=gb2312" import="java.sql.*"%>
//包含验证文件,避免非法用户进入该页面进行操作
<%@ include file="checkadmin.jsp"%>
| 删除投票项 | ||
|---|---|---|
| "+i+""); | "+rs.getString("item")+""); | 删除"); | 
| 添加投票项 | ||
| <%--利用表单输入添加信息,提交给添加投票项处理页面add.jsp--%> | ||
| 返回投票页面 | ||
(5)add.jsp
名称:添加投票项处理页面
功能:主要负责处理添加操作。
输入:用户输入的投票项名称。
处理:向vote表中插入新记录,其中item字段值为用户输入值,count字段值为0。
输出:重定向到投票管理页面。
程序清单:
<%@ page contentType="text/html;charset=gb2312" import="java.sql.*"%>
<%
request.setCharacterEncoding("gb2312");
//从表单中获取输入信息,存储到字符串变量additem中
String additem=request.getParameter("additem");
if(additem!=null)
{
/*向数据表vote中添加一条新记录,其item字段值为用户输入的信息,得票数初始时为0*/
String sql="insert into vote(item,count) values('"+additem+"',"+0+")";
db.executeUpdate(sql);
db.close();
}
%>
<%--重定向到manage.jsp让用户继续添加或删除操作--%>
(6)delete.jsp
名称:删除投票项处理页面
功能:主要负责处理删除操作。
输入:要删除的投票项id号。
处理:从vote表中删除相应记录。
输出:重定向到投票管理页面。
程序清单:
<%@ page contentType="text/html;charset=gb2312" import="java.sql.*"%>
<%
//获取跳转时传递过来的参数delid
String delid=request.getParameter("delid");
if(delid!=null)
{
//将id号为delid的记录从数据表vote中删除
db.executeUpdate("delete from vote where id="+delid);
db.close();
}
%>
<%--重定向到manage.jsp让用户继续添加或删除操作--%>
4 小结
本系统仅仅是一个功能十分简单的投票系统雏形,和完整的投票系统尚有差距,有些功能并未考虑,例如:对同一IP地址的用户重复投票的、对现有投票项的修改功能等,可以在今后的实践过程中加以改进、逐步完善。本系统旨在展现一个最基本的JSP与后台数据库互操作的应用程序的实现过程,为今后更为复杂的应用程序的实现打下基础。本系统中使用了JDBC技术实现了与后台数据库的互连,主要利用了JDBC中的几个重要接口,如:DriverManager、Connection、Statement和ResultSet等,利用其中的标准方法实现和数据库的连接、访问、断连等操作,完整的体现了一个数据库应用程序应具备的最普遍的功能,所使用的语句和操作步骤均可能在今后的相似类型的程序中使用到。另外,使用了JavaBean技术封装了对数据库的常用操作,在使用时只需对写好的JavaBean组件做简单的调用即可,有效的减少了代码冗余,提高了程序的执行效率。
在对本系统的实现过程中,首先应掌握关系数据库的标准语言SQL的基本语法和主要关键字,并会利用集函数如SUM()等来进行简单的统计或运算。另外,应重点掌握利用JDBC的标准接口访问数据库的操作方法,并应对在JSP页面中如何使用JavaBean组件有所了解。
