分类

课内:
不限
类型:
不限 毕业设计 课程设计 小学期 大作业
汇编语言 C语言 C++ JAVA C# JSP PYTHON PHP
数据结构与算法 操作系统 编译原理 数据库 计算机网络 软件工程 VC++程序设计
游戏 PC程序 APP 网站 其他
评分:
不限 10 9 8 7 6 5 4 3 2 1
年份:
不限 2018 2019 2020

资源列表

  • 基于php的校园二手信息网站的设计与开发

    摘 要二手信息网站,为二手物品交易提供了网上平台。如今,随着电子商务的不断发展完善,大学校园也需要一个能为学生提供二手物品交易的专用网站,以便发布各种商品信息。
    本设计具有一般电子商务的功能,且体现出校园风格。该系统提供的功能包括注册、查询信息、发布信息、找回密码等。本系统的特点在于应用了PHP技术。它是一种简单的动态脚本语言,具有开放源码、执行速度快的特点。该技术还支持广泛的数据库连接,具有大量的扩展库,安全性能高,易学易用。
    本文首先介绍了该系统的可行性和应用工具,并就系统的需求性和PHP的优势进行了阐述;接着进行系统分析,并设计了本系统所用到的基于MYSQL数据库的数据表结构;然后对该系统各功能模块进行了详细设计;最后,针对系统在代码优化和加密方面的不足做出总结。
    关键词:二手信息;PHP;MySQL;APACHE;MD5;SESSION
    AbstractSecond-hand informationwebsite provides a second-hand goods transactions online platform. Now, withthe continuous development of e-commerce perfect, University campus also needsan able to provide our students with the second-hand goods transactionsdedicated web site, in order to disseminate information of various commodities.
    E-commerce’s generalfunction can find in this design, and reflects the style of the campus.Functions include user registration, information inquiry, disseminateinformation and retrieve passwords in the system. The system has a majorcharacteristic of PHP applications which is a simple dynamic scripting languagethat is open source, faster implementation characteristics. And it supports awide range of database connections, with a lot of extensions, security is alsovery high performance, easy to learn and use.
    This paper introducesthe feasibility of the system and application tools, described the needs of thesystem and the advantages of PHP, then the systems analysis, design and MYSQL-based database system used in the data table structure, Then the functionof the system modules and the detailed design and code is a major achievement.Description and testing of the system encountered a character coding using thedatabase errors; by setting MYSQL and linking coding solve this error. Finally,summarize the system of encryption and code optimization for the shortage.
    Key words: Second-Hand Information;PHP; MySQL; APACHE; MD5; SESSION
    1 引 言1.1 课题的背景随着Internet 爆炸式的发展,中国自加入WTO以来,电子商务在国内也迅速的发展了起来,现在互联网上各种电子商务网站更是迅速的增长。还在校园的我也深受其中的影响,开发一个对在校学生适用的网站,希望能给大家提供方便的服务。
    作为一个大学生,深有体会,从身上的衣服到大家所用的书籍、文具以至各种生活常用品,用上一段时间就会被淘汰,有的同学干脆扔掉,很是浪费还污染了环境。也有的同学想到卖掉,苦于难寻买家,将其卖给收费品的。这样就造成了物不能尽其用。
    为了解决这种资源的浪费,所以开发了校园二手信息网站,借助于低交易成本的Internet。为大家提供一个低成本、快速迅捷的信息发布平台。新系统开发过程中严格按照系统开发步骤进行,在系统调研、分析、设计到系统的实施的全过程中,力求其科学性和合理性。
    1.2 可行性分析可行性分析的任务是从技术上、经济上、社会上、法律上分析需要解决的问题是否存在可行的解。
    1.2.1 技术可行性该系统采用BS模式设计,在高校的校园网上运行。学生可以通过接入校园网的计算机,访问二手信息网站。本系统是一个比较普通的BS模式的信息发布系统,在技术上具有可行性。
    1.2.2 经济可行性现在,计算机的价格已经十分低廉,性能却有了长足的进步。而本系统的开发,为大家节约了大量的资源,为此主要表现有以下几个方面:

    本系统的运行可以代替废物买卖贴示,避免一些不必要的麻烦
    本系统的运行可以节省许多资源
    本系统的运行可以大大的提高废物再利用
    本系统可以使敏感文档更加安全

    所以,本系统在经济上是可行的。
    1.2.3 运行可行性系统为一个小型的信息管理系统,所耗费的资源非常的小,一般的电脑无论是硬件还是软件都能够满足条件,因此,本系统在运行上是可行的。
    1.2.4 法律可行性系统纯为私人设计,在开发过程中没有涉及合同、责任等与法律相抵触的方面。因此,本系统在法律上是可行的。
    2 理论基础知识介绍2.1 PHP技术2.1.1 PHP简介PHP是一种简单的、面向对象的、解释型的、安全的、性能非常之高的、独立于架构的、可移植的、动态的脚本语言。PHP具有和Java类似的Class关键字。因为不需要虚拟机,以致速度比Java快5倍。PHP正迅速变成一种标准的、多用途的、面向对象的脚本语言。PHP不仅可用来开发Web应用程序,也可以开发普通应用程序。
    PHP是Hypertex tPre-Processor(超文本预处理器)的缩写,它是一种服务器端的HTML脚本编程语言。PHP语法上与C相似,可运行在Apache, Netscape/iPlanet,和Microsoft IIS Web服务器上。PHP作为一种工具,可以让你创建动态的Web页面。应用PHP的网页与常规的HTML页面并无二致,你可以用同样的方式来创建、编辑它们。PHP允许你直接在HTML文件里写入简单的脚本,这一点与JavaScript非常相似。而不同的是,PHP不依赖于浏览器,是服务器端的语言,而JavaScript却是一种客户端的嵌在HTML中的语言。概念上,PHP与Netscape的LiveWirePro产品,Microsoft的ASP以及Sun Microsystem的JSP相似。
    2.1.1.1 PHP的强劲之处在于:PHP是一项最优秀的技术。其它技术,如PERL,Python,VB Script,ASP相对来说,都是陈旧低劣的。即使是Java/JSP,也在PHP之下。其特点如下:

    兼容性:PHP5.0程序可与旧版本兼容
    易学易用:PHP的语法类似C及Per,所以有程序编写经验者很快即可上手
    开放的来源:PHP的原始码及编译后文件可免费下载
    可扩充:使用者可新增模块以扩充PHP引擎之功能
    跨平台:PHP程序可在数种主要作业平台及Web服务器上执行
    支持多种数据库:PHP支持十余钟数据库,且编写存取数据库资料的程序相当容易

    PHP是最好的,因为它面向对象,并且吸收了C/C++/Java/PERL的精华。PHP可以替代PERL,Python,Java,C,C++,AWK,Unix Shell脚本,Visual Basic和其它语言。PHP直接运行,而且是由C写成的。PHP可以运行在Apache,Microsoft IIS等多种Web服务器上。PHP太容易使用了,你可以用它在非常短的时间里,非常迅速的开发出非常复杂的Web。
    PHP最大的优势在于PHP自身完全是由C语言写成的,因此可广泛运行于各种平台之上,如BeOS,UNIX,MS Windows,Apple Macintosh,IBMOS/2以及其它更多的操作系统。而Windows下开发的PHP代码也可以不经过任何改变,就用于UNIX/Linux上。
    2.1.1.2 PHP网页执行流程PHP与传统网页不同,一般的HTML网页在加载时,会直接将网页全部传到使用者的计算机中,然而在使用者的计算机上执行程序,展示内容;PHP则是刚好相反,它主要的用途是在网站服务器端的网页开发,程序员可以通过程序的控制,让网站与访问者交互,进而设计出迷人的动态网页。例如:会员登录、资料认证网页等。如下图:

    2.1.2 PHP安装下载PHP安装程序 http://www.php.net/downloads.php最新版的为PHP5.1 ,Windows的PHP安装分为两种方式,一种是源代码安装方式,一种是EXE安装方式,双击即可安装。本文主要说一下源代码安装过程。
    下载“PHP-5.0.3-Win32.rar”。然后解压缩下载到的 RAR文件到c:\php
    复制 c:\php\php5ts.dll 到 c:\windows\system32。(有时候为了方便,在PHP文件夹中点击搜索*.dll把搜索到的所有文件夹都复制到system32中也可以)复制 c:\php\php.ini-recommended(或者是php.ini-dist)为 c:\windows\php.ini然后打开 c:\windows\php.ini修改如下几个地方:
    如果是在生产服务器上,可以不用修改下面这两行
    error_reporting=E_ALL & ~E_NOTICEdisplay_errors = On(这里是修改PHP的错误提示,OFF为不提示,有些数据库链接非错误信息也会被PHP当做错误信息输出,建议用作Web服务器的关闭!)
    指示 PHP 扩展库所在文件夹。
    extension_dir="c:\php\ext
    以下两个是超时时间:一般是60-120。
    max_execution_time=90 max_input_time=90post_max_size=8M(6-10M最佳)upload_max_filesize=8M(上传附件大小最大)default_socket_timeout=90(端口时间60-120)session.gc_maxlifetime=3600(session默认存活时间,秒)session.save_path="c:\php\sessiondata"(Session的存储目录)extension=php_mysql.dll(支持MySQL数据库)extension=php_gd2.dll(支持生成真彩图片)```php###2.1.3 验证安装用记事本写几行代码:```php<? phpinfo();?>保存为网站根目录下为phpinfo.php文件。然后启动浏览器,访问 http://localhost/phpinfo.php ,如果看到如下画面就证明PHP安装成功了!

    2.2 MySQL 简介MySQL是一个广受Linux社区人们喜爱的半商业的数据库。MySQL是可运行在大多数的Linux平台(i386,Sparc,etc),以及少许非Linux甚至非Unix平台。
    2.2.1 MySQL 简介2.2.1.1 安装可以在MySQL站点上获得大多数主要的软件包格式(RPM、DBE、TGZ、RAR)。RAR格式的安装没有多大麻烦,并且无需初始配置;直接解压缩运行安装文件即可进行安装。MySQL的守护进程(mysqld)消耗很少的内存并在只有在执行真正的查询时才装载到处理器上,这意味着对小型数据库来说,MySQL可以相当轻松地使用而不会对其他系统功能有太大的影响。
    2.2.1.2 数据类型字段支持大量数据类型是件好事。通常的整数、浮点数、字符串和数字均以多种长度表示,并支持变长的BLOB(Binary Large Object)类型。对整数字段由自动增量选项,日期时间字段也能很好的表示。
    2.2.1.3 SQL兼容性它也缺乏一些常用的SQL功能,没有子选择(在查询中的查询)。视图(View)也没了。当然大多数子查询可以用简单的连接子句重写,但有时用两个嵌套的查询思考问题比一个大连接容易。同样,视图仅仅为程序员隐蔽where子句,但这正是程序员们期望的另一种便利。
    2.2.1.4 存储过程和触发器MySQL没有一种存储过程(Stored Procedure)语言,这是对习惯于企业级数据库的程序员的最大限制。多语句SQL命令必须通过客户方代码来协调,这种情形是借助于相当健全的查询语言和赋予客户端锁定和解锁表的能力,这样才允许的多语句运行。
    2.2.1.5 参考完整性MySQL的主要的缺陷之一是缺乏标准的RI机制;然而,MySQL的创造者也不是对其用户的愿望置若罔闻,并且提供了一些解决办法。其中之一是支持唯一索引。Rule限制的缺乏(在给定字段域上的一种固定的范围限制)通过大量的数据类型来补偿。不简单地提供检查约束(一个字段相对于同一行的另一个字段的之值的限制)、外部关键字和经常与RI相关的“级联删除”功能。有趣的是,当不支持这些功能时,SQL分析器容忍这些语句的句法。这样做目的是易于移植数据库到MySQL中。这是一个很好的尝试,并且它确实未来支持该功能留下方便之门;然而,那些没有仔细阅读文档的人可能误以为这些功能实际上是存在的。
    2.2.1.6 安全性自始至终我对MySQL最大的抱怨是其安全系统,它唯一的缺点是复杂而非标准,另外只有到调用mysqladmin来重读用户权限时才发生改变。通常的SQL GRANT/REVOKE语句到最近的版本才被支持,但是至少他们现在有了。 MySQL的编写者广泛地记载了其特定的安全性系统,但是它确实需要一条可能是别无它法的学习过程。
    2.2.1.7 备份和恢复、数据导入/导出强制参考一致性的缺乏显著地简化备份和恢复,单靠数据导入/导出就可完美复制这一功能。LOAD DATA INFILE命令给了数据导入很大的灵活性。Select INTO命令实现了数据导出的相等功能。另外,既然MySQL不使用原始的分区,所有的数据库数据能用一个文件系统备份保存。数据库活动能被记载。与通常的数据库日志不同(存储记录变化或在记录映像之前/之后),MySQL记载实际的SQL语句。这允许数据库被恢复到失败前的那一点,但是不允许提交(commit)和回卷(rollback)操作。
    2.2.1.8 连接性MySQL客户库是客户/服务器结构的C语言库,它意味着一个客户能查询驻留在另一台机器的一个数据库。然而MySQL真正的强项处于该库中的语言“包装器(wrapper)”,Perl、Pathon和PHP只是一部分。Apache的Web服务器也有许多模块例如目录存取文件等允许各种各样的Apache配置信息(例如目录存取文件)使用MySQL,应用程序接口简单、一致并且完整。
    2.2.2 数据库引擎MyISAM强调了快速读取操作,这是为什么MySQL受到了Web开发如此青睐的主要原因:在Web开发中所进行的大量数据操作都是读取操作。所以,大多数虚拟主机提供商和Internet平台提供商(InternetPresenceProvider,IPP)只允许使用MyISAM格式。MyISAM存储格式自版本3.23以来是MySQL中的缺省类型,它有下列特点:

    如果操作系统自身允许更大的文件,那么文件比ISAM存储方法的大
    数据以低字节优先的机器独立格式存储。这表示可将表从一种机器拷贝到另一种机器,即使它们的体系结构不同也可以拷贝
    数值索引值占的存储空间较少,因为它们是按高字节优先存储的。索引值在低位字节中变化很快,因此高位字节更容易比较
    AUTO_INCREMENT处理比ISAM的表更好
    减少了几个索引限制。例如,可对含NULL值的列进行索引,还可以对BLOB和TEXT类型的列进行索引

    为了改善表的完整性检查,每个表都具有一个标志,在myisamchk对表进行过检查后,设置该标志。可利用myisamchk-fast跳过对自前次检查以来尚未被修改过表的检查,这样使此管理任务更快。表中还有一个指示表是否正常关闭的标志。如果服务器关闭不正常,或机器崩溃,此标志可用来检测出服务器起动时需要检查的表。
    2.3 Apache简介Apache是世界使用排名第一的Web服务器,它可以运行在几乎所有广泛使用的计算机平台上。
    Apache源于NCSAhttpd服务器。经过多次修改,他成为了世界上最流行的Web服务器软件之一。Apache取自“a patchy server”的读音,意思是充满补丁的服务器,因为它是自由软件,所以不断有人来为它开发新的功能、新的特性、修改原来的缺陷。Apache的特点是简单、速度快、性能稳定,并可做代理服务器来使用。
    本来它只用于小型或试验Internet网络,后来逐步扩充到各种Unix系统中,尤其对Linux的支持相当完美。Apache有多种产品,可以支持SSL技术,支持多个虚拟主机。Apache是以进程为基础的结构,进程要比线程消耗更多的系统开支,不太适合于多处理器环境,因此,在一个Apache Web站点扩容时,通常是增加服务器或扩充群集节点而不是增加处理器。到目前为止Apache仍然是世界上用的最多的Web服务器,市场占有率达60%左右。世界上很多著名的网站如Amazon.com、Yahoo!、W3 Consortium、Financial Times等都是Apache的产物,它的成功之处主要在于它的源代码开放、有一支开放的开发队伍、支持跨平台的应用(可以运行在几乎所有的Unix、Windows、Linux系统平台上)以及它的可移植性等方面。
    Apache服务器拥有以下特性:

    支持最新的HTTP/1.1通信协议
    拥有简单而强有力的基于文件的配置过程
    支持通用网关接口
    支持基于IP和基于域名的虚拟主机
    支持多种方式的HTTP认证
    集成Perl处理模块
    集成代理服务器模块
    支持实时监视服务器状态和定制服务器日志
    支持服务器端包含指令(SSI)
    支持安全Socket层(SSL)
    提供用户会话过程的跟踪
    支持Fast CGI
    通过第三方模块可以支持Java Servlets

    3 系统分析与数据库设计3.1 系统功能需求分析根据一般电子商务系统功能分析,将系统分为管理员、用户两大模块。系统管理员模块包括:系统配置管理、会员信息管理、网站新闻管理、物品信息管理、管理员管理、登录日志管理。用户模块包括:安全登录、找回密码、查询信息、发布信息、会员注册、物品类别、物品信息管理、会员信息修改。刚进入网站的非会员能够在此网站浏览和搜索信息,不仅能浏览二手信息还能浏览到热门信息。经过注册成为会员便能发布信息。此系统还考虑到用户利用穷举法破解密码,专门设置了用户和管理员登录日志,以便及时了解和防范。
    3.2 系统模块关系图根据系统功能需求建立的模块关系图如下图:

    3.3 系统E-R图本实例根据上面的模块关系图规划出的实体有管理员、二手信息机及新闻、用户、会员实体、各实体的E-R图及其关系描述如下(带下划线的为主键):
    会员实体E-R图

    二手信息实体E-R图

    新闻实体E-R图

    管理员实体E-R图

    超级管理远实体E-R图同管理员实体E-R图类似,无权限属性(省略)。
    各实体的关系E-R图描述如下:

    3.4 数据库设计3.4.1 数据库表之间的关系数据库表



    序号
    数据库表
    数据库存储内容




    1
    ershou_adminstage
    存储管理员和会员的登录日志


    2
    ershou_class
    存储二手信息的类别信息


    3
    ershou_pinglun
    存储会员对物品信息的评论


    4
    ershou_news
    存储新闻


    5
    ershou_user
    存储会员的相关信息


    6
    ershou_wupin
    存储以发布的物品信息


    7
    ershou_manager
    存储管理员的信息



    数据表关系图如下:

    3.4.2 数据表结构的详细设计用户资料表(ershou_user)



    序号
    字段名
    字段类别
    说明
    备注




    1
    user_name
    varchar(20)
    用户的账号名称
    主键


    2
    user_pass
    varchar(20)
    用户的帐号密码



    3
    user_question
    varchar(50)
    找回密码提问



    4
    user_angser
    varchar(50)
    找回密码答案



    5
    user_mphone
    varchar(12)
    移动电话



    6
    user_phone
    varchar(12)
    座机



    7
    user_school
    varchar(60)
    所在学校



    8
    user_email
    Varchar(80)
    电子邮箱



    9
    user_date
    datetime
    注册时间



    10
    user_qq
    Int
    QQ号



    11
    user_kt
    Int
    标志
    默认为0



    类别信息表(ershou_class)



    序号
    字段名
    字段类别
    说明
    备注




    1
    class_name
    varchar(20)
    类别名称
    主键


    2
    class_order
    int
    大类顺序标记小类为默认的0
    默认值为0


    3
    class_cid
    int
    小类顺序标记大类为默认的0
    默认值为0



    用户与管理员登录日志信息表(ershou_adminstage)



    序号
    字段名
    字段类别
    说明
    备注




    1
    manager_name
    varchar(20)
    登录名
    主键


    2
    manager_action
    varchar(50)
    登录动作



    3
    manager_ip
    varchar(30)
    登录ip



    4
    manager_time
    datetime
    登录时间



    5
    manager_state
    int
    登录状态
    默认为0


    6
    manager_if
    Int
    判断为管理员还是用户
    默认为0



    评论表(ershou_pinglun)



    序号
    字段名
    字段类别
    说明
    备注




    1
    pid
    int
    Id
    主键


    2
    pinglun_wid
    int
    物品id
    默认值为0


    3
    user_name
    varchar(20)
    会员名



    4
    pinglun_nr
    varchar(200)
    内容



    5
    Pinglun_time
    datetime
    时间



    网站新闻表(ershou_news)



    序号
    字段名
    字段类别
    说明
    备注




    1
    nid
    tinyint(6)
    设置新闻编号



    2
    news_title
    varchar(100)
    设置新闻标题



    3
    news_class
    varchar(20)
    设置新闻类别



    4
    news_ly
    varchar(30)
    新闻来源



    5
    news_jishu
    int
    浏览次数
    默认值为0


    6
    news_nr
    text
    新闻内容



    7
    news_time
    datetime
    设置添加时间



    8
    news_guoqi
    Char(2)
    设置是否过期
    默认值为1


    9
    news_name
    varchar(20)
    发表新闻的管理员帐号
    主键



    物品信息表(ershou_wupin)



    序号
    字段名
    字段类别
    说明
    备注




    1
    wid
    int
    物品id
    主键


    2
    bclass_name
    varchar(20)
    所属大类别



    3
    class_name
    varchar(20)
    所属小类别



    4
    wuping_name
    varchar(40)
    物品名称



    5
    wuping_jishu
    int
    浏览次数
    默认设置为0


    6
    wuping_nr
    text
    物品介绍



    7
    user_name
    varchar(20)
    用户帐号



    8
    wuping_time
    datetime
    发表时间



    9
    wuping_guoqi
    int
    交易状态
    默认设置为1



    管理员信息表(ershou_manager)



    序号
    字段名
    字段类别
    说明
    备注




    2
    manager_name
    varchar(20)
    管理员名称
    主键


    3
    manager_pass
    varchar(20)
    管理员密码



    4
    manager_sup
    int
    标志为管理员权限
    默认值为0



    3.5 系统安全MD5是在Web应用程序中最常用的密码加密算法。由于MD5是不可逆的,因而经过MD5计算得到后的密文,不能通过逆向算法得到原文。所谓MD5,即”Message-Digest Algorithm 5(信息-摘要算法)”,它由MD2、MD3、MD4发展而来的一种单向函数算法(也就是HASH算法),它是国际著名的公钥加密算法标准RSA的第一设计者R.Rivest于上个世纪90年代初开发出来的。MD5的最大作用在于,将不同格式的大容量文件信息在用数字签名软件来签署私人密钥前”压缩”成一种保密的格式,关键之处在于——这种”压缩”是不可逆的。
    在Web应用程序中使用MD5加密文本密码的初衷,就是为了防止数据库中保存的密码不幸泄露后被直接获得。但攻击者不但拥有数据量巨大的密码字典,而且建立了很多MD5原文/密文对照数据库,能快速地找到常用密码的MD5密文,是破译MD5密文的高效途径。然而,MD5密文数据库所使用的是最常规的MD5加密算法:原文—>MD5—>密文。因此,使用字符串次序干涉MD5算法,使现成的MD5密文数据库无所作为。此函数是把MD5运算后的密文字符串的顺序调转后,再进行一次MD5运算。函数代码如下:
    function md5_5($psw) { //得到数据的密文 $ psw = md5($psw); //再把密文字符串的字符顺序调转 $ psw = strrev($psw); //最后再进行一次MD5运算并返回 return md5($psw); }
    4 系统的实现4.1 系统的主要功能归纳起来,系统的功能大约有以下几点:用户注册,信息查询,发布信息,找回密码等。
    4.1.1 注册为了实现不同地域的学生通过网络、不择时间地自主填写并上传自己的基本档案(不合要求的档案可以由管理员及时清除),需要录入基本的个人信息。
    4.1.1.1 步骤
    开始注册
    填写个人信息
    提交(如失败返回填写页面重填写;如果重名错误,显示提示信息)
    进入登录界面
    登录成功,进入主界面

    4.1.1.2 主要验证代码://值存在则继续执行if(($_GET["ac"]=="in")and(isset($_POST["user_name"]))) { //判断验证码是否正确 if($_POST["ac_uthnum"]==$_SESSION["user_authnum"]) { $user_name=$_POST["user_name"]; $user_name=trim($user_name); $user_pass1=$_POST["user_pass"]; $user_pass1=trim($user_pass1); $user_pass=md5_5($user_pass1);//密码进行MD5加密 $user_question=$_POST["user_question"]; $user_angser1=$_POST["user_angser"]; $user_angser1=trim($user_angser1); $user_angser=md5_5($user_angser1);//密码进行MD5加密 $user_school=$_POST["user_school"]; $user_phone=$_POST["user_phone"]; $user_mphone=$_POST["user_mphone"]; $user_qq=$_POST["user_qq"]; $user_email=$_POST["user_email"]; $user_kt="1"; //查询是否存在当前注册用户名 $query="select count(*) count from ershou_user where user_name='$user_name'"; $result=mysql_query($query); while($info=mysql_fetch_array($result)) { $count=$info["count"]; } if($count==0){//不存在才执行注册 $sqladd = "INSERT INTO ershou_user SET user_name='$user_name', user_pass='$user_pass', user_question='$user_question', user_angser='$user_angser', user_school='$user_school', user_phone='$user_phone', user_mphone='$user_mphone', user_qq='$user_qq', user_email='$user_email', user_kt='$user_kt', user_date=NOW()"; else{//存在相同用户名则重新填写 echo '<table width="100%" border="0" cellPadding="0" cellSpacing="0"> <tr> <td height="300" align="center"><img src="images/warning.gif" border="0" /> 该会员已存在 <a href="javascript:history.back()">返回</a>重新填写 </td> </tr> </table>';} }
    4.1.1.3 主要窗口如下图:
    4.1.2 搜索信息为了实现快速浏览网站信息,各用户可以根据所须信息类别并填写查询关键字,很快的找出需要的信息。
    4.1.2.1 步骤:
    填写信息类别
    修改或删除信息类别
    浏览信息类别

    4.1.2.2 主要代码$sql ="select count(*) count from ershou_wupin where bclass_name='$bclass_name' and wupin_name like '%$searchcontent%'"; $result=mysql_query($sql) or die(mysql_errno().": ".mysql_error()."\n"); $rs=mysql_fetch_object($result); $recountCount=$rs->count; $show=20; $totalPage=ceil($recountCount/$show); $page = (isset($_GET['page']) && $_GET['page']>=0)? $_GET['page']: 0; $isLast = ($page==($totalPage-1))? true: false; $hasNoPre = ($page==0)? true: false; $hasNoNext = ($page==$totalPage-1)? true: false; $isFirst = ($page==0)? true:false; $start = $page*$show; if($recountCount==0){ //搜索结果不为0则显示未找到echo '<tr><td height="25" align="center">未找到!</td></tr>';} else{ $sqlwupin="select * from ershou_wupin where bclass_name='$bclass_name' and wupin_name like '%$searchcontent%' ORDER BY wupin_time desc limit $start,20"; $resultwupin = mysql_query($sqlwupin) or die(mysql_errno().": ".mysql_error()."\n"); while($rswupin=mysql_fetch_object($resultwupin)){ $wupin_name=$rswupin->wupin_name; $wupin_time=$rswupin->wupin_time; $date_format=date("m/d",strtotime($wupin_time)); $wid=$rswupin->wid; echo '<tr><td height="25">  <font color="#333333">['.$rswupin->class_name.']</font> <a href="wupin.php?wid='.$wid.'" target="_blank"><font color="#333333">'.TrimChinese($wupin_name,"80").'</font></a> <font color="#666666"> ('.$date_format.') </font></td></tr>';}}
    4.1.2.3 主要窗口如下图:
    4.1.3 发布信息实现用户发布二手信息,建立一个简单易操作的信息发布平台。
    4.1.3.1 步骤:
    输入标题
    选择类别
    输入内容
    选择有效标志

    4.1.3.2 主要代码<?//处理内容提交if(($_GET["ac"]=="in")&&(isset($_POST["wupin_name"]))){ $wupin_name=$_POST["wupin_name"]; $class_name=$_POST["class_name"]; $wupin_nr=$_POST["wupin_nr"]; $wupin_img=$_POST["wupin_img"]; $user_name=$_POST["user_name"]; $wupin_time=$_POST["wupin_time"]; $wupin_guoqi=$_POST["wupin_guoqi"];//查询所属大类的id号$sqlbclass="select * from ershou_class where class_name='$class_name'"; $resultbclass=mysql_query($sqlbclass); while($infobclass=mysql_fetch_array($resultbclass)) { $class_cid=$infobclass["class_cid"];} //根据大类的id号 查询出大类名称 $sqlbclass1="select * from ershou_class where cid='$class_cid'"; $resultbclass1=mysql_query($sqlbclass1); while($infobclass1=mysql_fetch_array($resultbclass1)) { $bclass_name=$infobclass1["class_name"];} $sqlup = "INSERT INTO ershou_wupin SET bclass_name='$bclass_name',wupin_name='$wupin_name',class_name='$class_name',wupin_nr='$wupin_nr',user_name='$user_name',wupin_guoqi='$wupin_guoqi',wupin_time=NOW()"; if(@mysql_query($sqlup)) { msg("增加成功!","#ff0000"); echo '<meta http-equiv ="Refresh" content = "1 ; URL=wupin_manager.php">'; } else { echo"<p>Error: ".mysql_error()."</p>"; }}?>
    4.1.3.3 窗口如下图:
    4.1.4 密码找回实现找回密码,大意丢失密码的拥护根据所须填写注册时的问题答案,就能更改密码。
    4.1.4.1 步骤:
    填写用户名
    填写答案跟新密码
    提交密码

    4.1.4.2 主要代码如下:<? $user_name1=$_POST["user_name"];//前页隐藏表单提交过来的的当前用户名 $user_angser2=$_POST["user_angser"]; $user_name1=trim($user_name1); $user_angser2=trim($user_angser2); $user_angser1=md5_5($user_angser2);//填写的答案进行加密 以去和数据库的值对比 $user_pass2=$_POST["user_pass1"];//读取新密码 $user_pass2=trim($user_pass2); $user_pass1=md5_5($user_pass2);//加密 $sql="select * from ershou_user WHERE user_name='$user_name1'"; $result = mysql_query($sql) or die(mysql_errno().": ".mysql_error()."\n"); $rs=mysql_fetch_object($result); $user_angser=$rs->user_angser; if($user_angser!=$user_angser1){//数据库答案与输入的不相同 就提示 echo '<tr bgcolor="#f3f3f3"> <td height="50" align="center">答案错误!请<a href="user_repw.php"><font color="#ff0000">返回</font></a></td></tr>';}//输入的答案正确和输入了新密码就提交修改的用户密码 elseif($user_angser1==$user_angser) { $sqlup="UPDATE ershou_user SET user_pass='$user_pass1' where user_name='$user_name1'"; if(@mysql_query($sqlup)) { echo '<img src="images/success.gif" border="0" />'; msg("修改成功,返回登录","#ff0000"); echo '<meta http-equiv ="Refresh" content = "1 ; URL=user_login.php">'; } else { echo"<p>Error: ".mysql_error()."</p>"; } } ?>
    4.1.4.3 主要窗口如下:
    4.1.5 数据库连接代码<?######MySQL数据库信息######$DBhost = "localhost"; //主机名$DBuser = "root"; //用户名$DBpass = ""; //密码$DBname = "ershou"; //数据库名mysql_connect($DBhost,$DBuser,$DBpass) or die("无法连接到数据库!");mysql_query("SET NAMES GBK");mysql_select_db ($DBname);?>
    4.2 创建界面4.2.1首页:网站首页是用户进入系统的第一个界面,因此,简洁、友好、清晰醒目是设计时要考虑的风格。样式如图所示:

    4.2.2 管理员管理主界面:管理员输入正确地用户名和口令后,就可进入管理主界面。管理主界面是管理员维护网站使用的界面,因此要求简单明了,容易操作。样式如下图:

    5 系统测试5.1 本地服务器测试本系统是基于Windows平台,在PHP、MYSQL、Apache的环境下运行的;启动Apache应用服务器,打开Internet Explorer,在URL地址中输入 http://localhost ,即可打开系统首页。经过测试,本系统已经能够顺利完成系统要求的基本功能,达到预期目标。
    5.2 远程服务器测试在Linux、PHP、MYSQL、Apache的环境下;用户远程访问此系统,页面会出现乱码。就此问题经过如下分析,并给出解决方案:系统显示信息时出现了中文文字显示的问题。系统文件乱码的出现是由于编码(charset)设置错误,导致浏览器以错误的编码来解析。
    此系统测试时遇到的主要是数据库连接编码,指的是进行数据库操作时以哪种编码与数据库传输数据,由于Linux操作系统上数据库采用UTF8编码,而网页的页面申明编码是GB2312。这时候在PHP脚本里面直接SELECT数据出来的就是乱码,需要在查询前先使用:
    Mysql_query ("SET NAMES GBK");
    来设定MYSQL连接编码,保证页面申明编码与这里设定的连接编码一致(GBK是GB2312的扩展)。
    此问题解决后,继续测试系统。能够顺利完成系统要求的基本功能,系统在远程服务器上运行成功。
    2 评论 74 下载 2019-01-06 17:36:28 下载需要8点积分
  • 基于Jsp和Sql Server 2008实现的在线公益平台系统

    摘要随着全社会对环境保护、资源节约、弱势群体以及对生物多样性保护的关注度越来越高,各种公益组织和志愿者组织也越来越多。利用网络,不但可以更快更广地把公益组织传播给更多人知道,也可以通过网络在线捐助的方式奉献自己的爱心。在软件工程指导思想下,基于B/S构架、JAVA、JSP平台和SQL Server 2008数据库平台,为满足用户能在虚拟网络上快捷便利地进行捐助,以及在现实世界进行公益活动的真实体验的两种不同需求,设计了在线公益平台包含登录模块、个人信息管理员管理模块、同城活动管理模块、在线捐助模块,为用户在线报名参与公益活动带来了很大的便利,同时组织者也可以根据在线报名志愿者的资料,更好地组织管理志愿者活动。
    关键词:JSP;数据库;公益平台
    AbstractWith the whole society of environmental protection, resource conservation, vulnerable groups, as well as the protection of biological diversity of concern is getting higher and higher, a variety of public welfare organizations and volunteer organizations are also more and more. Using the network, not only can be faster and more widely spread to more people to know the public welfare organization, but also through the network online donation way to sacrifice their love. In the guidance of the software engineering, JAVA, B/S framework, JSP platform and SQL Server 2008 database based on the platform, to meet the user can be convenient to donate in the virtual network, and the public welfare activities in the real world the real experience of two kinds of demand, the design of the online public platform includes login module, personal information manager the management module and the activities of the city management module, online donation module, registration for online users to participate in public welfare activities to bring great convenience at the same time, the organizers can also according to the online registration volunteer information, better management of volunteer activities.
    Key words: JSP; database; public service platform
    引言中国正处于发展转型的关键时刻,发展公益也正契合当今时代国情的需求。公益的发展是在保护弱势群体,促进社会公平,缓和社会矛盾,有助于国家实现构建和谐社会的重要目标。在网络技术的推动下,互联网已渗透到政治、文化、经济、生活当中,公益活动借助网络媒体多渠道传播、信息强时效性、及时互动反馈登优势。本文基于此,设计在线公益平台,依托互联网,有助于发觉公众的善心,拉近人与人的距离使公益活动走上快速发展的道路。
    1 课题分析1.1 课题背景21世纪以来,网络社会的崛起转化了人类的社会生活图景。以信息技术为中心的技术革命,正在加速社会物质基础的重构。人们开始习惯穿梭于网络与现实的世界之中。互联网信息技术的日益普及,创造了新的信息传播形式和互动沟通方式,也催生了新的组织形态,它既塑造着生活,同时也为生活所塑造。
    网络时代的今天,互联网信息技术已经普遍渗透到了人类社会生活的全部领域,中国的公益领域也不例外。尽管在上世纪短短十年中,以“希望工程”为标甘志的中国公益事业取得了巨大的成功,但带有强烈的“官办”色彩强烈的“组织化公益”并非真正意义上或现代意义上的公益。在互联网技术力量的推动下,网络公益力量开始觉醒,并积极推动中国公益事业实现从传统向现代的转型。
    近年来,中国公益事业进入了高速发展时期,各类公益组织数量呈几何式增长,其中网络公益组织增速最快,据统计,截止2011年底,各类网络公益组织已经超过11万个。网络公益力量的迅速崛起,无形中敦促中国公益事业加快现代公益转型的脚步。追溯网络公益兴起的过程,不得不提到几个关键性的时间节点。2008年汉川地震,公众自发的善举通过互联网传向全国各地。正是互联网及时性的报道和跨时空式的信息传播,让人们感受到了一种前所未有的网络公益力量。2011年“微博公益”的出现更是推动了网络公益的发展,同时也揭露了现实世界中公益的阴暗面。河南宋庆龄基金会巨额劝募资金事件、红十字会郭美美事件等负面新闻在网络上频繁曝光,掀起了一股强有力的公益问责风暴。正所谓“祸兮福之所伏,福兮祸之所倚”。国内慈善公益机构频繁遭遇的公信力危机,洽恰成为了中国公益事业走向公开透明的关键转折点。现实的巨大压力与公众高昂的呼声,无疑都催促着中国社会急需一股透明、公开的力量来践行公益。同一年,“免费午餐”、“微博打拐”“大爱清尘”等网络公益项目突破了以往公益项目的运作模式,秉承公开透明、人人皆可参与的理念取得了巨大成功。在中国这个特定的环境下,网络被公众赋予了新的角色,它似乎成为公众了解、参与、监督公益事业,实现公益诉求,争取公民参与权和话语权的“唯一”途径[1]。
    对于网络公益力量的崛起,学界已有所关注。例如,北京师范大学中国公益研究院,其发布的《走向现代慈善一2011中国公益事业年度发展报告》对2011年中国公益慈善界的热点事件进行了分析,该报告认为互联网等新技术创新了公众慈善参与模式,促进、动员传统慈善走向现代“全民公益”慈善的转型。在长期对网络公益的关注下,笔者意识到在网络公益力量日益壮大的今天,给予网络公益项目更多的关注是十分必要的。虽然,学界己对其有所关注,但对网络公益的研究还比较零散,缺少更为深入、系统的实证研究。特别是针对网络公益项目的实证研究更是十分匾乏。尽管,网络公益己经在技术和制度的结合上做了大量的探索,但如何借助网络技术建立一套有效的动员参与机制、通过网络有效整合公益资源等问题都是网络公益有待深入研究的问题。
    1.1.1 国内研究概况国内研究来看,微信公益传播等在线公益平台尚属新兴的媒介现象,例如微信公益传播是公益在微信平台上的传播,既具有公益传播的特点也有微信传播的特点。在媒体与公益传播的研究中,许多学者着重梳理不同媒介形式对公益传播的影响。传统公益传播主要是借助报纸、电视等传统媒体进行公益传播,四川大学的王炎龙在《我国媒体公益传播研究分析》中,他通过描述报纸、广播、电视、新媒体在公益传播过程中的发展现状,归纳总结了公益在以传统媒体与新媒体为载体进行传播时所展现的特点。报媒凭借自身的号召力影响着公益发展趋势,广播的范围覆盖要求公益传播的内容必须多元化,多形态的传播形式对公益营销和价值塑造具有重要作用,新媒体的技术进步拓展了公益的传播渠道。网络公益传播是通过互联网平台进行公益传播。成都理工大学王颖的硕士论文《我国网络媒介中的公益传播现象研究》,概述了公益传播的四种类型,对网络公益传播的性质和内容进行了总结,分析了网络公益传播质效性、关联性、低成本性等传播特点,将网络公益传播与传统媒体的公益传播进行了对比分析,最后指出了网络媒介在传播上的劣势并提出了策划网络公益活动吸引网民参与等发展建议。
    在《网络公益慈善传播研究》中,王心论述了企业、公益慈善组织、网民、媒体作为传播主体的网络公益慈善传播,并根据这四个主体的传播特点提出了网络信息浅层化、个体传播差异化、公益资源不均等传播问题。在对企业公益行为的研究中,主要从公益营销的角度进行分析。王炎龙等人认为,企业通过投资公益活动、建立基金等方式开展公益营销,有助于企业承担应有的社会责任,树立良好的品牌形象,增强行业竞争力。
    1.1.2 国外研究概况国外对于公益组织的研究主要以不同国家、不同地区、不同领域的个案研究居多。日本早稻田大学的 Hiromitsu Kataoka (2007)研究了亚洲非盈利组织的电子化治理。他认为,非盈利组织的社会资本较为分散,如果想要获得更好的“协作性优势”,非盈利组织之间应该进行合作,通过电子化治理形成社会网络。社会网络不仅便于接收海外的捐赠,集中获得有效的社会资本,还能够建立信任关系,将捐赠交易过程变得更加透明化。以 WEB 2.0 为基础的网络平台结束了单相沟通,通过优化用户体验,提高互动频率,达到增加网站访问量的最终效果。显而易见,研究社交网络平台对于公益组织、企业、个人等公益发起人如何通过平台获得社会资源,赢得社会信任是至关重要的。
    国外对公益传播的研究也深于国内。以公益广告为例,美国的公益广告模式是由政府、企业、媒体、广告公司等多方共同参与运转的,明确了公益广告的四大责任主体:“美国广告理事会负责组织,企业负责捐款,广告公司负责制作,媒体负责发布。”鉴于美国的广告模式,英国、法国、日本等国也纷纷效仿,建立起了适合本国国情的公益广告模式。法国模式以慈善捐款为主,以提供人道援助宗旨,英国模式重视依托于企业的社会营销,日本则以广告评议会为核心,企业、广告公司、媒体也是公益广告的发布者。
    1.2 研究目的及意义互联网时代下我国公益传播迎来了新机遇、新挑战。微信微博等媒介平台的出现也让我们应该思考如何更有效地运用新媒体发展公益事业。公益发展与网络媒体的关系日趋紧密,研究分析在线公益传播的基本构型,进而设计开发便捷的在线公益平台,对传播模式进行归纳,总结应对策略,这对我国在线公益传播发展具有重要意义。
    从理论意义上讲,对在线公益系统性研究的论文目前较少,对公益传播的研究主要集中在传统公益传播的研究、非政府组织的传播研究现状等。对在线公益传播的研究主要是对在线公益的发展潜力、公益组织网络传播的策略研究。选取公益传播的网络视角,探讨在网络这种新媒介特质下,公益传播的基本模式、构型以及问题策略等,借助传播学理论分析在线公益案例不仅有利于丰富公益传播的基本理论,促进政府、公益组织、企业等传播主体利用网络平台进行公益传播,还有助于推进我国公益事业的发展。
    从现实意义上讲,随着互联网的发展,新媒体的技术进步正在改变中国公益发展的传统格局,传统的公益活动模式将被彻底颠覆。人们参与公益的热情与日俱增,对公益的关注愈发频繁,但公益的发展疏于漏洞面临着巨大的信任危机。近期,公益组织被质疑的事件比比皆是,2014 年 1 月 6日,周筱赟在网上举报,质疑李亚鹏发起的嫣然天使基金存黑幕,4 月 22 日,四月网发布微博质疑李连杰贪污壹基金芦山地震赈灾款,8 月 5 日,女演员袁立在微博中以捐款人身份对天使妈妈基金财务问题提出质疑,当“冰桶挑战”风靡微博时,渐冻人组织对瓷娃娃罕见病关爱中心的接受善款资格及善款使用方向提出质疑,这迫使公益组织必须转型。在线公益的研究与设计有助于让公益组织更好地转变社会角色,不再是公益活动的绝对领导者,而是要增加与公益参与者的互动,与公众共同见证公益活动的成果,调动团队的公益资源,接受群众的监督,重获公众对公益组织的信任[2]。
    1.3 本文所做工作本文数据库系统的相关理论用于实践,在系统开发需求分析的过程中,具体所做的工作有:

    在该系统的可行性分析和规划阶段,对于互联网在公益平台上的运用和发展背景做了简单的介绍,和实现系统的技术路线
    在该系统的需求分析和总体设计阶段,给出了系统实现的功能模块和基本构架
    在详细设计和具体实施阶段完成了对于在线公益平台的功能模块设计、功能设计、数据库设计,并完成实现了具体的功能

    2 技术路线及开发工具2.1 技术路线2.1.1 技术思路本系统设计了针对不同用户身份而专设的功能页面,完成其各自特有的功能。利用软件工程原理和结构化程序设计思想,基于Browser/Server软件体系构架,结合关系数据库平台、JAVA与JSP编程技术、Servlet、JAVA EE体系结构中的MVC模式,完成实现了整个系统。
    2.1.2 技术路线图
    2.2 开发技术及工具2.2.1 开发技术JAVA作为一种历史不长的计算机语言,由于其自身的特点,得到了众多开发者的青睐,在许多编程语言热门程度排行中都名列前茅。JAVA语言由于其简单性、网络特性、面向对象性、平台无关性、鲁棒性、安全性、多线程性、解释性等特点,适合于各种对于执行效率要求不是很高、很苛刻的应用[8] 。
    JSP采用JAVA作为脚本语言,在实际运行的时候被编译成为Servlet,这种优势使得JSP能够运行在所有类型的服务器上,面对不同的需求或者不同的软硬件开发环境,JSP都能够应对。JSP是从JAVA语言中产生出来的,其在很大程度上和JAVA 有相似之处[7]。
    JAVA EE就是为了解决“企业应用”方面的问题,将工作划分为不同的层次,包括如下三层:服务器端业务逻辑层、服务器端表示层、客户端表示层。JAVA EE的应用部署在JAVA EE服务器中,JAVA EE服务器支持Web组件以及三层构架,并使用标准的JAVA EE来处理不同事务[6]。

    所谓MVC模型就是将数据、逻辑处理、用户界面分离的一种方法。

    M(Model, 模型):用于数据处理、逻辑处理
    V(View,视图):用于显示用户界面
    C(Controller,控制器):根据客户端的请求控制逻辑走向和画面

    而在Java中,MVC这三个部分则分别对应于 JavaBeans、JSP和Servlet。

    M = JavaBeans(java类):用于传递数据,拥有与数据相关的逻辑处理
    V = JSP:从Model接收数据并生成HTML
    C = Servlet:接收HTTP请求并控制Model和View

    本系统的运行模式为B/S构架,所谓B/S构架(Browser/Server,浏览器/服务器模式)是Web技术兴起后的一种网络结构模式,Web浏览器如IE、Mozila FireFox、Chrome等是客户端最主要的应用软件[ 9]。这种模式统一了客户端,将系统的核心功能实现部分集中到了服务器上,简化了系统的开发、使用以及维护。在B/S模式中,浏览器以超文本形式向Web服务器提出访问数据库服务器,数据库服务器得到请求后,进行验证并处理,然后将处理后的结果返回给Web服务器,Web端再一次将得到的所有结果进行转化,换成HTML形式,转发给浏览器以页面的形式显示。
    所谓数据库,即就是数据存放的地方,需要长期存放在计算机内,有组织、可共享的数据集合。数据库中的数据按照一定的数据模型组织、存储和描述,具有较小的冗余度、较高的数据独立性和易扩展性,可以为不同的用户所共享。
    而数据库的内容通过数据库管理系统(Database Management System, DBMS)来管理。数据库管理系统是指数据库系统中对于数据进行管理的软件,它是数据库系统的核心组成部分,用户对数据库的一切操作,比如定义、查询、更新以及各种控制,都是通过数据库管理系统来操作的。
    关系数据库是由数据表和表之间的关联组成。其中的数据表通常是一个由列和行组成的二维表,每一个数据表分别说明数据库中某一个特定方面或部分的对象及其属性。数据表中的行通常叫做元祖,它代表众多具有相同属性的对象中的一个;数据库表中的列通常叫做属性,它代表相应数据库表中存储对象的共有属性。
    关系数据库由于其建立在严格的数学概念基础之上,概念单一,结构简单、清晰、用户易懂易用,存取路径等物理操作对用户透明等特点,成为当今的最主流数据库技术。
    2.2.2 开发工具本系统在Windows 7 操作系统上开发,Web服务器采用Apache Tomcat 7.0,数据库服务器采用了SQL Server 2008。
    由Microsoft公司发布的SQL Server 2008 产品是一个典型的关系型数据库管理系统,以其强大的功能,操作的简易、可靠的安全性,等到了众多用户的认可,应用也越来越广泛[5]。而最新发布的SQL Server 2008 ,在其前一版本SQL Server 2005的强大功能基础之上,为用户提供了一个完整的数据理论和分析解决方案[10]。
    Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。本系统的开发将使用Eclipse的neon版本。
    如果要运行JSP的话,还需要一个Servlet/JSP容器来支持它,当今流行的Servlet/JSP容器有Tomcat、WebLogic等[4]。Tomcat是一个免费开源的Web应用服务器,非常适合于在中小型和并发访问用户不是很多的场合使用,是开发和调试JSP程序的首要选择。Tomcat收到广大开发者的青睐,由于其运行时占用系统资源小,扩展性好,并且支持负载平衡和邮件服务等开发引用系统常用的功能[3]。
    3 功能分析与设计3.1 需求分析3.1.1 用户调研本系统中的用户角色可以分为普通用户、主办方用户、普通管理员、系统管理员。为了能更加清晰的体现各用户的不同功能权限,在实际开发以前针对各个角色都做了一定的相关资料收集,一定的考察,让系统的功能、环境等经可能的符合实际使用情况。
    3.1.2 初步设计根据用户对本系统在功能、性能、行为、设计约束等方面的要求,系统大体功能如下:

    三个角色分别登录,可以进入属于自己角色的特有的操作界面
    各个角色的用户登录了之后可以对自己的基本信息进行修改、查询
    添加、删除、修改各个角色的功能可以由管理员完成
    普通用户可以除了对自己的基本信息进行查询、修改意外,还可以进行在线捐助、参加同城活动等
    主办方登录之后可以对自己所管理的活动进行基本的查看、增加、修改的操作

    3.2 系统设计3.2.1 系统流程设计根据对需求分析阶段所得到的信息进行分析,将系统流程细化如图3-1:

    3.2.2 系统功能分析为了满足不同角色用户的需求,将本系统的用户角色分为管理员、普通用户、主办方三类角色,其各自具体功能如下:
    管理员管理员可以进行增加、删除普通用户和主办方。

    其中系统管理员除了可以进行增加、删除普通用户和主办方,还可以增加、删除普通管理员。

    普通用户
    查询、修改自己的基本信息
    查询活动信息以及自己参加的活动情况
    查询自己的在线捐助记录
    查询主办方信息
    在线捐款
    参加同城活动
    申请主办方


    主办方用户
    查询、修改自己的基本信息
    查询活动信息以及自己参加的活动情况
    查询自己的在线捐助记录
    查询主办方信息
    在线捐款
    接受在线捐助
    参加同城活动
    发起同城活动
    修改同城活动信息


    3.3 模块划分按照功能分析图将系统划分为如下几个模块:

    用户登录模块,身份验证,读取数据库中的用户信息,验证用户的登陆方式、用户名及密码,全部通过则进入系统,系统分为管理员和普通用户两个登陆页面
    个人信息管理模块,修改保存个人信息(面向前台用户),所有用户登陆后可以修改自己除用户名外的所有信息(包括密码),保存后更新
    管理员管理模块,该模块实现了对于三种角色的用户的管理
    同城活动管理模块,同城活动管理面向主办方,主办方登陆后可以对自己名下的同城活动进行管理。功能包括:创建同城活动,修改活动信息
    在线捐助模块,在线捐助面向前台用户,系统的所有前台用户登陆成功后,都可以通过系统提供的界面进行在线捐助

    3.4 系统总体设计在线捐助和同城活动系统的主要功能是为用户提供一个简单有效的公益社区,以便用户在网络上快速地对自己感兴趣地活动主办方进行资金方面地捐助,或者参与同城活动,进行实际的行为支持。同时主办方也可以根据在线报名志愿者的资料,更好地组织管理志愿者活动。
    系统的功能结构分为前台和后台两个部分:
    前台

    后台

    3.5 概念结构设计3.5.1 数据库设计
    users(UserID,UserMail,Password,UserName,Sex,Tel,City,UserCover)
    organizer (UserID, UserMail, UserName, Class, Tel, City, Number, AdminName, UserCover, Intro, Remark,)
    admin (UserName, Password, Role)
    donation (ID, DonorID, RecipientID, Amount, Time, DonorName, DonorTel, Remark)
    activity (ActID, OrgName, ActName, ActClass, StartTime, EndTime, Address, Intro, Cover)
    actMember (ActMemberID, ActName, UserMail, UserName)

    3.5.2 E-R图管理员实体E-R图

    普通客户实体E-R图

    主办方实体E-R图

    捐助记录实体E-R图

    同城活动实体E-R图

    活动成员实体E-R图

    系统总体E-R图

    3.6 系统核心功能设计3.6.1 核心功能顺序图UML通过视图化的表示机制从多个侧面对系统的分析和设计模型进行刻画,其中被广泛运用的顺序图是属于行为图的一种,强调了对象之间发生消息传递的时间顺序。
    系统整体数据流动的顺序图如图3-26:

    首先用户在JSP页面提交表单,数据被Servlet接收到,并根据用户提交表单的不同情况决定可能迁移到哪些不同的页面。紧接着将对应的提交数据作为参数传递给对应的DatabaseBean类,在DatabaseBean类中访问数据库并且进行相关的操作,然后在对应的页面空间设置下一个JSP页面显示需要的数据并且返回。在Servlet中根据DatabaseBean类的方法运行结果,判断应该如何进行页面迁移和显示结果。最后对应的JSP页面显示在用户的浏览器中。
    3.7 逻辑结构设计及物理设计3.7.1 数据库关系表admin(管理员表)


    序号
    字段
    别名
    数据类型
    数据长度

    是否可空




    1
    UserName
    用户名
    varchar
    50
    PK



    2
    Password
    密码
    varchar
    50




    3
    Role
    角色
    varchar
    50





    其创建代码如下:
    CREATE TABLE [dbo].[admin]( [UserName] [varchar](50) NOT NULL, [Password] [varchar](50) NOT NULL, [Role] [varchar](50) NOT NULL, CONSTRAINT [PK_admin] PRIMARY KEY CLUSTERED ([UserName] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
    users(用户表)


    序号
    字段
    别名
    数据类型
    数据长度

    是否可空




    1
    UserID
    用户序号
    int
    4
    PK



    2
    UserMail
    用户邮箱
    varchar
    50




    3
    Password
    密码
    varchar
    50




    4
    UserName
    用户名
    varchar
    50




    5
    Sex
    性别
    varchar
    50




    6
    Tel
    电话
    varchar
    50




    7
    City
    城市
    varchar
    50




    8
    UserCover
    用户头像
    varchar
    50





    CREATE TABLE [dbo].[users]( [UserID] [int] NOT NULL, [UserMail] [varchar](50) NOT NULL, [Password] [varchar](50) NOT NULL, [UserName] [varchar](50) NOT NULL, [Sex] [varchar](50) NOT NULL, [Tel] [varchar](50) NOT NULL, [City] [varchar](50) NOT NULL, [UserCover] [varchar](50) NULL, CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED ([UserID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
    organizer(主办方表)


    序号
    字段
    别名
    数据类型
    数据长度

    是否可空




    1
    UserID
    用户序号
    int
    4
    PK



    2
    UserMail
    用户邮箱
    varchar
    50




    3
    UserName
    用户名
    varchar
    50




    4
    Class
    类别
    varchar
    50




    5
    Tel
    电话
    varchar
    50




    6
    City
    城市
    varchar
    50




    7
    Number
    人数
    int
    4




    8
    AdminName
    管理用户
    varchar
    50




    9
    UserCover
    用户头像
    varchar
    50




    10
    Intro
    简介
    varchar
    50




    11
    Remark
    备注
    varchar
    50





    其创建代码如下:
    CREATE TABLE [dbo].[organizer]( [UserID] [int] NOT NULL, [UserMail] [varchar](50) NOT NULL, [UserName] [varchar](50) NOT NULL, [Class] [varchar](50) NOT NULL, [Tel] [varchar](50) NOT NULL, [City] [varchar](50) NOT NULL, [Number] [int] NULL, [AdminName] [varchar](50) NOT NULL, [UserCover] [varchar](50) NULL, [Intro] [varchar](2000) NOT NULL, [Remark] [varchar](2000) NULL, CONSTRAINT [PK_organizer_1] PRIMARY KEY CLUSTERED ([UserID] ASC)WITH(PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
    donation(捐助记录表)


    序号
    字段
    别名
    数据类型
    数据长度

    是否可空




    1
    ID
    序号
    int
    4
    PK



    2
    DonorID
    捐助者序号
    int
    4
    FK



    3
    RecipientID
    接收者序号
    int
    4
    FK



    4
    Amount
    金额
    int
    4




    5
    Time
    时间
    varchar
    50




    6
    DonorName
    捐助者姓名
    varchar
    50




    7
    DonorTel
    捐助者电话
    varchar
    50




    8
    Remark
    备注
    varchar
    100





    其创建代码如下:
    CREATE TABLE [dbo].[donation]( [ID] [int] NOT NULL, [DonorID] [int] NOT NULL, [RecipientID] [int] NOT NULL, [Amount] [int] NOT NULL, [Time] [varchar](50) NOT NULL, [DonorName] [varchar](50) NULL, [DonorTel] [varchar](50) NULL, [Remark] [varchar](100) NULL, CONSTRAINT [PK_donation] PRIMARY KEY CLUSTERED ( [ID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
    activity(活动信息表)


    序号
    字段
    别名
    数据类型
    数据长度

    是否可空




    1
    ActID
    活动序号
    int
    50
    PK



    2
    OrgName
    主办方
    varchar
    50




    3
    ActName
    活动名称
    varchar
    50




    4
    ActClass
    活动类型
    varchar
    50




    5
    StartTime
    开始时间
    varchar
    50




    6
    EndTime
    结束时间
    varchar
    50




    7
    Address
    地址
    varchar
    50




    8
    Intro
    简介
    varchar
    50




    9
    Cover
    头像
    varchar
    50





    其创建代码如下:
    CREATE TABLE [dbo].[activity]( [ActID] [int] NOT NULL, [OrgName] [varchar](50) NOT NULL, [ActName] [varchar](50) NOT NULL, [ActClass] [varchar](50) NOT NULL, [StartTime] [varchar](50) NOT NULL, [EndTime] [varchar](50) NOT NULL, [Address] [varchar](50) NOT NULL, [Intro] [varchar](50) NOT NULL, [Cover] [varchar](50) NULL, CONSTRAINT [PK_activity] PRIMARY KEY CLUSTERED ([ActID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
    actMember(活动成员信息表)


    序号
    字段
    别名
    数据类型
    数据长度

    是否可空




    1
    ActMemberID
    成员序列
    int
    4
    PK



    2
    ActName
    活动名称
    varchar
    50




    3
    UserMail
    用户邮箱
    varchar
    50




    4
    UserName
    用户姓名
    varchar
    50





    其创建代码如下:
    CREATE TABLE [dbo].[actMember]( [ActMemberID] [int] NOT NULL, [ActName] [varchar](50) NOT NULL, [UserMail] [varchar](50) NULL, [UserName] [varchar](50) NULL, CONSTRAINT [PK_actMember] PRIMARY KEY CLUSTERED ([ActMemberID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
    3.7.2 数据库关系图数据库个表之间的关系图如下:

    4 开发与实现4.1 系统核心程序编写4.1.1 Jsp+Servlet框架搭建MVC构架,它提供了一个控制器Servlet来处理页面导航。它的View层就是JSP;它的Contoller层是一个独立的Servlet类,叫做ActionServlet;它的Modole层包括了Form和Action的JAVA类。
    在本系统login.jsp文件中,通过<form action="servlet/login">,表格将这种请求提交给Servlet,由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。<servlet>元素用于注册Servlet,它包含有两个主要的子元素:<servlet-name>和<servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。 一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。例如注册模块的web.xml的配置:
    <?xml version="1.0" encoding="UTF-8"?><web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>login</servlet-name> <servlet-class>client.login</servlet-class> </servlet> <servlet-mapping> <servlet-name>login</servlet-name> <url-pattern>/servlet/login</url-pattern> </servlet-mapping></web-app>
    配置好web.xml文件后,编写用于执行的login.java类,调用DB,java类的相关连接数据库,登录验证的函数,将login,jsp的页面传送过来的参数,通过login.java来进行判断验证和页面跳转控制[9]。
    4.1.2 访问数据库DB公共类编写DB,java类作为整个系统连接数据库,操纵数据库的所有方法所在的公共类,其包含了包括各个角色登录验证方法,各个角色和产品的操作、各个角色对于各自相关操作的所有方法,其核心代码如下:
    package client;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class DB { public DB() { super(); } public ResultSet select(String sql) { String url="jdbc:sqlserver://localhost:1433;DatabaseName=GY"; String userName="sa"; String password="sa"; Connection conn=null; Statement stmt=null; ResultSet rs=null; try{Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");} catch(ClassNotFoundException e){System.err.print("连接数据库失败");} try {System.out.println("lianjiechengg"); conn=DriverManager.getConnection(url,userName,password); stmt = conn.createStatement(); rs=stmt.executeQuery(sql); //// //rs.next(); ///// return rs; }catch(SQLException e){System.out.println("查询失败");} return rs; } public void insert(String sql) { String url="jdbc:sqlserver://localhost:1433;DatabaseName=GY"; String userName="sa"; String password="sa"; Connection conn=null; Statement stmt=null; try{Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");} catch(ClassNotFoundException e){System.err.print("连接数据库失败");} try { conn=DriverManager.getConnection(url,userName,password); stmt = conn.createStatement(); stmt.executeUpdate(sql); conn.close(); }catch(SQLException e){System.out.println("插入失败");} } public void update(String sql) { String url="jdbc:sqlserver://localhost:1433;DatabaseName=GY"; String userName="sa"; String password="sa"; Connection conn=null; Statement stmt=null; try{Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");} catch(ClassNotFoundException e){System.err.print("连接数据库失败");} try { conn=DriverManager.getConnection(url,userName,password); stmt = conn.createStatement(); stmt.executeUpdate(sql); conn.close(); }catch(SQLException e){System.out.println("修改失败");} } public void delete(String sql) { String url="jdbc:sqlserver://localhost:1433;DatabaseName=GY"; String userName="sa"; String password="sa"; Connection conn=null; Statement stmt=null; try{Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");} catch(ClassNotFoundException e){System.err.print("连接数据库失败");} try { conn=DriverManager.getConnection(url,userName,password); stmt = conn.createStatement(); stmt.executeUpdate(sql); conn.close(); }catch(SQLException e){System.out.println("删除失败");} }}
    4.2 系统实施4.2.1 面向管理员功能面向管理员的主页具备如下的功能:

    查询、修改自己的基本信息
    添加、删除、修改普通用户、主办方
    其中系统管理员还可以添加、删除普通管理员

    实际效果如下:

    4.2.2 面向普通用户功能面向普通客户的主页具备如下的功能:

    查询、修改自己的基本信息
    查询活动信息以及自己参加的活动情况
    查询自己的在线捐助记录
    查询主办方信息
    在线捐款
    参加同城活动
    申请主办方

    实际效果如下:

    4.2.3 面向主办方功能面向销售人员的主页具备如下的功能:

    查询、修改自己的基本信息
    查询活动信息以及自己参加的活动情况
    查询自己的在线捐助记录
    查询主办方信息
    在线捐款
    接受在线捐助
    参加同城活动
    发起同城活动
    修改同城活动信息

    实际效果如下:


    5 系统测试与应用5.1 系统测试运行环境系统运行环境有服务器端、因特网、客户端即浏览器构成。
    5.1.1 服务器端运行环境服务器端应由Web服务器、应用程序服务器、数据库服务器等组成。
    服务器运行环境基本要求:操作系统至少为Windows XP及其以上,数据库服务器为SQL Server 2008,安装有Tomcat 7.X及其以上版本、Eclipse neon版本。
    5.1.2 客户端(浏览器)运行环境系统能够用于访问各类Internet的计算机,只要计算机能够支持TCP/IP协议,操作系统为Windows XP及其以上,浏览器为IE、Chrome等都可。
    5.2 数据库测试与运行5.2.1 管理员管理功能测试管理人员进入自己的界面,对其余各个角色的人员进行相应的操作,如下图所示:

    5.2.2 主办方管理功能测试主办方进入自己的界面,对其余各个角色的人员进行相应的操作,如下图所示:

    5.2.3 用户在线捐助功能测试普通客户进入自己的界面,对其余各个角色的人员进行相应的操作,如下图所示:

    5.2.4 用户参加同城活动功能测试客服人员进入自己的界面,查看自己的收件箱并进行相应的操作,如下图所示:

    6 总结与展望6.1 总结随着全社会对环境保护、资源节约、弱势群体以及对生物多样性保护的关注度越来越高,各种公益组织和志愿者组织也越来越多。利用网络,不但可以更快更广地把公益组织传播给更多人知道,也可以通过网络在线捐助的方式奉献自己的爱心。为满足用户能在虚拟网络上快捷便利地进行捐助,以及在现实世界进行公益活动的真实体验的两种不同需求,设计该系统的核心功能有:

    用户登录:身份验证,读取数据库中的用户信息,验证用户的登陆方式、用户名及密码,全部通过则进入系统,系统分为管理员和普通用户两个登陆页面
    个人信息管理:修改保存个人信息(面向前台用户),所有用户登陆后可以修改自己除用户名外的所有信息(包括密码),保存后更新
    用户管理:普通会员管理面向管理员,管理员可以在后台系统界面中对普通会员进行添加、查看和删除操作
    主办方管理:主办方管理面向管理员,一般管理员可以在后台系统界面中对主办方进行添加、查看、删除操作
    系统管理员管理:管理员管理面向系统管理员,系统管理员可以对一般管理员的信息进行添加、修改密码、删除操作
    同城活动管理功能:同城活动管理面向主办方,主办方登陆后可以对自己名下的同城活动进行管理。功能包括:创建同城活动,修改、活动信息
    在线捐助功能:在线捐助面向前台用户,系统的所有前台用户登陆成功后,都可以通过系统提供的界面进行在线捐助

    目前,本系统的大体核心功能都基本实现,但是整个系统的应用上来说还是有很多的不足。
    通过对本课题的研究以及原型系统的设计与开发,在进一步巩固我计算机专业的同时也大大的提高了软件的开发与实践的能力。在开发实践的过程中,也让我对JAVA、JSP、SQL Server 、Tomcat、等软系统件开发所涉及的环境、平台、工具等有了根深一步的认识。也让我认识到,要做出一个出色的管理系统软件,不仅仅要进行严谨的调研考察,做出准确的需求分析,而且在设计开发的过程中也要遵守标准的开发方法,才可以开发出优秀的系统软件。
    6.2 展望如今,随着全社会对环境保护、资源节约、弱势群体以及对生物多样性保护的关注度越来越高,各种公益组织和志愿者组织也越来越多。利用网络,不但可以更快更广地把公益组织传播给更多人知道,也可以通过网络在线捐助的方式奉献自己的爱心。本小组设计的在线公益平台满足用户能在虚拟网络上快捷便利地进行捐助,以及在现实世界进行公益活动的真实体验的两种不同需求,同时我们还对机构进行个性化的分类,并提供机构所开展项目的详细介绍。用户可以便利地进行在线报名参与公益活动,组织者也可以根据在线报名志愿者的资料,更好地组织管理志愿者活动。在这个快节奏的生活之中,快捷便利的在线参与慈善事业,减少了传统过于复杂的捐款流程以及一些捐助过程中的不透明现象,如此高效的公益活动参与系统,符合自身利益,是未来公益事业筹募的发展方向。
    参考文献[1] 胡少雄,基于微信平台的公益传播研究[D].内蒙古:内蒙古师范大学,2015:4-6
    [2] 王颖,我国网络媒介中的公益传播现象研究[D].成都:成都理工大学,2010:6-8
    [3] 李建刚,秦兴桥,郑雨贝. JSP网络编程技术与实践[M].北京:清华大学出版社,2008:10-112
    [4]沈应逵,曾凌.Java Web数据库系统应用开发与实践[M].北京:人民邮电出版社,2008:390-404
    [5] 崔群法,祝红涛,赵喜来. SQL Server 2008 从入门到精通[M].北京:电子工业出版社,2009:203-244
    [6] 刘乃丽.精通Java EE项目案列—基于Eclipse、Spring、Struts、Hibernate[M]. 北京:人民邮电出版社,2008:155-237
    [7] 王萍萍,崔红义,孙强. JavaScript应用开发技术详解[M].北京:科学出版社,2008:20-53
    [8] Copeland. L.Covisint technology partners sign equity agreements [J]. Computerworld, 2001(35): 30-31
    [9] Hayes. F. Counting Casualtie [J].Computerworld, 2001, 35(25): 62-66
    [10] Disabatino. J. From Fee to Free To Fee Again: Britannica.com Restructures [J].Computeeworld, 2001, 35(12): 16-18
    1 评论 3 下载 2020-05-02 12:16:44 下载需要18点积分
  • 基于Python的TCP和UDP数据流的带宽竞争分析

    第1章 绪论1.1 题目来源本课题来源于计算机网络实践与应用课程的创新型实验,题目为“TCP和UDP数据流的带宽竞争分析”。实验的主要目的是通过编程实现多进程TCP和UDP数据传输模块,编写相关的TCP/UDP流利用带宽测量软件,设计实验,让多个TCP和UDP流竞争有限带宽,分析结果,进而掌握TCP和UDP流传输的特点,了解工作原理和工作过程,并通过测试验证其竞争机制。
    1.2 项目意义在实际应用中,一个端设备往往同时存在多个TCP和UDP的连接。通过此项目,我们可以了解多连接情况下TCP和UDP的运行性能与特点,从而在实际的应用中合理分配混合数据流的TCP和UDP的连接数,从而提高数据流的传输性能,充分利用有限的带宽,提高传输效率。
    1.3 项目创新分析该项目通过实现编程代码来进行TCP和UDP的传输和监听,创新性地将TCP和UDP的相关内容特点与现实问题(有限带宽竞争)相联系,可以让我们从新的角度理解课程中以及书本上的TCP和UDP的特点,增强了我们用实践来检验理论知识的创新意识。
    第2章 与项目相关的主要技术及其分析2.1 socket编程(python)Socket套接字是网络通信过程中端点的抽象表示,是程序进行网络通信的基础,使应用层能使用传输层提供的服务(TCP和UDP),进而实现TCP和UDP的数据传输模块。
    本次实验中,我们使用python中的socket包,分别在client和server中将socket与IP地址和端口号建立对应关系,进而实现TCP和UDP的发送和监听。
    2.2 多线程技术多线程技术建立多个线程来收发数据,可以用来同时建立多个连接,进而可以在一个程序中进行TCP和UDP的同时收发,进而实现可控的连接数对网络带宽的竞争。
    使用python中的threading包来实现函数在多个线程的同时运行。
    2.3 流量的实时计算与可视化(python)通过调用pyshark(基于wireshark的Python库)来进行实时捕获,分析每秒内不同目的端口接收的TCP和UDP数据包,计算流量。
    使用python中的matplotlib来实时绘制TCP和UDP的流量曲线图,从而进行流量的可视化,体现TCP和UDP的竞争关系。
    2.4 GUI编程(python)Tkinter 是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序,从而使整个操作过程直接明了,易于控制。
    第3章 混合数据流带宽竞争分析实现3.1 实验方案用python实现客户端与服务器端的应用程序client.py与server.py,以及在服务器端运行的流量监听工具Monitor.py。
    使用两台计算机设备,分别作为服务器端和客户端。
    先在服务器端运行程序Server.exe(生成的可执行文件)与Monitor.py,再在客户端指定服务器IP地址与要发送的文件,进行多种情况下的TCP和UDP的竞争传输,在服务器端查看传输过程以及monitor的流量图像。
    3.2 客户端程序的实现用来向服务器指定端口发送数据包,TCP的目的端口是10241,UDP的目的端口是10240。

    TCP套接字connect服务器的10241端口,建立连接,再从本地读取文件,发送文件大小后,再发送数据包(分组大小设置为BATCH_SIZE),在发送数据的同时打印已发送数据的大小
    UDP进行无连接传输,直接向服务器的10240端口发送文件(如果先发送文件大小, 可能丢包)
    为TCP和UDP传输分别启用一个线程,用户自行选择传输方式(只进行TCP传输,只进行UDP传输,两者同时进行)

    运行效果

    3.3 服务器端程序的实现3.3.1 服务器端程序Server.py用来接收数据包,在10240接收UDP数据包,在10241接收TCP数据包。

    同样启用两个线程,设置两个socket分别绑定10240和10241,用来接收数据,使用listen方法进行监听,并将接受的数据包写入指定文件中
    TCP连接能先获知接受数据的大小

    实现效果

    3.3.2 流量计算工具Monitor.py通过调用pyshark(基于wireshark的Python库)进行实时捕获 ,分析每秒内目的端口为10240的UDP数据包和10241的TCP数据包,计算流量,使用matplotlib实时绘制TCP和UDP流量曲线图。
    3.4 带宽竞争的实现按照3.1中的实验方案进行操作,Client端要发送大量数据来竞争带宽,因此在操作过程中选择一个较大的文件进行TCP和UDP的传输,确保达到有限带宽内的竞争。
    第4章 项目测试4.1 测试方案
    基本操作过程按照3.1实验方案进行
    TCP和UDP同时启动时,进行实验,观察流量监听界面,进行分析
    TCP先启动时,UDP后启动时,进行实验分析
    UDP先启动时,TCP后启动时,进行实验分析

    4.2 测试结果TCP和UDP同时启动时,流量监听界面如下
    g)
    发现在同时启动的情况下,TCP传输相对于UDP传输有一个滞后的过程,UDP发送很多数据后TCP才会进行发送。TCP是面向连接的传输层服务,开始时需要建立连接(三次握手),而UDP是无连接的,直接进行数据的发送。因此会出现这种现象。
    TCP先启动时,UDP后启动时,流量监听界面如下


    UDP先启动时,TCP后启动时,流量监听界面如下


    经过以上监测到的竞争过程,我们可以发现:
    在TCP和UDP竞争中,UDP会占用更多的带宽。(还可能出现UDP完全压制TCP传输的现象,如下图所示)只有在UDP传输完成后,TCP才能恢复到较高的速率进行传输。

    第5章 结论在测试中,带宽占用率过高时,TCP和UDP竞争中,由于二者对网络拥塞的反应是不同的。TCP具有拥塞控制机制,对拥塞的处理是降低自身的传输速率,从而避免丢包的发生。而UDP缺少端到端的拥塞控制,进而在链路带宽的占用上处于优势,但会丢失一些数据包,其传输是不可靠的。
    竞争会使TCP流得不到公平的带宽,因此应当探索一种机制,来处理TCP和UDP的竞争过程。
    1 评论 9 下载 2019-10-22 13:18:16 下载需要13点积分
  • 基于遗传算法和大津阈值分割法实现的图像分割

    一、简述本实验采用遗传算法和大津阈值分割法确定图像分割的最佳阈值,从而对图像进行二值化分割。
    二、大津阈值分割法在计算机视觉和图像处理中,大津二值化法用来自动对基于聚类的图像进行二值化。或者说,将一个灰度图像退化为二值图像。
    算法假定该图像根据双模直方图(前景像素和背景像素)把包含两类像素,于是它要计算能将两类分开的最佳阈值,使得它们的类内方差最小;由于两两平方距离恒定,所以即它们的类间方差最大。因此,大津二值化法粗略的来说就是一维Fisher判别分析的离散化模拟。
    三、遗传算法遗传算法(英语:genetic algorithm (GA) )是计算数学中用于解决最佳化的搜索算法,是进化算法的一种。进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择以及杂交等。
    遗传算法通常实现方式为一种计算机模拟。对于一个最优化问题,一定数量的候选解(称为个体)可抽象表示为染色体,使种群向更好的解进化。传统上,解用二进制表示(即0和1的串),但也可以用其他表示方法。进化从完全随机个体的种群开始,之后一代一代发生。在每一代中评价整个种群的适应度,从当前种群中随机地选择多个个体(基于它们的适应度),通过自然选择和突变产生新的生命种群,该种群在算法的下一次迭代中成为当前种群。
    3.1 算法
    选择初始生命种群
    循环
    评价种群中的个体适应度
    以比例原则(分数高的挑中机率也较高)选择产生下一个种群(轮盘法(roulette wheel selection)、竞争法(tournament selection)及等级轮盘法(Rank Based Wheel Selection))。不仅仅挑分数最高的的原因是这么做可能收敛到局部的最佳点,而非整体的
    改变该种群(交叉和变异)
    直到停止循环的条件满足

    最简单的遗传算法将染色体表示为一个数位串,数值变量也可以表示成整数,或者实数(浮点数)。算法中的杂交和突变都是在字节串上进行的,所以所谓的整数或者实数表示也一定要转化为数位形式。例如一个变量的形式是实数,其范围是0~1,而要求的精度是0.001,那么可以用10个数位表示:0000000000表示0,1111111111表示1。那么0110001110就代表0.398。
    在遗传算法里,精英选择是一种非常成功的产生新个体的策略,它是把最好的若干个个体作为精英直接带入下一代个体中,而不经过任何改变。
    通过并行计算实现遗传算法一般有两种,一种是所谓粗糙并行遗传算法,即一个计算单元包含一个种群;而另一种是所谓精细并行遗传算法,每一个计算单元处理一个染色体个体。
    遗传算法有时候还引入其他变量,例如在实时优化问题中,可以在适应度函数中引入时间相关性和干扰。
    四、实验思路4.1 大致思路
    计算待分割图像的图像灰度直方图
    对图像的灰度值进行编码,随机产生M个初始种群
    根据OTSU算法计算每个个体的适应度值
    建立种群,进行一定数量的遗传操作, 包括顺次执行的选择操作、 交叉操作和变异操作
    选择操作(自然选择)
    将当代种群中的个体按照适应度值由大到小选择前M个个体,将他们复制到下一代种群中。同时使用随机的方式,保留一定比例落后的个体,让其存活,将他们复制到下一代种群中
    交叉操作(繁殖)随机选出父体和母体,进行交叉操作,类比染色体的交叉,随机选择交叉点。交叉完成的新个体补充到下一代种群中,直到种群数量足够为止
    变异操作(基因变异)将上述交叉操作产生的种群中的个体的变异率P进行变化,如某一个体的某一个基因进行突变
    进行多次迭代,直到种群进化了一定数量的代数以后,选择其最优先的个体
    优秀个体转换成分割阈值,处理图像,显示效果

    4.2 编码思考如何建立灰度图和染色体的联系?
    灰度图中,每个像素点的灰度值从0到256,二进制是8比特位,我将八个比特位看成一个染色体,每一个比特位就是一个基因点。
    如何考虑选择下一代种群?
    首先先把种群中的每一个个体计算适应度,借助OTSU算法,可以得出类内方差最小的值,通过此得出适应度,适应度的大小即可表示个体的优劣程度。但不能只选出色的个体,有些不好的个体可能会产生优质的下一代个体,因此在选择的时候,考虑首先选择前百分比a的优秀个体,剩下的个体中,随机选取比例b的个体幸存,其余淘汰。
    如何考虑变异?
    考虑到真实的环境中变异的可能性比较小,所以设定了一个变异的概率来控制变异的可能性,同时保证每个基因变异的可能性是一样的,这里也结合考虑过结合阈值来说的话,变异高位就可能导致相差太大,但最后的实验结果是没什么差别,反而对所有基因一视同仁思路更加简单。
    五、实验结果原图与结果图对比

    2 评论 29 下载 2019-05-25 16:36:13 下载需要11点积分
  • 基于QT实现的植物大战僵尸闯关游戏

    一、本游戏的简介1.1 游戏简单的说明本游戏满足本课程大作业的所有基本要求,并且额外编写了一些特殊的功能,包括在植物方面设计编写了双发射手,机枪射手与樱桃炸弹,在僵尸方面除了撑杆跳僵尸与铁桶僵尸还编写了报纸老人僵尸这个新的僵尸。在特殊的UI设计上,还设计了原作中的小车(除草机)。在其他新奇的设计上,本游戏在战斗开始时会播放原作的背景音乐,在樱桃炸弹爆炸后会放出爆炸的声响,在撑杆跳僵尸跳跃式会发出蹦跳的声音,在报纸僵尸咆哮时会发出特殊的声音。在从卡片中选取植物时,鼠标把植物拽出时,会有一个植物的阴影显示在植物应该放在的位置上。另外要申明一点,由于大作业汇报时间紧迫,我的冷却条是关闭的,但是本游戏是有冷却条效果的,希望助教您能够了解。
    1.2 游戏架构的说明
    注释:图中的箭头有包含之一。game_window为qt提供的主类,其中game_view的实例对象client为 game_window类的成员。而game_view类的成员对象包含除了主类与自身以外的所有类。
    gamePlant, gameWeapon, gameSlot, gameZombie, gameCar与gameSun 这些类均继承于game_player头文件的gamePlayer类。gameLawn负责记录草坪各块地方植物的放置情况。以下为各类的介绍:

    gamePlant:代表各色植物的类,用来构建植物,其中含有多个布尔型变量来控制植物gif的切换,各种植物在构造函数中发出的信号不同,在timeEvent中的坐标变换与gif切换也不同。在构造函数中相应的植物会发出不同的信号,向日葵会发出需求阳光的信号,射手会发出需求弹药的信号。
    gameZombie:代表各种僵尸类,用来构建僵尸,其中含有多个布尔型变量来控制僵尸gif的切换,各种僵尸在构造函数中发出的信号不同,在timeEvent中的坐标变换与gif切换也不同。
    gameSun:代表阳光类,用来构建阳光。设置了一个布尔变量,来判断阳光是植物生产的还是屏幕生成的。在该类中mousePressEvent函数被重载来实现点击阳光阳光消失,阳光值增加25的功能。
    gameWeapon:代表子弹类,用来构建子弹。
    gameSlot:用来构建游戏卡片与,卡槽,铲子的类,该类的成员变量中设置一int型来判断是什么类型。值大于0为植物的卡片,值为-1的为卡槽,值为-2的为铲子。该类重载了mouseReleaseEvent与mouseMoveEvent两个函数。当鼠标触碰植物卡片时,会有一个植物随着鼠标移动(但是操作要注意的是鼠标左键一定要一直按下),只有当鼠标在草坪正确位置放下时才会产生植物。而铲子则与卡牌不一样,鼠标点击它图标的中间后,不用鼠标一直按着,铲子会自动跟随,点击右键铲子回到卡槽,选择植物后点击即可铲除。
    gameButton:游戏开始界面的按钮,重载了mousePressEvent与mouseReleaseEvent和mouseMoveEvent,鼠标放在其上会变色,点击后进入战斗界面。
    gameEnd:游戏的退出按钮,重载了mousePressEvent与mouseReleaseEvent和mouseMoveEvent,鼠标放在其上会变色,点击后进入游戏结束界面。
    gameCar:负责游戏的小车构建。
    gameScreen:负责游戏的各种场景构建与开始动画的产生。
    game_view: 是整个游戏的核心类,它负责把各种植物僵尸与物品加入场景中。并且监视着整个游戏的进程。

    下面介绍game_view的主要槽函数:
    void move_to_screen():用来进入战斗场景void createBullet(int ):用来生成子弹void createBomb(int ):用来生成樱桃炸弹的伤害void createMoreBullet(int ):机枪射手生成子弹void makeCard(int ):用来生成新的植物void createSun(int, gamePlant*):用来生成太阳void damageVector(gamePlant*):用来从植物的QVector中删除已死的植物void damageVector1(gameZombie*):用来从僵尸的QVector中删除已死的僵尸void showSun(gameSun*):点击阳光使得阳光消失
    1.3 游戏逻辑设计说明为了实现程序良好的封装性,本程序在game_window只是实现了一个继承于QGraphicsView的类game_view的实例化对象client的生成,以及client相应成员之间信号的连接。本程序主要的内容都是写在game_view这个类中,它负责把各种物品音效与动画加载到场景中。下面我们来一一说明。当点击游戏的开始按钮时,gameButton类会发射信号,然后game_view类会设置一个槽函数:move_to_screen(),这个槽函数会加载新的战斗场景,而信号与槽的连接是在game_window的构造函数中实现的。
    在move_to_screen()的函数中每隔20毫秒会发送信号,在game_view类的timeEvent函数接收信号后程序会自动在场景上生成僵尸。僵尸,植物与子弹都用QVector来储存,在timeEvent中会进行一个二重for循环让僵尸判断是否与子弹和植物“相遇”,如果僵尸或者植物死亡,它们各自的QVector会把他们清理掉。当鼠标点击卡片时,卡片类gameSlot会发出信号,然后在game_view中设置一槽函数make_card(int),在这个函数中会响应gameSlot发出的鼠标移动与鼠标释放的信号生成新的植物,然后信号的连接也是在game_window的构造函数中完成的。当植物需要阳光或者子弹的时候,在make_card()函数新生成植物的同时也会在植物类中发出相应的信号,game_view类中有相应的槽函数,信号的连接是在make_card()函数中,同理铲子的功能实现也是如此。另外gameLawn这个类利用不同的数组来记录新生成植物的横纵坐标与植物在草坪的放置情况,我们把其数组相应的下标传入僵尸与植物,阳光与子弹类的相应参数中然后利用connect信号槽把相应的数据传到game_view中生成相应的东西。
    对于植物和僵尸的类,是通过它们的虚拟基类gamePlayer的枚举型参数type来决定植物与僵尸的种类,这样就实现了一个构造函数通过调整一个参数的不同值来生成不同的植物与僵尸。
    二、本游戏界面UI设计首先本游戏为无尽模式,僵尸数目是无限的,所以没有植物的胜利条件,但是当僵尸成功走到屏幕最左端时僵尸获得胜利出现胜利界面。本游戏开始时有一个开始界面,界面上又开始游戏按钮,把鼠标光标放在按钮所在区域,按钮会变色。

    点击按钮,游戏进入对战界面。然后会出现开场动画与音乐,提示玩家安放植物和僵尸的即将入侵。屏幕还有滚动条方便玩家在另一侧看僵尸的行踪。屏幕上有退出按钮。

    当点击卡片的时候会产冷却条,只有冷却条结束且有足够阳光才可再点击。当拖拽植物时植物会随鼠标移动一个植物阴影会产生在植物应该放置的正确位置上。(植物不可在同一位置重复放置,且点击卡片的时候最好点击卡片部分而不是卡片的植物形象部分)如图。

    对战界面满足作业的要求,有植物的卡片,放置卡片的卡槽,铲植物的铲子,还有阳光值得显示与放置植物和僵尸移动的草坪,草坪前端还有原作中的小车。当僵尸获得胜利时,会出现这样的界面。此时游戏结束,按下窗口右上角的叉号即可关闭程序。

    在游戏过程中,如果点下退出按钮,程序会转换为这个界面。

    此时已宣告玩家不再进行游戏,按下开始按钮也不再会有效用,玩家关闭整个窗口即可。
    三、植物角色与阳光的设计本游戏含有六种植物,包括向日葵,豌豆射手,坚果,双发豌豆射手,机枪射手与樱桃炸弹。向日葵与豌豆射手,双发豌豆射手和机枪射手的生命值都为100,坚果墙的生命值为400,豌豆射手类的植物他们的射程范围都是只能达到横坐标1000以内的僵尸,每发子弹。

    以上的这张图含有六种植物的五种向日葵,坚果,豌豆射手,双发射手与机枪射手。向日葵会每隔一段时间生产出阳光,屏幕上每隔一段时间也会落下一个阳光,点击阳光后阳光消失,阳光值会增加二十五。当僵尸达到植物的攻击范围时会发出子弹,每发子弹造成数值为5的伤害。

    双发射手一次发两法豌豆子弹伤害值为10,豌豆射手一次发一发伤害值为5,机枪射手一次发五法伤害值为25。关于子弹与植物的联系,下面我要详细介绍。
    在本游戏的框架中有一个类似中枢作用的类game_view,它属于game_controller.h这个头文件。这个类包含了主要的三个QVector分别存放所有的非樱桃炸弹的植物,所有僵尸,和所有子弹。每颗子弹都是由特定的子弹生成,在本程序中子弹的坐标完全由发射它的植物决定,植物发射子弹需求信号的频率决定了子弹发射的频率。

    下面我们来介绍坚果墙,坚果墙可以阻止非撑杆跳僵尸的移动(撑杆跳僵尸可以有一次跳过植物继续移动的机会)。当坚果墙的生命值低于原有的三分之二时,它的一部分变得残破如图。当它的血量不到原来的三分之一时,坚果的缺损程度会更大。
    樱桃炸弹是本游戏另一种特殊的植物,它只要放上去就会爆炸,爆炸后会在地面产生一个难以消去的大坑,在爆炸范围内的僵尸死亡动画则是灰飞烟灭。它相较于其他植物而言,特殊之处在于它攻击范围大威力大,但是在游戏的设定中它对撑杆跳僵尸威力较小(因为撑杆跳僵尸移动较快)。
    阳光与子弹的设计相似,它的来源有两方面,一方面是向日葵每隔一段时间生成的,另一方面是从屏幕上每隔一段时间落下的阳光。阳光点击即可得到25阳光值。向日葵生成阳光的设计与豌豆射手发射子弹的设计是相似的,每隔一段时间向日葵发出产生阳光的需求,然后在scene上产生阳光。从屏幕上掉落的阳光,是战斗的scene每隔10秒发送一个startTimer(10000)需求信号,然后中枢类的 timeEvent生成阳光。
    四、僵尸的设计本游戏设计了四种僵尸,三种特殊的僵尸,包括撑杆跳僵尸,铁桶僵尸。铁桶僵尸生命值为50速度为3,,报纸老人僵尸生命值为80速度为3,普通僵尸的生命值为25速度为3,撑杆僵尸生命值为100.速度为10,撑杆僵尸跑的比其他僵尸都快。普通僵尸的被子弹打死的死亡动画为头被打掉了的gif,被樱桃炸弹炸死的动画为化为灰烬的gif。铁桶僵尸当生命值为20以上时是带着头盔的,生命值大于0但是小于20时铁桶僵尸失去头盔。

    注:此时铁桶僵尸并未失去头盔。

    注:此时铁桶僵尸失去头盔。铁桶僵尸的死亡动画适合普通僵尸是一致的。
    然后我们来介绍撑杆跳僵尸,当它拿着撑杆时它是可以遇到植物做撑杆跳的,并且樱桃炸弹炸不死它。它跳跃后他就和其它僵尸移动速度差不多了,攻击特性也和其他的一样。撑杆跳僵尸一跳可以越过一格,但是它还是有一个致命的弱点,由于它运动员的身高过于高,它可以在奔跑与跳跃的过程中被相邻行的植物射手攻击到,所以克服这种僵尸的具体策略就是在它所在行放置两个土豆将它围困在其中,在相邻行设置射手攻击起跳或奔跑时的撑杆僵尸。
    我们再来介绍报纸老头僵尸,这类僵尸的防御力比较强(因为拿着报纸),它分为三种状态。当它的生命值大于40时,它的形象是拿着报纸的老头僵尸,当它的生命值在30到40之间时它是一个带着问号的僵尸形象,报纸被击落。当它的生命值小于30时,它的形象是一个暴走的僵尸形象。
    五、小车的设计小车的设计遵从原作的设计,但也有所创新。由于本游戏的设计,撑杆跳僵尸是一个速度快生命值高的厉害角色,所以小车对于它的判断就比较特殊,只要它距离小车有两个的距离小车就会发动,其他僵尸是靠近小车三分之一格的距离才会发动。
    六、对于铲子使用的解释点击铲子时必须尽量点击铲子图标的中心处这样鼠标相应比较灵敏,点击完后铲子图标会随着鼠标移动而移动,而后只要点击相应的植物即可清除植物。另外点击右键可以使铲子回到原处。
    2 评论 64 下载 2019-02-28 11:20:42 下载需要15点积分
  • 基于JAVA实现的塔防游戏

    1 项目概述塔防游戏主要代表一类通过在游戏地图上装置炮塔,阻止敌人进攻的策略型游戏。本游戏是在地图上的特定地点装置多种能力不同的炮台以抵御多种怪兽的入侵。同时玩家每场战斗将拥有多种道具让玩家防守更加轻松。游戏原型是【保卫萝卜】和【皇城守卫】,总体设计风格和游戏背景音乐音效向【皇城守卫】靠拢,而游戏机制是参照了【保卫萝卜】。
    1.1 项目目标该项目是要创造出一个界面设计良好,运行流畅,游戏体验较好的一款单机塔防类游戏。游戏风格偏向卡通,游戏难度较为困难,需要玩家合理使用道具和防御塔。
    1.2 项目任务
    游戏中的炮塔创建,怪兽移动,炮塔攻击特色,玩家的特殊道具等功能的实现
    背景音乐的开启和关闭,关卡和地图选择,用户帮助文档,重新开始等功能的存在
    不同界面之间的切换良好,用户不会感到阻塞

    2 需求分析本游戏能够实现正常塔防游戏的基础功能,并且我们在游戏机制上是综合了保卫萝卜和皇城守卫两款游戏。本款游戏将实现如下功能:

    防御塔的创建、售卖、攻击
    怪兽的攻击、移动
    合理的金币获得设计、获取量设计
    道具的设计
    BGM的关闭,游戏音效的实现

    详细将由下图给出:

    3 系统设计本游戏因为组员资源收集能力有限并未找到相应源码进行参考,所以游戏的核心代码全是组员之间相互讨论得出。
    3.1 开发环境及技术手段
    jre1.8.162
    Java语言

    3.2 系统技术架构本程序主要采用多线程处理问题,包含线程的有游戏界面类,防御塔类,怪兽类。在新建一座防御塔时就会让防御塔启动线程,而所有线程结束的判断条件都是玩家的血量是否为零。线程所做的事情是将自我特定属性进行改变,让主线程的paint调用每个类的paint方法,然后主线程不停的重绘,这样就能达到动画效果。
    3.3 系统流程设计在等待界面,关卡选择界面,游戏界面都是实现了简单的mouse listener事件,而在进入游戏界面时会启动游戏界面的线程,只要玩家血量不为零并且怪兽没有被全部消灭线程就不会终结。但是在游戏界面有事件可以暂停游戏,返回开始界面。本游戏并没有设计退出按钮,玩家想结束游戏是可以在任何界面关闭窗体达到退出游戏效果。
    3.3.1 游戏流程图本游戏通过鼠标事件在不同的就jpanel之间进行切换,其中有游戏界面,关卡选择界面,帮助界面,开始界面。判断条件就是玩家选择哪个界面。

    3.3.2 开始界面开始界面中含有转换到帮助界面,关卡选择界面的鼠标事件,同时鼠标事件还能实现提示效果。即鼠标触碰到固定区域或者按钮时会有提示音效和图片改变效果。

    3.3.3 帮助界面帮助界面将有不同的图片指引玩家更好的进行该游戏,帮助界面只能返回开始界面,且只能在开始界面访问帮助界面。

    3.3.4 关卡选择界面关卡选择界面与开始界面设计大致相同,不同旗子的click事件将会让玩家进入到新的游戏界面。

    3.3.5 游戏界面当进入到游戏界面时游戏界面线程就开始启动并进入循环。只有玩家胜利、失败或者返回开始界面时,游戏线程才会结束。同时只要玩家处在这个界面就能够响应其鼠标事件

    3.3.6 游戏界面鼠标监听游戏界面的鼠标监听主要分为两个部分,游戏结束时监听、游戏运行时监听。游戏时监听分为防御塔空地监听,系统按钮监听。游戏结束监听即是执行游戏结束函数,因为在游戏结束函数中加入了判定游戏是否结束,所以只要将该函数放在首位即可。

    3.3.7 游戏界面线程游戏界面线程主要工作就是在游戏没有结束时不停的刷新页面。在游戏结束时调用结束函数去结束防御塔和怪兽的线程。因为结束函数的关系,玩家可以选择不反悔开始页面重新进行本关卡。当让如果想返回开始界面可以在点击游戏界面后点击返回按钮返回开始界面。

    3.3.8 游戏结束函数游戏结束函数只要作用是让玩家胜利或者失败是停止游戏并播放相应的BGM,在界面中画出相应的失败胜利标志。同时在鼠标事件中提示玩家重新开始。玩家如果不想继续游戏可以在游戏界面点解返回按钮返回开始界面

    3.4 接口和包的设计
    3.5 类图设计
    3.6 类表
    4 系统简介游戏能够正常的进行防御塔建立,怪兽死亡,胜利,失败,道具使用。项目目标中的功能基本全部实现。
    开始界面

    关卡选择界面

    游戏界面一

    游戏界面二

    胜利画面

    失败画面

    道具释放画面一

    道具释放画面二

    5 总结本次实践项目完成度良好。同学们在本次实践项目中掌握了不仅熟练掌握了Java语言的基础语法,对于特定的属性方法也有所掌握,如Jpanel的布局方式,线程的实际应用等。除开语言本身的熟练,队员们对于面向对象的思想,以及如何完整,有组织,有纪律的完成一个项目的方法也有了一定的接触。这也显示着我们正在逐步变成一个有着良好习惯的程序员。虽然本次游戏基本实现了项目目标,但是在实践过程中还是出现了很多的失误。

    因为时间和外部环境的制约,本次实践没有使用GitHub等实用的代码管理工具,代码之间的整合基本靠U盘和网络发送
    虽然初期准备了很多,整个项目的大致方向基本确立,但是缺少核心代码的讨论,一致于组员在初期的第一次整合代码阶段出现了严重的失误,导致组员又要聚集在一起重新讨论游戏的核心实现代码,时间也浪费的较多
    任务时间分工执行并不彻底,因为组员代码编写能力有限,常常会出想某个同学等另一个同学的情况,但是等待的同学并没有做他自己剩余的其他任务,这样就导致了没有充分利用工作时间的问题
    在游戏完成之后,再次查看自己编写的代码发现其中存在很多重复,没有用到的代码,这种问题的存在说明初期对象设计的失误,在初期自己设计整个代码是没有考虑到后期的延展性

    除开上述我们组员出现的失误,组员也展示了自己的专业素养:

    基本实现面向对象思想,在初期分类的时候大家都集体整合了接口相关的问题,而后期实现时基本不会存在类中有类的现象,并且出现bug时能够快速的知道是哪个类出现了问题
    游戏基础功能运行良好,初期设立的项目目标基本实现。UI界面设计良好,游戏动画效果基本无卡顿现象
    在代码编写阶段时组员都编写了良好可用的注释,让其他组员可以独立自主的查看代码
    大家都很积极的参与到项目的完成工作之中,在代码编写阶段,出现了小bug时都能在极短的时间内找到相应代码编写者进行调试解决,从而保证了代码良好的运行,提高了工作效率
    6 评论 263 下载 2018-11-14 16:38:54 下载需要20点积分
  • 基于Java的聊天室系统

    一 需求分析编写一个小型Java聊天室系统,掌握Java网络通信、多线程、IO文件操作等高级应用编程技能。
    完成如下功能:

    多客户端模式下,实现客户与客户的单独通信,要求信息通过服务器中转;
    端到端的通信,实现并行通信模式(一端的信息发送不受另一端的影响);
    添加图形界面.

    二 程序设计2.1 设计思想
    利用socket套接字通信
    多线程处理不同任务
    用Properties在本地存储注册账号
    下载安装windowbuilder插件并用其设计图形界面

    2.2 整体设计(类之间关系)
    Server类(服务器),包含几个继承Runnable的内部类,用于处理客户端请求
    Client类、Login类、TalkFrame类、Regist类。Login类用于登陆,Regist类用于注册,TalkFrame类用于对话,Client实例则被这三个类调用
    Account类,这个类很简单,只有id和password两个属性和相应的set方法。

    类之间关系如下图所示:

    2.3 类的设计
    Client类中只定义了Login、Regist、TalkFrame中需要的socket和流,和 对这些属性初始化的构造函数。
    Login类用于登陆,包含账号label、密码label、账号JTextField、密码 JPasswordField、登陆按钮和注册按钮这些组件,还有一些监听器。
    如下图所示:



    Regist类用于注册,包含用户名label、密码labl、确认密码label、用 户名JTextField、密码JPasswordField、确认密码JpasswordField和注册按钮这些组件,还有一些监听器。
    如下图所示:



    TalkFrame类用于对话,包含选择对话用户label、UserList在线用户JscrollPane 面板、list用户列表、显示对话文本区域、发送信息文本区域和发送消息按钮这些组件,以及对应的监听器。TalkFrame中有两个继承了Runnable的内部类,分别处理在线用户显示和消息的发送。
    如下图所示:



    Server类有三个ServerSocket分别监听登陆端口、注册端口、显示在线用户端口。还有好几个继承Runnable的内部类,用于处理注册、登陆、显示在线用户、用户对话。
    三 程序实现由于涉及了账号注册的功能,必须能在本地保存账号,但我不会在Java中数据库插入数据库,所以只能想办法保存数据,一开始用的是hashtable,但保存到存盘有点困难,在网上搜到的方法是使用XML文件存取可序列化的对象的类,由于hashtable已经实现了序列化接口,所以可以这样实现,我用这种方法写了一遍,发现非常麻烦,再次百度,发现了properties这个集合类,查看JDK文档,了解了properties的load和store方法,这两个方法能很容易地将账号存储在磁盘的文件中。进而,我改用了properties存储账号。
    public Properties userInformation;//与磁盘文件建立联系userInformation = new Properties();uis = new FileInputStream("f:/userInfo.properties");uos = new FileOutputStream("f:/userInfo.properties", true);userInformation.load(uis);//将用户名和密码存储到内存中 userInformation.setProperty(account.getId(),account.getPW());//将用户名和密码保存到文件中userInformation.store(uos, null);
    在处理server接收到的信息时,我用了三个ServerSocket进行处理,RegistServer监听规定的注册端口,对接收的注册信息进行处理;LoginServer监听登陆端口,对登陆后的对话信息进行规定,要求客户端传递的信息必须以接收者id+“:”+发送者id+“:”+发送信息的形式传递给服务器,服务器对传递过来的字符串进行截取,将信息发送给接收者客户端。
    监听发送消息按钮,在字符串前面加上规定的信息然后传递给服务器sendButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { String str = sendMessageTextArea.getText(); String sendMessage = recieverId+":"+id+":"+"\n"; if(!sendMessage.equals("")){ client.pw.print(sendMessage); client.pw.flush(); oldMessageTextArea.append(sendMessage); oldMessageTextArea.setText(""); } } });
    服务器截取信息,获取接收者id,找到对应socket,将信息传递过去。
    String s = br.readLine(); String accountId =s.substring(0,s.indexOf(":")); String message = s.substring(s.indexOf(":")+1); receiveClient = clientConnection.get(accountId); PrintWriter pw= new PrintWriter(receiveClient.getOutputStream()); pw.println(message);
    四 运行测试登陆界面如下图:

    注册界面如下图:
    3 评论 113 下载 2018-10-27 22:17:51 下载需要5点积分
  • 基于JSP SSM框架的城市公交查询系统的设计与实现

    摘 要公交查询系统是为了方便人们查询公交的信息,并且能够及时的做到信息更新,其主要是要做到方便人们的使用,信息的可维护性和程序的稳定性 。本系统采用了JAVA编程语言,数据库使用Mysql。计算机技术不断发展,逐渐适应用于各领域,给人们的学习工作生活带来了便利,在公交查询系统也是这样。纸质的公交指南或繁杂的网络版公交指南,都在不同程度上限制了市民出行的方便性。本论文介绍的是一个城市的公交查询系统,方便市民用最简约的方式,查询到最实用的公交信息。本论文是在此系统经过测试并且所有功能都实现的基础上完成的,主要涉及软件,数据库与网络技术等。
    关键词:城市公交查询系统;数据库;JAVA;SSM
    AbstractThis city buses inquiry system aims to make the resident inquire city buses information more convenient and must achieve the information not too lag, but its main idea is the system administrate user-friendly, the data processes reliability, the maintainability, as well as procedure toughness. The system uses the JAVA programming language and MYSQL as database. Along with computer technology’s unceasing development, the computer applies in each big domain, and has brought the enormous convenience to people’s life, the city buses referral system is also. The departed paper city buses guide or the numerous and diverse online edition city buses guide, has limited the conveniences which in the different procedure when a resident goes on a journey. This thesis introduces a city buses referral system, by facilitates the resident with the briefest way and inquires the most useful city buses information. This thesis that is based on the system has been tested and functions all come true mainly involves software, database and networking and so on.
    Key words: City Buses inquiry system; Databases; JAVA; SSM
    1 概述1.1 项目开发背景和现状的研究1.1.1 开发背景随着城市建设的飞速发展,生活节奏的加快,公交系统对城市来说越来越重要。而政府在这方面的投入也是加大了力度,城市中的公交系统也是日益完善,公交系统的不断更新,却又导致了市民无法从原来的公交指南上看到现如今的信息,从而产生了很多不必要的麻烦。所以需要提供一个高效的公交查询系统,才是问题的根本所在。
    现在,随着计算机技术和通信技术的发展,与网络相结合是现如今的重要发展方向,特别是在网络普及,上网极为方便的网络信息时代,通过上网来查询公交信息是公交查询系统的发展方向。
    1.1.2 研究现状公交查询系统是为了方便人们查询公交的一些信息,并且能够做到信息的及时更新,主要是要方便人们的使用,信息的可维护性和程序的稳定性 。本系统采用JAVA,数据库使用的是Mysql。计算机技术的不断发展,逐渐适应用于各领域,给人们的学习工作生活带来了便利,在公交查询系统也是这样。纸质的公交指南或繁杂的网络版公交指南,都在不同程度上限制了市民出行的方便性。本论文介绍的是一个城市的公交查询系统,方便市民用最简约的方式,查询到最实用的公交信息。
    1.2 项目开发目的与意义1.2.1 系统开发的目标本系统是基于J2EE的公交查询系统,其中包括了公交查询系统的基本功能,并提供了用户留言的功能,方便根据用户提供的留言信息或是提出的建议对系统进行修改和完善,并提供了管理员用户后台维护公交信息的功能,做到能够实时添加和删除公交车次站点。除主要功能以外本系统还附带发布寻物启示与失物招领模块,方便用户。 本系统目标是方便市民进行公交信息查询,并且要做到信息不滞后,其主要思想是做到系统管理的人性化,数据处理的可靠性,可维护性,以及程序的健壮性[2]。系统提供了用户留言的功能,根据用户提供的留言信息或提出的建议提高公交公司的服务质量。基于J2EE的城市公交查询系统,它采用B/S模式。该系统不仅可以用于公交公司管理系统中,也可以单独作为公交管理系统的一个模块存在,并可以制作成城市公交信息系统查询网,放置于城市的主要场所[3]。这样不仅可以体现出一个城市的智能公交系统的水平,更显示出城市的数字化,信息化水平。
    1.2.2 系统开发的意义Internet 是城市公交信息查询系统得以实现的基础。在当今社会,网络大为普及,上网极为方便,通过网络查询公交信息更是城市公交信息查询系统的发展方向,与网络相结合是大势所趋[4]。城市公交信息查询系统旨在应用现代的信息网络化为广大乘客提供一种方便快捷的乘车线路服务,让网络惠及更多的人。提高市民的出行效率,促进社会的和谐。
    本论文主要涉及软件,数据库与网络技术等。涵盖知识面广,可有效地提高学生综合运用所学知识分析解决问题的能力,增强学生对事物的理解与掌握能力,培养学生掌握科学的研究方法,正确的设计思想,独立思考,勇于进取,探索创新,为今后进一步学习与工作奠定了良好的基础。
    1.3 本论文研究的主要内容本论文采用软件工程思想来进行城市公交信息查询系统的设计与实现。
    首先,介绍当前形势下大多数城市公交路线查询系统存在的诸多问题。在此基础上提出本系统的现实意义以及必要性。对城市公交信息查询系统进行了可行性分析,确定了本系统的功能、性能、界面等。
    其次,对城市公交信息查询系统进行模块分解,确定软件结构,模块功能和模块间的接口,以及数据库的设计。及根据需求分析中提出的思路来设计系统,对各个模块的设计进行了描述。然后给出了城市公交信息查询系统的整体结构图以及各个模块的实现流程图以及数据库设计时需要的表结构。
    再次,对本系统进行详细设计,在此基础上对各个模块的实现进行了介绍,给出了本系统的效果图,并且对重要功能给出了主要代码。
    最后,对系统进行了测试及分析。本文对软件测试的概念和方法进行了概要说明,并对系统的设计和实现进行了总结,提出了对城市公交信息查询系统的展望和具体的改进建议。
    2 需求分析2.1 需求分析2.1.1 系统需求由于本系统面向广大市民和公交公司管理本系统等非计算机专业人士的需求,因此要求硬件配置不能太高,任何一个普通的计算机用户都能很快的熟悉整个软件的使用。本系统要做到所耗费的资源常小,任何用户只需要在一般的电脑上面,就能够通过浏览器使用这个软件。公交公司管理人员能够简单、方便、快捷、远程的实现对系统实时维护和管理。
    2.1.2 技术需求本系统是以互联网为基础,采用SSM框架MySQL数据库开发模式,服务器采用Tomcat 6.0。服务器由数据库服务器、Web服务器等服务器组成,通过客户端网络连接进行系统的管理和维护,数据库服务器中的数据要实现实时更新,数据库要可靠稳定。
    2.1.3 安全需求本系统面向社会,因此对系统的安全性有较高的要求。对数据库要设置不同的用户权限,数据的操作需要用户身份验证,只有取得合法的身份才能进行操作,还应避免数据并发现象,防止数据库无法响应操作。
    2.2 系统可行性分析2.2.1 技术可行性现在,随着计算机技术和通信技术的发展,与网络相结合是以后的重要发展方向,特别是在网络大为普及,上网极为方便的网络信息时代,通过网络查询公交信息更是公交查询系统的发展方向。特别是在网络大为普及,上网极为方便的网络信息时代,通过网络查询公交信息更是查询系统的发展方向。基于Web的新型公交信息查询系统,数据信息更新更为准确、及时,用户可以利用计算机、手机等平台通过有限或无线的网络连接方式对系统进行访问,得到快捷的服务[5]。SSM(Spring + Springmvc +Mybatis)框架中Mybatis提供了多种常用的数据库应用程序,通过少量代码的编写,就能够实现数据库的访问[6]。系统采用MYSQL作为开发数据库。MYSQL是一种客户机/服务器结构的关系数据库管理系统[7]。在技术难度方面,有指导老师的指导、周围同学的热心帮助,加上对很多相关文献的参考,能够解决开发过程中所遇到的困难。因此,技术是可行的。
    2.2.2 经济可行性如今,随着计算机的大量普及,各种软件的开发成本越来越低,价格也越来越底。本系统也是这样,开发成本较低,只是需要一台配置一般的计算机,该系统运行时占计算机的资源也不多,但并不会因为开发成本低而造成系统功能性能的下降。相反,随着计算机技术的发展,各种实用软件的性能日渐提高。任务管理系统廉价的开发成本,却能够为用户带来相当大的实惠和方便。主要表现在:

    本系统可以说是一个拥有多种实用功能的系统,它集成了多种功能,具有较强的实用性和方便性
    本系统的运行可以大大提高查询信息的效率,减少不必要的人力和物力

    2.3 功能分析要设计一个良好的公交查询系统,就必须首先明确该应用环境对系统的要求。公交查询系统的应用背景为:方便市民搭乘公交车出行;手动(目前)、自动(将来)、及时更新查询数据。
    2.3.1 查询功能分析系统需要提供几种不同方式的查询手段,以实现灵活方便地管理整个系统。其中包括:

    线路查询:可以获得要查询公交所通过的所有站点
    站点查询:通过输入指定站点查询经过该站点的公交车
    公交换乘模块:主要体现那些不可直达需要转车的线路的所有换发

    2.3.2 数据的更新以及修改分析
    更新:系统允许管理员级别的用户对数据进行更新、修改并且存盘操作
    编辑:系统允许管理员级别的用户对数据进行编辑、删除的操作,保证数据的真实性与实时性

    系统采用采用B/S(Browser/Server)结构。整个系统最关键的就是数据库系统,一个强大的数据库可以支持完善一个优秀的软件设计,通过软件系统与数据库系统的连接来实现通过软件界面观察和处理操作数据[8]。通过软件系统与数据库系统的连接来实现通过软件界面观察和处理操作数据,如图2-1所示。

    系统采用三层结构,在客户端用户通过浏览器完成数据下载与模拟操作,浏览器端的表现逻辑通过JAVA网页完成[9]。而系统内部复杂的业务逻辑主要通过JavaBean的组件(Component)实现,JavaBean组件在WWW服务器上运行,通过JAVA返回到客户浏览器。通过表现逻辑与业务逻辑的分离,使网页内容简洁,系统的可维护性和可扩充性增强。在服务器端,系统使用JDBC中间件访问数据库,数据库服务器定义了本系统所需要的事务逻辑和数据逻辑。本系统使用JAVA技术作为表现手段,服务器采用Tomcat6.0作为JAVA引擎,系统业务逻辑由JavaBean 组件完成,使用JDBC 3.0 驱动程序访问数据库[10]。由于系统测试需要成熟的数据库支持,因此系统采用MySQL数据库作为数据库服务器。
    3 系统关键技术3.1 JAVA技术JAVA是由Sun微系统公司于1999年6月推出的一项技术,是基于JavaServlet以及整个Java体系的Web开发技术,利用这一技术可以建立先进、安全和跨平台的动态网页技术[11]。JAVA技术在多个方面加速了动态Web页面的开发。
    与微软公司的ASP技术相比,JAVA具有如下优点:

    开放的技术:JAVA技术基于平台和服务器的相互独立,技术支持来自广泛的、专门的、各种工具包,有服务器的组件和数据库产品开发商提供。相比之下,JAVA技术主要依赖MICROSOFT支持
    平台和服务器的独立性:JAVA编写的代码可运行在任何符合JAVA语法结构的环境中。这样JAVA就能够运行在多种WEB服务器上并支持来自多家开发商提供的各种工具包
    开放的开发过程,开放的源码:自1995年以来,SUN用开放过程方法同国际JAVA组织合作开发和修改JAVA技术和规范
    JAVA标记可扩充性:JAVA技术能够为开发者扩展JAVA标记,充分利用与XML兼容的标记技术强大的功能,大大减少对脚本语言的依赖
    JAVA跨平台的可重用性:JAVA组件(EJB,JavaBean或定制的JAVA标记)都是跨平台可重用的

    3.2 Java Bean技术JAVA作为一个很好的动态网站开发语言得到了越来越广泛的应用,在各类JAVA应用程序中,JAVA + JavaBean的组合成为了一种事实上最常见的JAVA程序的标准[12]。JavaBean是描述Java的软件组件模型,有点类似于Microsoft的COM组件概念。在Java模型中,通过JavaBean可以无限扩充Java程序的功能,通过JavaBean的组合可以快速的生成新的应用程序。对于程序员来说,最好的一点就是JavaBean可以实现代码的重复利用,另外对于程序的易维护性等等也有很重大的意义。JavaBean通过Java虚拟机(Java Virtual Machine)可以得到正确的执行,具有平台无关性[13]。一个JavaBean有三个部分组成:
    属性(Property)
    Bean的属性就是对象的属性,但提供了属性读取和设置的接口支持。例如一个时钟Bean可以有时区和镇铃属性,日历Bean可以有年份和月份属性。每个属性通常遵守简单的方法命名规则。这样可以很方便的找出Bean提供的属性,然后查询属性值或改变属性值,对Bean进行操作。
    方法(Method)
    由于Bean本身是Java对象,调用这个对象的方法是与其交互作用的唯一途径。JavaBean严格遵守面向对象的类设计逻辑,不让外界访问其任何实例字段(没有Public字段)。这样,方法调用的是接触Bean的唯一途径。
    事件(Event)
    Bean与其他软件组件交流信息的主要方式是发送和接收事件。这与对象之间通过消息通信类似。JavaBean传统的应用在于可视化的领域,如AWT下的应用。自从JAVA诞生后,JavaBean更多的应用在非可视化领域,在服务器端应用方面表现出来了越来越强的生命力。利用非可视化JavaBean, 来封装事务逻辑、数据库操作等等,可以很好地实现业务逻辑和前台程序(如JAVA)的分离,使得系统具有更好的健壮性和灵活性。
    3.3 JDBC技术JDBC是Java的开发者——Sun的Java Soft公司制定的Java数据库连接Java Data Base Connectivity技术的简称,是为各种常用数据库提供无缝联接的技术[14]。JDBC在Web和Internet应用程序中的作用和ODBC在Windows系列平台应用程序中的作用类似。JDBC有一个非常独特的动态连接结构,它使得系统模块化。使用JDBC来完成对数据库的访问包括以下四个主要组件:Java的应用程序、JDBC驱动器管理器、驱动器和数据源。简单地说,JDBC能完成下列三件事:

    同一个数据库建立连接
    向数据库发送SQL语句
    处理数据库返回的结果

    JDBC是一种可用于执行SQL语句的Java API(Application Programming Interface,应用程序设计接口)。它由一些Java语言写的类、界面组成。JDBC给数据库应用开发人员、数据库前台工具开发人员提供了一种标准的应用程序设计接口,使开发人员可以用纯Java语言编写完整的数据库应用程序。
    通过使用JDBC,开发人员可以很方便地将SQL语句传送给几乎任何一种数据库。也就是说,开发人员可以不必写一个程序访问MySQL,写另一个程序访问Oracle,再写一个程序访问Microsoft的SQLServer。用JDBC写的程序能够自动地将SQL语句传送给相应的数据库管理系统(DBMS)。不但如此,使用Java编写的应用程序可以在任何支持Java的平台上运行,不必在不同的平台上编写不同的应用。Java和JDBC的结合可以让开发人员在开发数据库应用时真正实现“Write Once,Run Everywhere![15]”。
    Java 具有健壮、安全、易用等特性,而且支持自动网上下载,是一种很好的与数据库线连接而使用的编程语言。它所需要的是Java应用如何同各种各样的数据库连接,JDBC正是实现这种连接的关键。
    JDBC扩展了Java的能力,如使用Java和JDBC API就可以公布一个Web页,页中带有能访问远端数据库的Applet。或者企业可以通过JDBC让全部的职工(他们可以使用不同的操作系统,如Windows, UNIX)在Internet上连接到几个全球数据库上,而这几个全球数据库可以是不相同的。
    3.4 Springmvc技术Springmvc虽然是在Struts1的基础上发展起来的,但它实质上是以WebWork为核心的,其次它为传统的Struts1注入了WebWork的先进设计理念,是在Struts和WebWork的技术基础上进行合并后的一种全新框架。它全新的体系结构与Struts1的体系结构差别很大,Springmvc以WebWork为核心,在Springmvc中大量使用拦截器机制来处理用户请求,采用这种设计的优势表现在:业务逻辑控制器能够与Servlet API 完全分离,避免了Struts1与Servlet API的严重耦合。
    Springmvc对Struts1进行了巨大的改进,主要表现在以下几个方面:

    线程模型方面:Springmvc的Action是一个请求对应一个实例,而Struts1用一个Action的实例处理所有的请求,它的Action工作在单例模式,存在线程安全问题
    Action实现方面:Struts1要求统一扩展自Action类,而Springmvc中可以是一个普通的POJO(Plain Old Java Objects)。POJO指简单的Java对象,实际就是普通Java Beans
    Servlet依赖方面:Struts1的Action依赖于Servlet API,例如Action的execute方法的参数包括request和response对象,使得程序难以测试,而Springmvc的Action不再依赖于Servlet API,便于测试
    封装请求参数:在Struts1中强制使用ActionForm对象封装请求参数而在Springmvc中可以直接使用Action的属性或者选择使用JavaBean来封装要请求的参数
    在数据校验方面: Struts1中支持覆盖validate方法或者使用Validator框架,而在Springmvc中支持重写validate方法或者使用XWork的验证框架
    在Action执行控制方面:Struts1支持每一个模块对应一个请求处理,但是模块中的所有Action必须共享相同的生命周期,而Springmvc支持通过拦截器堆栈为每一个Action创建不同的生命周期

    3.5 Mybatis技术Mybatis是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得开发人员可以随意的使用对象编程思想来操纵数据库,最具特色的是它可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任[16]。
    Mybatis 核心接口有Session、SessionFactory、Transaction、Query、Criteria和Configuration等6个。通过这六个核心接口,不仅可以对持久化对象进行存取,还能够进行事物控制。以下是对这6个核心接口的介绍:

    Session接口:该接口负责执行持久化对象的CRUD(Create Read Update Delete)操作,需要特别指出的是Session对象时非线程安全的
    SessionFactory接口:该接口负责初始化Mybatis。它的职能是负责创建Session对象,并充当数据存储的代理。这里用到了工厂模式,需要注意的是SessionFactory 并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory 就够了,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory
    Transaction接口:该接口负责事物相关的操作。它是可选的,开发人员可以根据自己的需要来编写自己的底层事物处理代码
    Query和Criteria接口:Query和Criteria接口负责各种数据库查询。它们可以使用SQL语句和HQL语言两种方式,本系统采用SQL语句

    3.6 JavaScript技术JavaScript是适应动态网页制作的需要而诞生的一种脚本语言。它具有交互性,能够包含更多活跃的元素,如今已经广泛地应用于Internet网页制作[17]。JavaScript是由Netscape公司开发的一种脚本语言(Scripting Language)。在HTML基础上,使用JavaScript可以开发交互式网页。它的出现使得网页和用户之间实现了一种实时性的、动态的、交互性的关系,使网页包含更多活跃的元素和更精彩的内容。
    JavaScript可以嵌入到HTML文件中,它的出现增强了网页的互动性,JavaScript简化了HTML文段中的有规律重复的部分,缩短了网页加载时间。
    3.7 MVC设计模式MVC模式是目前广泛流行的设计模式,包括三类对象。它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器[18]。
    3.7.1 模型(Model)模型就是业务流程、状态的处理以及业务规则的制定,业务流程的处理过程对其它层来说就是黑箱操作,模型接受视图请求的数据,并返回最终的处理结果。业务模型的设计可以说是MVC最主要的核心。目前流行的EJB模型就是一个典型的应用,它从应用技术实现的角度对模型做了进一步的划分,以便充分利用现有的组件。在MVC的三个部件中,模型处理的任务最多。模型的好处在于代码可以被多个视图重用,因此简化了代码。
    3.7.2 试图(View)视图代表用户交互界面,对于Web应用来说,可以概括为HTML界面。由于一个应用可能有很多不同的视图,MVC设计模式对于视图的处理仅限于视图上数据的采集和处理,以及用户的请求,而不包括在视图上业务流程的处理。业务流程的处理交予模型处理。
    3.7.3 控制器(Controller)控制器可以理解为从用户接收请求,将模型与视图匹配在一起,共同完成用户的请求。所以当单击Web页面中的超链接和发送HTML表单时,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后用确定用哪个视图来显示模型处理返回的数据。
    3.8 系统运行环境服务器端的最低配置是由建立站点所需要的软件来决定的,在最底配置的情况下,服务器的性能往往不进人意,现在硬件性能已经相当出色,而且价格也很便宜,因此通常应给服务器端配置高性能硬件。
    本系统的配置要求如下:

    处理器:1.5GHZ以上
    内存:512MB
    硬件空间:160GB

    题目主要采用的开发环境及技术:

    开发环境

    Windows XP Professional(以上版本)Internet Explorer6.0(以上版本)
    开发工具包:JDK Version1.6
    脚本语言:JavaScript
    数据库工具:MYSQL
    JAVA开发工具:MyEclipse8.5

    4 系统总体设计4.1 系统总体设计概述本系统设计使用了面向对象技术和模块化技术。面向对象技术是一种软件开发和程序设计技术,其所开发的程序是面向对象程序,直接描述客观世界的对象及其相互关系。对象是封装了数据和操作的程序块。所谓封装是为这个程序块建立显示的界面,其它对象只能向这个界面发消息,不能访问内部的私有数据和操作。因此,内部的数据和实现操作的算法若有改动,对其它程序对象没有任何影响。封装使程序局部化、易修改、好维护,但许多对象有相同的功能时免不了重复,所以面向对象技术有继承的机制。此外,由于对象自己操作自己的数据,对同一消息不同的对象均以自己的方式响应使得一种消息可有多种响应方式,这就是多态性。封装、继承、多态是面向对象程序的主要特征[19]。正是这些特征使程序安全、可靠、可重用、易维护。因而面向对象技术也成为当今计算机的新兴技术。
    4.2 系统功能结构图根据上述设计思想进行分析,确定了系统的基本框架,如图4-1所示。

    可以看出城市公交信息查询系统的相关功能,这为系统开发及功能模块化提供了清晰地设计思路与方向,基于系统需求分析,以下为该系统的详细功能:
    登录模块
    普通登陆成功后进入用户个人主界面并选择各种操作,否则会返回到登录界面重新进行登录。管理员登录成功进入管理员主界面选择相应操作。
    公交系统查询模块
    无需登录,进入系统首页根据自己需要进行公交查询。有包括车次查询、站点查询和查询公交换乘方案等。车次查询即为根据车次号查询车次经过的站点,该车次开收车时间,等基本信息;站点查询为经过该站点的车次信息;公交换乘方案查询即分别输入起始站点和目的站点并查询公交乘车方案。
    公告管理模块
    普通用户登录系统后,进入公告管理模块,用户可以提出自己的一些看法意见和对本公交系统的建议,能查看以前的留言。除此之外系统还提供事物认领模块。
    用户个人信息管理模块
    用户登录成功后即可进入到用户的个人主界面,在个人主界面中,用户可以查看个人详细信息,包括用户名账号,保护邮箱等信息,并可以自行修改密码等个人信息,最后注销登录返回到系统登录界面。
    站点信息管理模块
    管理员登录系统后进入相应管理员主界面,在管理员主界面中,可对公交站点信息进行添加和删除,实时更新公交变动信息。
    车次信息管理模块
    管理员登录系统后进入相应管理主界面,在管理员主界面中,可对公交车次信息进行添加和删除,实时更新公交变动信息。
    4.3 系统流程图4.3.1 系统操作流程系统操作流程图详细阐述了该系统的整体操作流程,如图4-2所示。

    用户进行登录,选择登录身份是普通用户或者管理员,如果用户名和密码正确则进入到相应的用户个人主界面,否则返回登录界面重新进行登录。在用户个人主界面,用户可以进行各自需要的操作。若用户为普通用户,则可以进行查询公交信息,留言,注销和更改个人信息等操作;用户为管理员,可添加删除公交信息。最后,用户操作完毕,即可退出本系统,整个系统操作流程到此结束。
    4.3.2 数据增加流程添加信息时,编号字段由系统自动生成,且不能修改,其他信息由用户输入,之后对数据进行合法判断, 合法则写入保存至数据库,不合法则重新输入数据。数据增加流程图如图4-3所示。

    4.3.3 数据修改流程在修改信息时,先选中一条待修改的记录,然后直接输入数据,判断合法性,合法则保存至数据库,不合法重新输入。数据修改流程图如图4-4所示。

    4.3.4 数据删除流程当用户选定一条记录时,单击删除按钮,会提示用户是否确定删除,然后删除数据库相关内容。数据删除流程图如图4-5所示。

    4.4 数据流分析管理员登录系统后,可进行车次管理、站点管理、线路管理、删除用户等操作。普通用户注册登录后,进入查询界面通过系统数据库,可进行公交信息查询、留言版留言。如图4-6所示。

    4.5 业务流分析城市公交信息查询系统工作流程为:输入首页网址进入首页界面,游客只能查询公交信息,游客可以通过注册成为普通用户。普通用户除了具备游客权限外还可以管理个人资料以及发布信息。管理员拥有最高权限,可以对系统信息增删改查,以及对普通管理员的管理,系统业务流程图如图4-7所示。

    5 系统详细设计5.1 后台数据库设计数据库技术是信息资源管理最有效的手段。数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,有效存储数据,满足用户信息要求和处理要求[20]。
    毕业设计城市公交信息查询系统需要对大量的数据完成搜集、分析、整理、存储、交换等工作,这就需要设计一个较为强大的数据库来对这些数据进行管理。在这里本着实用、方便、安全、可靠的原则,采用MySQL作为本系统数据库的支持。本系统主要数据表有:普通用户表、管理员表、车次信息表、站点信息表、中间站点关联表、留言信息表等。
    为了满足系统存储数据需要,方便进行插入,更新,统计分析等操作,数据一共设计为两个部分,第一部分为满足插入,更新,删除较多的数据存储。第二部分为满足查询和统计分析。
    管理员信息表:该表主要保存管理员信息,包含管理员编号、管理员姓名、账户名、密码。



    列名
    数据类型
    字段大小
    可否为空
    说明




    id
    int


    管理员编号(主键)


    adminName
    varchar
    50

    管理员姓名


    loginName
    varchar
    50

    账户名


    passWord
    Varchar
    50

    密码



    公交线路信息表:该表主要保存公交线路信息,包含线路编号、正向途经站点、反向途经站点、公交线路名称、始发时间与末班时间。



    列名
    数据类型
    字段大小
    可否为空
    说明




    id
    int


    线路编号(主键)


    content
    varchar
    255

    正向途径站点


    content2
    varchar
    255

    反向途径站点


    name
    varchar
    50

    线路名称


    title
    varchar
    255

    始末发车时间



    失物信息表:该表主要保存用户发布的信息,包括启示编号、启示内容、发布时间、启示标题、启示类别。



    列名
    数据类型
    字段大小
    可否为空
    说明




    id
    int


    启示编号(主键)


    contents
    varchar
    20

    启示内容


    inputTime
    varchar
    255

    发布时间


    title
    varchar
    255

    启示标题


    type
    int


    启示类型



    找回密码表:该表主要保存找回密码所需信息,包括编号、问题答案内容、问题类型。



    列名
    数据类型
    字段大小
    可否为空
    说明




    id
    int


    编号(主键)


    content
    varchar
    255

    答案内容


    title
    int


    问题类型



    公告表:该表主要保存发布的公告信息,包括公告编号、公告内容、发布时间、公告标题。



    列名
    数据类型
    字段大小
    可否为空
    说明




    id
    int


    公告编号(主键)


    contents
    varchar
    20

    公告内容


    inputTime
    varchar
    255

    发布时间


    title
    varchar
    255

    公告标题



    用户信息表:该表主要保存用户注册信息,包括编号、用户地址、用户邮箱、用户姓名、登录密码、用户名、用户电话、附加信息。



    列名
    数据类型
    字段大小
    可否为空
    说明




    id
    int


    用户编号(主键)


    address
    varchar
    255

    用户地址


    contents
    varchar
    255

    附加信息


    email
    varchar
    50

    邮箱


    loginName
    varchar
    255

    用户名


    passWord
    varchar
    50

    密码


    userName
    varchar
    50

    用户姓名


    tel
    varchar
    20

    用户电话



    5.2 系统模块设计5.2.1 注册与登录用户注册界面,要求用户必须输入姓名、用户名、密码、联系电话以及邮箱等必填信息以及联系地址等选填信息。当信息填完后点击保存按钮完成注册工作,进入用户登录界面,点击返回按钮返回到首页,如图5-1所示。

    登录界面,分为普通用户登录和管理员登录。普通用户或系统管理员在用户对应的文本框中输入用户名,在密码对应的文本框中输入密码,然后选择相应的用户类型。如果用户名和密码同时与数据库中的用户名和密码相对应,点击确定后进入系统主界面,如果输入的信息不正确,则给出提示。
    用户要登录本系统需要提供用户名和密码,在这里就是要检验用户是否满足输入的要求,即检验用户名和密码文本框是否为空,若为空,则提示用户输入用户名和密码。检验用户名是否存在或密码是否正确,即是否存在用户输入的用户名,并且密码是否正确,如图5-2所示。

    输出:登录成功,进入用户的系统使用资源页面,不成功则显示错误信息页面,管理界面如图5-3所示。

    5.2.2 公交信息查询用户根据自己的实际情况选择按站点查询、按线路查询也可以根据其实位置和终点位置进行查询,在相应的位置进行输入,然后提交给系统,系统会自动查找线路表所有相匹配的信息,并返回给用户要查询的公交信息,如图5-4所示。

    查询公交信息数据库相关操作代码:
    public String zz() throws Exception { String cd = request.getParameter("textfield3").trim(); String zd = request.getParameter("textfield4").trim(); ArrayList al = (ArrayList) indexDao.checkCDZD(cd, zd); System.out.println("al.size=" + al.size()); HttpSession session = request.getSession(); if (al.size() > 0 && al != null) { //如果有直达的车辆(也就是不用转车) session.setAttribute("zzMore", al); //直达的车辆的信息 session.setAttribute("zzMorecd", cd); //您输入的起点名 session.setAttribute("zzMorezd", zd); //您输入的终点名 return "zzone"; } else { ArrayList arrMiddleAll = indexDao.checkMiddle(cd, zd); if (arrMiddleAll.size() > 0 && arrMiddleAll != null) {//查询一个中转站可以到达目的地的方法 session.setAttribute("zzMoreMiddleAll", arrMiddleAll); //得到一个中转站可以到达目的地的所有信息 session.setAttribute("zzMorecd", cd); //您输入的起点名 session.setAttribute("zzMorezd", zd); //您输入的终点名 System.out.println("=======================zztwo"); return "zztwo"; } else { //也就是要倒两次以上车 ArrayList arrTwoMiddleAll=indexDao.checkTwoMiddle(cd,zd); if (arrTwoMiddleAll.size() > 0 && arrTwoMiddleAll != null) { session.setAttribute("zzMorecd", cd); //您输入的起点名 session.setAttribute("zzMorezd", zd); //您输入的终点名 session.setAttribute("zzMoreTwoMiddleAll", arrTwoMiddleAll); //得到二个中转站可以到达目的地的所有信息 System.out.println("=======================zzthree"); return "zzthree"; }else{ System.out.println("======================= - zzerror - "); return "zzerror";}
    5.2.3 寻物启事和失物招领普通用户进入该模块可以发布寻物启示以及失物招领信息,如图5-5所示。

    数据库操作相关代码:
    public String noteSSMow() throws Exception { if (request.getSession().getAttribute("loginmessage") == null) return "noLogin";//判断是否登录 NotesEntity pe = indexDao.noteSSMow(request); request.setAttribute("NotesEntity", pe); return "noteSSMow"; } // 公告管理:修改信息 public String notesUpdList() throws Exception { if (request.getSession().getAttribute("loginmessage") == null) return "noLogin";//判断是否登录 List list = indexDao.notesList(request); request.setAttribute("notesUpdList", list); return "notesUpdList"; } // 公告管理:修改单个信息 public String notesUpd() throws Exception { if (request.getSession().getAttribute("loginmessage") == null) return "noLogin";//判断是否登录 NotesEntity notesEntity = indexDao.noteSSMow(request); request.setAttribute("getNotesView", notesEntity); return "notesUpd"; } // 公告管理:修改保存到数据库 public String notesUpdDB() throws Exception { if (request.getSession().getAttribute("loginmessage") == null) return "noLogin";//判断是否登录 indexDao.notesUpdDB(request); return "notesUpdList"; } // 公告管理:删除信息 public String notesDelList() throws Exception { if (request.getSession().getAttribute("loginmessage") == null) return "noLogin";//判断是否登录 List list = indexDao.notesList(request); request.setAttribute("notesDelList", list); return "notesDelList"; } // 公告管理:删除单个信息 public String notesDel() throws Exception { if (request.getSession().getAttribute("loginmessage") == null) return "noLogin";//判断是否登录 indexDao.notesDel(Long.valueOf(request.getParameter("id"))); return "notesDelList"; }
    5.2.4 用户个人信息管理普通用户登录成功后可以进入到个人主界面,该界面实现的功能为:查看个人详细信息、修改个人信息,如图5-6所示。

    5.2.5 公交线路管理此模块需要系统管理员权限,在管理员主界面中,可对公交线路进行添加、删除以及对公交变动信息实时更新。如图5-7所示。

    5.3 连接池配置在城市公交信息查询系统中采用数据库连接处技术提高访问数据库的效率。在数据源中建立了多个数据库连接,这些连接保存在数据库连接池中。Java程序访问数据库时,只需要从连接池中取出空闲的数据库连接,程序访问数据库完毕之后,再将数据库连接池放回连接池,具体实现是在applicationContext.xml中加入:
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://127.0.0.1:3306/buscity</value> </property> <property name="username"> <value>root</value> </property> <property name="password"> <value></value> </property></bean>
    5.4 SSM框架的整合为实现Spring 整合Mybatis和Springmvc,需要配置applicationContext.xml文件,配置完成后系统就可以通过Springmvc的action直接调用了。Mybatis访问数据库的操作都在Spring中实现了,而Spring的调用是在Springmvc的action中实现。SSM框架整合具体如下:
    首先在web.xml文件中添加Spring配置、新增一个监听器(Linstener)。监听器的作用是启动 Web 容器时,自动装配 ApplicationContext 的配置信息。因为它实现了ServletContextListener这个接口,在Web.xml完成这个监听器的配置后,启动容器时,就会默认执行它实现它的方法。实现代码如下:
    <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:/applicationContext.xml </param-value> </context-param><listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
    配置数据源、SessionFactory。连接池的数据源和分配 sessionFactory 对象是通过Spring 管理的。Spring 通过建立一个LocalSessionFactory对象来完成对Mybatis 的配置,这是一个工厂 bean 的实现。然后就可以通过继承 Spring 为 我们提供MybatisDaoSupport(MybatisDao层都需要继承extends它)来对数据库的 DAO 模式管理。代码如下:
    <!-- 配置数据源 DBCP 提供的BasicDataSource --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://127.0.0.1:3306/buscity</value> </property> <property name="username"> <value>root</value> </property> <property name="password"> <value></value> </property> </bean> <!-- Mybatis配置 --> <bean id="sessionFactory" class="org.springframework.orm.Mybatis3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="MybatisProperties"> <props> <prop key="Mybatis.dialect">org.Mybatis.dialect.MySQL5Dialect</prop> <prop key="Mybatis.show_sql">true</prop> <prop key="Mybatis.format_sql">true</prop> <prop key="Mybatis.hbm2ddl.auto">update</prop> </props> </property> <property name="packagesToScan" value="com.Mybatis" /> </bean>
    将sessionFactory 对象作为属性注入到这个服务类中去。代码如下:
    <bean id="indexDao" class="com.struts.dao.IndexDao"> <property name="sessionFactory" ref="sessionFactory"></property></bean>
    装配事务管理器,使用annotation定义事物、自动注册bean。代码如下:
    <!-- 事务管理器配置,单数据源事务 --> <bean id="transactionManager" class="org.springframework.orm.Mybatis3.MybatisTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 使用annotation定义事务 --> <tx:annotation-driven transaction-manager="transactionManager" /> <context:annotation-config /> <!-- 使用annotation 自动注册bean,并保证@Required,@Autowired的属性被注入 --> <context:component-scan base-package="com.*"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan>
    配置struts.xml的Action。
    6 系统调试与测试6.1 程序调试在设计系统的过程中,存在一些错误是必然的。对于语句的语法错误,在程序运行时自动提示,并请求立即纠正,因此,这类错误比较容易发现和纠正。但另一类错误是在程序执行时由于不正确的操作或对某些数据的计算公式的逻辑错误导致的错误结果。这类错误隐蔽性强,有时会出现,有时又不出现,因此,对这一类动态发生的错误的排查是耗时费力的。
    6.2 程序的测试6.2.1 测试的重要性及目的测试的重要性
    软件的测试在软件生命周期中占据重要的地位,在传统的瀑布模型中,软件测试学仅处于运行维护阶段之前,是软件产品交付用户使用之前保证软件质量的重要手段。近来,软件工程界趋向于一种新的观点,即认为软件生命周期每一阶段中都应包含测试,从而检验本阶段的成果是否接近预期的目标,尽可能早的发现错误并加以修正,如果不在早期阶段进行测试,错误的延时扩散常常会导致最后成品测试的巨大困难。
    测试是所有工程学科的基本组成单元,是软件开发的重要部分。自有程序设计的那天起测试就一直伴随着。统计表明,在典型的软件开发项目中,软件测试工作量往往占软件开发总工作量的40%以上。而在软件开发的总成本中,用在测试上的开销要占30%到50%。如果把维护阶段也考虑在内,讨论整个软件生存期时,测试的成本比例也许会有所降低,但实际上维护工作相当于二次开发,乃至多次开发,其中必定还包含有许多测试工作。
    在实践中,软件测试的困难常常使人望而却步或敷衍了事,这是由于对测试仍然存在一些不正确的看法和错误的态度,这包括:
    认为测试工作不如设计和编码那样容易取得进展难以给测试人员某种成就感;
    以发现软件错误为目标的测试是非建设性的,甚至是破坏性的,测试中发现错位是对责任者工作的一种否定;
    测试工作枯燥无味,不能引起人们的兴趣;
    测试工作是艰苦而细致的工作;
    对自己编写的程序盲目自信,在发现错误后,顾虑别人对自己的开发能力的看法。
    这些观点对软件测试工作是极为不利的,必须澄清认识、端正态度,才可能提高软件产品的质量。
    测试的目的
    如果测试的目的是为了尽可能多地找出错误,那么测试就应该直接针对软件比较复杂的部分或是以前出错比较多的位置。
    软件测试是为了发现错误而执行程序的过程,测试是为了证明程序有错,而不是证明程序无错误,一个好的测试用例是在于它能发现至今未发现的错误,一个成功的测试是发现了至今未发现的错误的测试。
    这种观点可以提醒人们测试要以查找错误为中心,而不是为了演示软件的正确功能。但是仅凭字面意思理解这一观点可能会产生误导,认为发现错误是软件测试的唯一目,查找不出错误的测试就是没有价值的,事实并非如此。
    首先,测试并不仅仅是为了要找出错误。通过分析错误产生的原因和错误的分布特征,可以帮助项目管理者发现当前所采用的软件过程的缺陷,以便改进。同时,这种分析也能帮助我们设计出有针对性地检测方法,改善测试的有效性。其次,没有发现错误的测试也是有价值的,完整的测试是评定测试质量的一种方法。
    6.2.2 测试的步骤与内容与开发过程类似,测试过程也必须分步骤进行,每个步骤在逻辑上是前一个步骤的继续。大型软件系统通常由若干个子系统组成,每个子系统又由若干个模块组成。因此,大型软件系统的测试基本上由下述几个步骤组成:

    模块测试:在这个测试步骤中所发现的往往是编码和详细设计的错误
    系统测试:在这个测试步骤中发现的往往是软件设计中的错误,也可能发现需求说明中的错误
    验收测试: 在这个测试步骤中发现的往往是系统需求说明书中的错误

    测试的主要内容:
    为了保证测试的质量,将测试过程分成几个阶段,即:代码审查、单元测试、集成测试、确认测试和系统测试[21]。
    单元测试
    单元测试集中在检查软件设计的最小单位—模块上,通过测试发现实现该模块的实际功能与定义该模块的功能说明不符合的情况,以及编码的错误。
    集成测试
    集成测试是将模块按照设计要求组装起来同时进行测试,主要目标是发现与接口有关的问题。如一个模块与另一个模块可能有由于疏忽的问题而造成有害影响;把子功能组合起来可能不产生预期的主功能;个别看起来是可以接受的误差可能积累到不能接受的程度;全程数据结构可能有错误等。
    确认测试
    确认测试的目的是向未来的用户表明系统能够像预定要求那样工作。经集成测试后,已经按照设计把所有的模块组装成一个完整的软件系统,接口错误也已经基本排除了,接着就应该进一步验证软件的有效性,这就是确认测试的任务,即软件的功能和性能如同用户合理期待的那样。
    系统测试
    软件开发完成以后,最终还要与系统中其他部分配套运行,进行系统测试。包括恢复测试、安全测试、强度测试和性能测试等。
    6.2.3 单独对系统的测试单独对系统的测试主要从以下几个方面入手:

    功能测试:测试是否满足开发要求,是否提供设计所描述的功能,是否用户的需求都得到满足。功能测试是系统测试最常用和必须的测试,通常还会以正式的软件说明书为测试标准
    强度测试及性能测试:测试系统能力最高实际限度,即软件在一些超负荷情况下功能实现的情况
    安全测试:验证安装在系统内的保护机构确实能够对系统进行保护,使之不受各种非常的干扰。针对本系统主要是对权限系统的测试和对无效数据、错数据、和非法数据干扰的能力的测试

    6.3 测试分析本系统主要实现了公交查询功能,并附有用户留言的功能,同时具有管理员后台维护公交信息等功能。但由于本人能力不足以及所学知识的缺乏,再加上时间有限,该系统还不够健全。该系统虽然基本实现了所要求的功能,但是还存在很多不足,有待于进一步的完善和改进。经过上述的测试过程对软件进行测试后,软件基本满足开发的要求,测试宣告结束。
    结束语本文通过本系统设计与开发感触颇深,总结如下:
    学习一门新技术,最重要的是实践,只有多动手才能尽快掌握它。一个系统的开发,经验是最重要的,经验不足,就难免会有许多考虑不周之处。要想吸引更多的用户,系统的界面必须要美观、有特色、友好,功能要健全。不过由于经验不足,我设计的图形界面比较简单。只是对基本功能进行了开发。
    本次开发,我参考了很多本系统的例子,吸取了一些别的本系统的长处,对自己的毕业设计进行了完善,但是还有很多的不足之处,有待以后进一步学习。实践证明,本系统有着很好的发展前景,经测试运行。本文所制作的系统界面友好、使用灵活、操作简单、功能齐全、表现方式独特,已基本具备了成熟的技术理论。
    由于时间仓促,本次设计由我完成本系统的制作,对我这样一个JAVA新手而言所制作的模块还有不完善的地方。数据库的设计也比较简单。还有很多毕业设计中用到JAVA语言的知识也不够全面,还有很多地方不能够作到完全的理解和掌握。通过这次毕业论文的设计制作使本人受益匪浅。由于是毕业设计是独立完成的,因此在毕业设计的过程遇到了很多的困难,我求教了不少老师和同学,在这个过程中让我体会到了,一个团队的重要性。
    参考文献[1] BruceEckel. JAVA编程思想[M].北京:机械工业出版社,2003
    [2] 赛奎春. JAVA工程应用与项目实践[M]. 北京:机械工业出版社, 2002
    [3] 陈守学、刘电霆.中小城市公交线路查询系统设计方法研究[M]. 桂林航天工业高等专科学校学报,2007.12
    [4] 刘晓妍. 基于J2EE公交查询系统的研究[D].上海:华东师范大学软件学院,2010.4
    [5] 吴永军、蔡永香、郭庆胜. 城市公交查询系统的设计与实现[D].武汉:武汉大学资源与环境科学学院,2006.5
    [6] 周继芳. 基于J2EE的公交线路查询系统的设计与实现[D].西昌:西昌卫星发射基地,2009.5
    [7] 孙一林,彭波. JAVA数据库编程实例[M]. 北京:清华大学出版社,2002
    [8] 萨师煊,王珊. 数据库系统概论[D].高等教育出版社,2002
    [9] 耿祥义,张跃平. JAVA实用教程[M]. 北京:清华大学出版社,2003
    [10] 蔡剑,景楠. Java Web应用开发J2EE和Tomcat[M]. 北京:清华大学出版社, 2005
    [11] Brown等. JAVA编程指南(第二版)[M]. 北京:电子工业出版社 ,2003
    [12] 沈雄. 基于SSM的分布式公交运营管理系统设计与实现[EB/OL].http://wenku.baidu.com/view/c49946293169a4517723a3cc.html,2011-05-09/2012-03-28
    [13] JAVA 程序设计论坛http://techbbs.zol.com.cn/subcate_list_8.html,2010-11-04/2012-03-29
    [14] 徐国志,汪孝宜等. SQL Server数据库开发实例精粹[M].北京:电子工业出版社,2006
    [15] 岳昆、王晓玲、周傲英. Web服务核心支撑技术[J]:研究综述.软件学报,2004,18(1):16-20
    [16] 冯锐. SSM权威指南[M].北京:中国电力出版社,2003
    [17] 月影. JavaScript王者归来[M].北京:清华大学出版社,2008
    [18] 孙卫琴. 精通Struts:基于MVC的Java Web设计与开发[M]. 北京:电子工业出版社,2004
    [19] 张存保等. 基于WebGIs的城市公交问路系统.武汉理工大学学报,2004,23(1):20-24
    [20] Paul Simith. Database Appliction[J]. 北京:电子工业出版社,2001
    [21] 王水,张晓民.软件工程素质导论[M].河南:河南科学技术出版社,2011
    6 评论 115 下载 2019-05-14 11:17:31 下载需要16点积分
  • 基于react框架和MYSQL数据库的社团管理系统

    一、技术简介1.1 ReactReact 可以非常轻松地创建用户交互界面。为你应用的每一个状态设计简洁的视图,在数据改变时 React 也可以高效地更新渲染界面。以声明式编写UI,可以让你的代码更加可靠,且方便调试。创建好拥有各自状态的组件,再由组件构成更加复杂的界面。无需再用模版代码,通过使用JavaScript编写的组件你可以更好地传递数据,将应用状态和DOM拆分开来。
    1.2 JSX一种 JavaScript 的语法扩展。 我们推荐在 React 中使用 JSX 来描述用户界面。
    JSX 是在 JavaScript 内部实现的。我们知道元素是构成 React 应用的最小单位,JSX 就是用来声明 React 当中的元素。与浏览器的 DOM 元素不同,React 当中的元素事实上是普通的对象,React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。
    1.3 webpackwebpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
    1.4 npmnpm 是 JavaScript 世界的包管理工具,并且是 Node.js 平台的默认包管理工具。通过 npm 可以安装、共享、分发代码,管理项目依赖关系。
    1.5 YarnYarn 对代码来说是一个包管理器,可以通过它使用全世界开发者的代码, 或者分享自己的代码。Yarn 做这些快捷、安全、可靠。
    通过Yarn可以使用其他开发者针对不同问题的解决方案,使开发过程更简单。 使用过程中遇到问题,可以将其上报或者贡献解决方案。一旦问题被修复, Yarn会更新保持同步。
    1.6 iViewiView 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品。
    1.7 Ant Designantd服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。
    1.8 Eggegg.js是阿里推出的基于koa的node开发框架。为企业级框架和应用而生。Egg 的插件机制有很高的可扩展性,一个插件只做一件事(比如 Nunjucks 模板封装成了 egg-view-nunjucks、MySQL 数据库封装成了 egg-mysql)。Egg 通过框架聚合这些插件,并根据自己的业务场景定制配置,这样应用的开发成本就变得很低。
    Egg 奉行『约定优于配置』,按照一套统一的约定进行应用开发,团队内部采用这种方式可以减少开发人员的学习成本,开发人员不再是『钉子』,可以流动起来。没有约定的团队,沟通成本是非常高的,比如有人会按目录分栈而其他人按目录分功能,开发者认知不一致很容易犯错。但约定不等于扩展性差,相反 Egg 有很高的扩展性,可以按照团队的约定定制框架。使用 Loader 可以让框架根据不同环境定义默认配置,还可以覆盖 Egg 的默认约定。
    1.9 JSON Web TokenJSON Web Token(JWT)是目前最流行的跨域身份验证解决方案。它是一个很长的字符串,中间用点(.)分隔成三个部分。客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。
    1.10 KnexKnex.js是为Postgres,MSSQL,MySQL,MariaDB,SQLite3,Oracle和Amazon Redshift设计的“包含电池”SQL查询构建器,其设计灵活,便于携带并且使用起来非常有趣。它具有传统的节点样式回调以及用于清洁异步流控制的承诺接口,流接口,全功能查询和模式构建器,事务支持(带保存点),连接池 以及不同查询客户和方言之间的标准化响应。
    二、系统概要设计系统的设计主要前台和后台两个部分
    2.1 系统需求分析
    登录/登出
    社团信息管理

    新增/查询/编辑/注销社团移除社团成员关键字查询社团信息
    公告管理

    新增公告预览/查询/删除已创建的公告公告流量统计
    管理员管理

    添加/删除/编辑管理员权限验证
    个人信息管理

    用户名编辑修改密码

    2.2 可行性分析这里讲的可行性分析的任务是从技术上、经济上分析需解决的问题是否存在可行性。其目的是在尽可能短的时间内用尽可能小的代价确定问题是否有解。
    技术上的可行性分析主要分析技术条件能否顺利完成开发工作,硬、软件能否满足开发者的需要等。
    React是一个用于创建可重用且有吸引力的JavaScript框架。它非常适合代表经常变化的数据的组件。使用React,您可以通过将它们分解为组件而不是使用模板或HTML来构建可重用的用户界面。

    灵活性和响应性:它提供最大的灵活性和响应能力
    虚拟DOM:由于它基于文档对象模型,因此它允许浏览器友好地以HTML,XHTML或XML格式排列文档
    丰富的JavaScript库:来自世界各地的贡献者正在努力添加更多功能
    可扩展性:由于其灵活的结构和可扩展性,React已被证明对大型应用程序更好
    不断发展: React得到了Facebook专业开发人员的支持,他们不断寻找改进方法
    Web或移动平台: React提供React Native平台,可通过相同的React组件模型为iOS和Android开发本机呈现的应用程序

    无论是Web还是本机移动开发,React都是大多数用户界面设计平台的理想选择。
    本系统数据库使用的MySQL,MySQL是最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的关系型数据库,轻量、开源、简便易用,使用Navicat Premium 12做数据库图形化管理更高效率进行前后端开发。
    2.3 Server端模型
    由前台客户端发起请求来请求数据,Egg服务器判断是否在白名单或请求头中的token是否有效,若满足条件之一,则放行请求,根据router访问对应的controller,controller为数据的处理层,将数据处理好后通过service对数据库进行访问与操作,然后将service返回的结果在controller进行再次处理与封装,然后将响应数据和状态码(默认200)返回前台
    三、数据库设计3.1 数据概念结构设计E-R模型是数据进行第一层抽象的表示方法。它的主要成分包括:实体、联系和属性。我们可以用E-R图将内容表达出来,辅助设计的实现[6]。
    3.2 数据库关系设计该系统数据库关系图如下所示:

    3.3 数据字典管理员表(admin)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    login_name
    varchar(255)





    name
    varchar(255)





    password
    varchar(255)





    role
    int(1)


    1:超级管理员 2:管理员


    isDel
    int(1)


    默认0



    学生表(student)



    字段
    类型
    主键
    允许空值
    备注




    stu_id
    varchar(255)
    P




    stu_name
    varchar(255)





    password
    varchar(255)





    sex
    int(1)


    0:男 1:女


    role
    int(1)


    0:未审核 1:家庭成员 2:业主


    tel
    varchar(255)





    社团表(community)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    title
    varchar(255)





    desp
    varchar(255)





    belong_dept
    int(11)





    manage_dept
    int(11)





    chairman_stu_id
    int(11)





    type
    int(11)





    create_time
    varchar(13)





    status
    int(1)


    0:未审核 ; 1:已审核 ; 2:已注销



    社团-学生表(community_student)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    stu_id
    int(11)





    community_id
    int(11)





    role
    int(11)


    0:成员; 1:社团管理员


    isDel
    int(11)





    社团类型表(community_type)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    type_name
    varchar(255)





    isDel
    int(11)


    默认0



    部门表(dept)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    dept_name
    varchar(255)





    isDel
    int(11)


    默认0



    公告表(notice)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    title
    varchar(255)





    author
    varchar(255)





    content
    text





    create_time
    varchar(255)





    isDel
    int(11)





    公告日志表(notice_log)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    notice_id
    int(11)





    stu_id
    int(11)





    create_time
    varchar(255)





    四、后台设计在接口设计方面,使用restful API设计原则,访问同一资源的不同操作时,使用同一命名空间,使用不同的请求方式区分不同的操作。
    数据中均没有使用物理删除,只做了逻辑删除,保证数据可回溯。
    新增与更新,都使用同一个接口,根据是否有id去判断是更新还是新增
    4.1 Egg本系统后台采用egg.js编写,egg继承于koa,操作与配置更加简洁,每个请求发送至后台时,先通过编写好的中间件(middleware),然后根据访问的路由(router)去执行对应的控制器(controller),控制器中只做数据操作,不对数据库进行直接操作,将数据整理为服务(service)所需要的形式,直接发送给对应的服务,服务对数据库进行直接操作,然后将结果直接返回给控制器,控制器再将结果响应给前台。
    如此,完成了一次请求
    4.2 权限校验已登录的用户,在请求时的请求头会带Authorization字段,若请求在白名单内,则不需要通过jwt中间件,直接放行,否则要校验此字段,字段里是bare + 登录时生成的json web token。
    jwt中间件对token进行解码后,判断是否合法并且在有效期内,通过则放行,不通过则直接返回状态码401(无权限)。
    代码实现:

    4.3 连接数据库本系统通过knex对数据库进行操作,以函数式编程的方式,简化了手写sql语句的操作,使代码更具语义化与可读性。
    配置MySQL数据库

    4.4 上传图片前端将图片以表单提交的形式传至后台,后台接受一个文件流,将其重命名后存放到目的位置,之后将完整路径发送至前端。

    五、页面设计页面采用蚂蚁金服出品的Ant Design UI 组件库,提供了完善的设计原则、最佳实践和设计资源文件(Sketch 和 Axure),来帮助业务快速设计出高质量的产品原型。
    5.1 登录页面
    输入用户名密码,点击登录,在对密码进行MD5加密后将login_name和password发送至后台,后台进行校验,匹配后将Json Web Token响应回来,将这个token存至cookie中,设定7天的过期时间,当前端再次发起其他请求时,将这个token带到请求头的Authorization字段中,供后台解析。
    若cookie中无请求头,则中止请求,使页面跳转回login页面,重新登录。

    5.2 主页
    antd支持layout和grid两种页面布局,这里采用layout布局,侧边栏通过递归一个JSON对象进行渲染对应的列表内容。

    获取到用户信息时,判断用户的角色,只有超级管理员才可显示管理员管理页签。
    顶部header下拉菜单可以直接跳转到个人信息或者退出登录。

    侧边栏通过collapsed状态进行切换开启或关闭状态。


    主题内容部分采用react-router-dom路由切换,根据url变化切换content内容。

    当页面均无法匹配到对应路由的时候,则进入noFound页面
    5.3 社团管理
    社团列表页面,做了关键字查询与分页功能,分页功能默认每页10条,可更改。

    点击编辑按钮可对当前社团进行更改。

    对每一项均做了填写校验。

    在选择社团主席时,输入学号进行远程搜索,动态选择。
    此处使用Lodash中的防抖功能对输入进行了优化,减少了多次请求造成的性能问题,也避免因请求返回次序不同造成的数据错误。



    当点击详情按钮时,可显示社团内成员,并进行了分组,可对成员进行直接移除。
    5.4 公告管理5.4.1 新增公告
    此处使用react-draft-wysiwyg富文本编辑器制作新增公告功能。编辑好的内容会以HTML标签字符串的形式发送给后台。当发送空值时内容为 ’<p></p>’,此时发布会提示没有添加正文,是否确定提交。

    由于富文本中添加图片是一个比较复杂的操作,此富文本编辑器默认仅可选择在线图片,可增加选取本地图片的选项,但是需要自己后台支持。

    在此处选择图片时,图片限制不可超过500KB并且只可选择’jpg’, ‘jpeg’, ‘png’, ‘gif’这四种格式的图片,选择成功后,会自动将图片上传至服务器,服务器会将处理好的图片的url返回至前台并显示在虚框内,点击添加即可显示到富文本编辑器中,发布时此处会变为<img />标签。
    5.4.2 公告列表
    在此处使用了骨架屏,在数据未完整请求到时,显示骨架,并且为骨架添加必要的延迟,避免白页与页面闪烁。


    当骨架结束后,页面显示内容,对数据进行必要的处理后,点击预览按钮可以显示手机模拟器,预览本条公告。

    手机页面可以进行滚动,但由于在电脑浏览器端显示滚动会有滚动条,很难去掉,有兼容性问题,为了提高体验,显示滚动条,然后将内层盒子扩大出一个滚动条的宽高,再将外层盒子进行over-flow设置为hidden,超出部分不可见,更好地实现模拟手机的滚动功能。


    点击删除按钮时会弹出提示。

    确定后才会删除(逻辑删除)
    5.4.3 流量统计
    默认显示一周以内的公告流量数据,此处使用echarts制作环形图,点击右侧可进行过滤上部时间picker可以选择时间范围,默认为一周内。通过此功能,可以对公告的阅读量进行统计,以便推出更受欢迎的公告资讯。
    5.5 管理员管理只有超级管理员可进入此tab,普通管理员进入不显示这个菜单项,如果在url处输入对应路径,会进入no permission(无权限)页面。


    进入管理员管理页面后,可操作其他管理员但不可操作自己与其他超级管理员。


    此处填写表单均做了表单校验,新增与编辑同理。
    5.6 个人信息
    此处分为基本信息模块与密码模块,基本信息模块可修改用户基本信息,此处只设置了姓名,还可以增加手机号,性别,个性签名,身份证号等等。
    密码模块必须正确输入之前的密码,两次新密码必须一致,而且要满足以字母开头,长度在6~18之间,只能包含字母、数字和下划线才可提交。


    原密码错误会提示错误。
    2 评论 22 下载 2019-08-11 08:41:12 下载需要11点积分
  • 基于JAVA的图书管理系统

    1 数据库设计1.1 需求分析1.1.1系统简要分析本系统的用户为图书馆工作人员,系统用户分为管理员和普通用户两种。管理员为系统的高级用户,普通用户为图书馆工作人员。管理员账号和密码预先写入数据库中,账号是每位同学的学号,密码是学号后三位。
    系统为不同用户提供不同的功能:
    1.1.2基本需求功能点分析系统为不同用户提供不同的功能:

    管理员功能:

    登陆:输入管理员帐号和密码,验证通过后可登陆系统。
    用户管理:

    添加系统普通用户为普通用户重置登陆密码。
    图书类别管理:

    添加图书类别,如:政治,经济,军事,医药等。修改图书类别名称。类别查询。
    图书管理:

    添加一本图书。图书信息包括:书名,第一作者,第一出版社,出版年份,状态(正常,报废),类别等。修改图书信息。图书查询。
    读者类别管理:

    添加读者类别,类别信息包括:类别名称,最长借阅天数,最大借阅本数等。修改读者类别名称。读者类别查询。
    读者管理:

    添加读者。读者信息包括:姓名,读者类别,身份证号,联系电话等等。修改读者信息。读者查询。
    普通用户功能:

    系统登陆和密码修改图书馆工作人员凭用户号和密码登陆系统。图书借阅为读者借书。如果该读者的借书量未达到最大借阅本书,且无超期欠费情况,则可以为其登记借书信息;如有欠费,则需先缴费还书。为读者还书。如果该读者所还图书未超期欠费,则可以为其还书;如欠费,则先计算欠费金额,付费后再还书。

    1.1.3 系统运行条件分析此软件系统需要至少一台计算机为服务器Windows操作系统SQL Server 2008 或更高版本数据库服务器
    1.1.4 数据字典


    表名
    字段序号
    字段名
    主键
    类型
    占用字节
    长度
    允许空




    t_borrowing
    1
    readerId

    int
    4
    10




    2
    bookId

    int
    4
    10




    3
    borrowingTime

    date
    3
    10



    t_return
    1
    readerId

    int
    4
    10




    2
    bookId

    int
    4
    10




    3
    returnTime

    date
    3
    10



    t_reader_bookRelation
    1
    readerId

    int
    4
    10




    2
    bookId

    int
    4
    10



    t_user
    1
    id

    int
    4
    10




    2
    password

    varchar
    50
    50




    3
    username

    varchar
    50
    50




    4
    usertype

    varchar
    20
    20



    t_bookType
    1
    id

    int
    4
    10




    2
    bookTypeName

    varchar
    10
    10




    3
    bookTypeDesc

    varchar
    1000
    1000



    t_book
    1
    id

    int
    4
    10




    2
    bookName

    varchar
    20
    20




    3
    author

    varchar
    20
    20




    4
    bookTypeid

    int
    4
    10




    5
    publisher

    varchar
    20
    20




    6
    publishtime

    varchar
    10
    10




    7
    state

    varchar
    10
    10




    8
    bookDesc

    varchar
    100
    100



    t_readerType
    1
    id

    int
    4
    10




    2
    readerTypeName

    varchar
    20
    20




    3
    theLongestBorrowingDay

    int
    4
    10




    4
    maximumBorrowingNumber

    int
    4
    10



    t_reader
    1
    id

    int
    4
    10




    2
    IDNumber

    varchar
    20
    20




    3
    name

    varchar
    20
    20




    4
    readerTypeid

    int
    4
    10




    5
    tel

    varchar
    11
    11




    1.2 概念结构设计系统E-R图如图

    1.3 逻辑结构设计此部分需要列出由E-R图转化得到的数据表。

    用户表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    id
    int
    4
    主码
    用户id


    password
    varchar
    50
    非空
    用户登录密码


    username
    varchar
    50
    非空
    用户名


    usertype
    varchar
    20
    非空,管理员或普通用户
    用户类型




    图书类别表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    id
    int
    4
    主码
    图书类别id


    bookTypeName
    varchar
    10
    非空
    图书类别名


    bookTypeDesc
    varchar
    1000

    图书类别描述




    图书表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    id
    int
    4
    主码
    图书id


    bookName
    varchar
    20
    非空
    图书名


    author
    varchar
    20
    非空
    作者


    bookTypeid
    int
    4
    非空,外键
    图书类别id


    publisher
    varchar
    20
    非空
    出版社


    publishtime
    varchar
    10
    非空
    出版时间


    state
    varchar
    10
    正常或报废
    图书状态


    bookDesc
    varchar
    100

    图书描述




    读者类别表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    id
    int
    4
    主码
    图书id


    readerTypeName
    varchar
    20
    非空
    读者类型名


    theLongestBorrowingDays
    int
    4
    非空
    最长借阅时间


    maximumBorrowingNumber
    int
    4
    非空
    最大借阅数量




    读者表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    id
    int
    4
    主码
    读者id


    IDNumber
    varchar
    20
    非空
    身份证号


    name
    varchar
    20
    非空
    姓名


    readerTypeid
    int
    4
    非空,外键
    读者类别号


    tel
    varchar
    11

    联系方式




    借书表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    readerId
    int
    4
    主码
    读者id


    bookId
    int
    4
    主码
    图书id


    borrowingTime
    date
    8
    主码
    借阅时间




    还书表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    readerId
    int
    4
    主码
    读者id


    bookId
    int
    4
    主码
    图书id


    returnTime
    date
    8
    主码
    归还时间




    读者-图书关系表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    readerId
    int
    4
    主码
    读者id


    bookId
    int
    4
    主码
    图书id



    1.4 物理结构设计数据库管理系统:SQLServer 2014
    1.5 数据库实施1.5.1 数据库表和视图清单如图所示:

    1.5.2 数据库基本表
    用户表


    图书类别表


    图书表


    读者类别表


    读者表


    借书表


    还书表


    读者-图书关系表

    1.5.3 视图1.5.3.1 view_bookType创建视图代码:
    create view view_bookTypeasselect* from t_bookType
    作用:对图书类别全部属性的查询语句,通过java代码实现可显示在图书类别维护界面的表格中。
    1.5.3.2 view_borrowing创建视图代码:
    create view view_borrowingasselect readerId,IDNumber,name,bookId,borrowingTimefrom t_reader,t_borrowingwhere t_reader.id=t_borrowing.readerId;
    作用:对借书表和读者表部分属性的查询语句,通过java代码实现可显示在图书借阅记录界面的表格中。
    1.5.3.3 view_userlist创建试图代码:
    create view view_userlistasselect * from t_user where usertype='普通用户'
    作用:查询用户类别为普通用户的用户的全部属性,通过java代码显示在重置用户密码界面的表格中。
    1.5.4 存储过程1.5.4.1 existBookByBookTypeId存储过程创建存储过程代码:
    create procedure existBookByBookTypeId(@ID int)as (select*from t_bookwhere bookTypeId=@ID)
    作用:判断指定图书类别下是否有图书
    1.5.4.2 existReaderByReaderTypeId存储过程create procedure existReaderByReaderTypeId(@ID int)as(select*from t_readerwhere readerTypeId=@ID)
    作用:判断指定读者类别下是否有读者
    1.5.5 触发器删除读者触发器
    create trigger triger_deletereaderon t_reader instead of deleteasbeginEXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'--禁用约束delete from t_borrowing where readerId=(select id from deleted)delete from t_return where readerId=(select id from deleted)delete from t_reader where id=(select id from deleted)EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL' --启用约束end
    作用:删除读者时有外键约束,触发器取消外键约束,删除借书还书记录中该读者的记录,再删除该读者,再启用约束。
    2 系统设计2.1 系统功能模块设计此部分主要描述各个模块具体实现的各项功能点以及模块之间的关系,模块结构划分如图所示:

    2.1.1 管理员用户模块该模块具体功能是管理员对图书系统进行管理,主要包括图书类别管理模块,图书管理模块,读者类别管理模块,读者管理模块,用户管理模块。

    图书类别管理模块:此模块下可进行图书类别的添加和维护,维护包括查询、删除和修改,可以对图书类别名和图书类别描述等属性进行操作。
    图书管理模块:此模块下可进行图书的添加和维护操作,维护包括查询删除和修改,可对图书名称、图书作者、图书类别、出版社、出版时间、图书状态、图书描述等属性进行操作。
    读者类别管理模块:此模块下可进行读者类别的添加和维护,维护包括查询、删除和修改,可对读者类别名称、最长借阅天数和最大借阅本数等属性进行操作。
    读者管理模块:此模块下可进行读者的添加和维护,维护包括查询、修改和删除,可对读者身份证号、姓名、联系方式、读者类别等属性进行操作。
    用户管理模块:此模块下可进行对普通用户的添加和修改普通用户密码操作。

    2.1.2 普通用户具体功能模块该模块具体功能是普通用户登录系统后进行借书和还书操作,主要包括图书借阅和图书归还模块。

    图书借阅模块:此模块下可进行图书借阅操作和对借阅记录的查询操作。图书借阅可添加图书借阅记录。
    图书归还模块:此模块下可进行图书归还操作和对归还记录的查询操作。图书归还可添加图书归还记录。

    2.2 系统功能设计本部分按系统主要功能绘制流程图,说明系统功能将如何现。如图所示:

    3 系统实现3.1系统项目清单系统项目具体所含如图所示:
    model包包含各种实体类,dao包包含各种数据库操作的类,util包包含数据库工具类和字符串工具类,model包包含各种界面类。


    3.2 登录界面登录界面由LogOnFrm.java实现,输入用户名和密码,选择用户类型为管理员或普通用户,验证成功即可进入主界面。用户名或密码错误或未输入则弹出窗体提示。如图所示。

    3.3 管理员主界面管理员主界面由MainFrm.java实现,选中菜单栏中选项选择要显示的功能窗体。如图所示:

    3.3.1 图书类别维护界面

    3.3.2 图书添加图书的添加是管理员向数据库中加入一条图书信息,若图书名称、图书作者等非空数据为空,则弹出提示图书不能为空等。图书类别为一个下拉框,其中显示图书类别表中的图书类别名称。图书状态只有正常和报废两种,用单选按钮实现。图书添加界面如图所示。

    3.3.3 图书维护图书维护界面可实现图书的查询、修改删除。没有操作时中间表格bookTable显示所有图书。进行查询操作时表格中显示查询到的结果。添加了表格行点击事件,点击指定行时,下面的表单操作中的文本框被选中内容填充,修改文本框的内容后点击修改按钮,对数据库执行update操作,修改了数据库中数据,然后界面中bookTable表刷新,显示更新后的数据。点击删除按钮时执行sql的delete操作。图书维护界面如图所示。

    3.3.4 添加普通用户在管理员主界面选择用户管理-添加普通用户弹出菜单如图3-8,输入要添加的用户名和密码,点击添加按钮,提示用户添加成功。如用户名和密码为空则弹出错误提示。重置按钮可清空两个文本框。

    3.3.5 重置用户密码菜单在管理员主界面选择用户管理-重置用户密码菜单如图,可进行查询和修改密码操作。在查询框中输入要查询的用户名,中间的userTable中将显示查询出的信息,运用视图view_userlist。点击要修改的用户所在行,该用户密码将出现在密码修改框的密码文本框中,修改内容,点击修改按钮,弹出用户密码修改成功则完成用户密码修改。选中表中用户点击删除按钮,弹出删除成功提示框,则完成了删除该普通用户操作。

    3.3.6 读者维护界面在管理员主界面选择读者管理-读者维护显示读者维护界面如图。可对读者进行查询、修改、删除操作。查询结果显示在表格中。选择表格中数据可进行修改、删除操作。修改、删除完成后提示修改成功或删除成功。删除操作运用触发器triger_deletereader同时删除被删除读者的借书记录和还书记录。

    3.3.7 读者类别维护界面在管理员主界面选择读者类别管理-读者类别维护显示读者类别维护界面如图。读者类别管理界面可实现对读者类别的查询、修改、删除操作,其中删除操作调用存储过程existReaderByReaderTypeId判断该读者类别下是否有读者。有读者时的错误提示如图。


    3.4 普通用户主界面普通用户主界面由MainFrm2.java实现,选中菜单栏中选项选择要显示的功能窗体。如图所示。

    3.4.1 图书借阅界面在普通用户主界面点击借书-图书借阅显示图书借阅界面如图。输入读者编号和图书编号点击确定,若读者编号和图书编号在t_reader和t_book表中不存在则弹出错误提示框。点击重置两文本框重新为空。借书本数超限提示如图,借书时间超限提示如图。



    3.4.2 图书借阅记录查询在普通用户主界面选择借书-借阅记录查询显示界面如图。在查询框中输入读者身份证号和图书编号,点击查询按钮,可进行查询操作。中间表格运用视图view_borrowing显示查询出来的记录,查询之前显示所有的借书记录。

    4 总结图书管理系统运用java语言,连接数据库,主要用eclipse的windowsbuilder插件完成图形化界面,数据存储在SQL server数据库中,通过SQL语句完成对数据库的操作。
    运用了视图、存储过程、触发器来完善系统。系统完成了对图书、读者、用户等对象的增删改查操作。实现了大部分图书管理系统要求的功能。
    不足:系统虽然完成了图书借阅超过期限的提示,但没有写有关的缴费界面和操作。
    3 评论 260 下载 2019-03-02 17:57:17 下载需要12点积分
  • 基于VC++和TCP Socket实现的网络聊天室

    一、课程设计要求1.1 项目介绍首先,服务器聊天程序要在特定的端口上等待来自聊天客户的连接请求,并且需要维护一个客户连接表,以记录所有成功的连接。
    其次,服务器聊天程序要及时接收从各个聊天客户发送过来的信息,然后把这些信息转发到一个或多个客户连接。对于公共聊天室,服务器将把收到的信息向除源端外的所有客户发送过去。
    最后,服务器还要监控这些连接的状态,在客户主动离开或发生故障时从列表中删除相应表项,并及时更新连接表。
    这些要求可以通过CSocket类提供的功能来实现。从CSocket派生出两个类:ClistenSocket和CclientSocket,它们分别用来侦听客户的连接请求和建立与客户的连接。服务器只需要——个侦听套接字ClistenSocket,然后根据客户的连接请求动态创建客户套接字CclientSocket。客户套接字的数量是不可预知的,因此需要一个列表来记录。MFC的CptrList类就能够实现这种功能。
    1.2 实现要求本聊天服务器端聊天程序要求能够检测和显示所有聊天用户的聊天内容,以及各个聊天客户的网络地址和连接端口。

    监听本机IP地址中的一个指定的端口
    当有用户端向该端口发送请求时,服务器程序里克建立一个与该客户端的连接并启动一个新的线程来处理该客户端的所有请求
    根据客户端发送来的各种不同的请求,执行相应地操作,并将处理结果返回给该客户端。服务器能够识别3种请求命令:CONN(建立新连接)、CHAT(聊天)、和EXIT(离开)

    二、设计流程:首先需要运行服务器端,在服务器端创建服务器端的SOCKET并且开启一个特定的端口等待客户端的访问,并且监听到达该端口的访问;客户端运行后通过服务器端的IP地址和端口号与服务器端建立TCP链接,各个客户端的聊天内容先发送到客户端然后再由客户端发向各个客户端。客户端或者服务器端终端链接后释放连接。
    2.1 服务器端流程图
    2.2 客户端流程图
    2.3 主要用到的类和函数说明2.3.1 Socket类public Socket(InetAddress address, int port)throws IOException
    创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
    如果应用程序已指定套接字,则调用该套接字的 createSocketImpl 方法来创建实际套接字实现。否则创建“普通”套接字。

    参数: address - IP 地址 port - 端口号
    侦听套接字类:CListeningSocket
    抛出:

    IOException - 如果创建套接字时发生 I/O 错误SecurityException - 如果安全管理器存在并且其 checkConnect 方法不允许进行该操作

    2.3.2 BufferedReader类public BufferedReader(Reader in,int sz)
    创建一个使用指定大小输入缓冲区的缓冲字符输入流。

    参数: in - 一个 Reader sz - 输入缓冲区的大小
    2.3.3 InputStream类public abstract class InputStream extends Object implements Closeable
    此抽象类是表示字节输入流的所有类的超类。
    需要定义 InputStream 的子类的应用程序必须始终提供返回下一个输入字节的方法。
    2.3.4 JFrame类public class JFrame extends Frameimplements WindowConstants, Accessible, RootPaneContainer
    2.3.5 ActionListener类public interface ActionListener
    ActionListener 接口是一个有用扩展,以便若干控件访问相同的功能。 ActionListener 接口定义的 actionPerformed 方法用来进行对于事件的监听,然后进行处理。描述该方法的一个或多个文本字符串。描述该方法的一个或多个图标。
    2.4 主要部分系统代码的实现2.4.1 服务器端监听套接字的实现CListeningSocket::CListeningSocket(CServerDlg* pDlg){ //对成员变量赋值 m_pDlg=pDlg;}CListeningSocket::~CListeningSocket(){}void CListeningSocket::OnAccept(int nErrorCode){ CSocket::OnAccept(nErrorCode); //调用主对话框类中的函数 m_pDlg->OnAccept();}/////////////////////////////////////////////////////////////////////////////// CListeningSocket member functions#ifdef _DEBUGvoid CListeningSocket::AssertValid() const{ CSocket::AssertValid();}void CListeningSocket::Dump(CDumpContext& dc) const{ CSocket::Dump(dc);}#endifIMPLEMENT_DYNAMIC(CListeningSocket,CSocket)
    2.4.2 客户端套接字的实现//构造函数CClientSocket::CClientSocket(CServerDlg* pDlg){ m_pDlg=pDlg; m_nMsgCount=0; m_pFile=NULL; m_pArchiveIn=NULL; m_pArchiveOut=NULL;}//初始化void CClientSocket::Initialize(){ //构造相应的CSocketFile对象 m_pFile=new CSocketFile(this); //构造相应的CArchive对象 m_pArchiveIn=new CArchive(m_pFile,CArchive::load); m_pArchiveOut=new CArchive(m_pFile,CArchive::store);//放弃传送void CClientSocket::Abort(){ if (m_pArchiveOut!=NULL) { m_pArchiveOut->Abort(); delete m_pArchiveOut; m_pArchiveOut=NULL; }}//发送消息void CClientSocket::SendMessage(CMsg* pMsg){ if (m_pArchiveOut!=NULL) { //对消息进行序列化 pMsg->Serialize(*m_pArchiveOut); //将CArchive对象中的数据强制性写入文件中 m_pArchiveOut->Flush(); }}//接收消息void CClientSocket::ReceiveMessage(CMsg* pMsg){ //对消息进行序列化 pMsg->Serialize(*m_pArchiveIn);}//OnReceive事件处理函数void CClientSocket::OnReceive(int nErrorCode){ CSocket::OnReceive(nErrorCode); //调用主对话框类中的相应函数处理 m_pDlg->OnReceive(this);}//析构函数CClientSocket::~CClientSocket(){ if (m_pArchiveOut!=NULL) delete m_pArchiveOut; if (m_pArchiveIn!=NULL) delete m_pArchiveIn; if (m_pFile!=NULL) delete m_pFile;}#ifdef _DEBUGvoid CClientSocket::AssertValid() const{ CSocket::AssertValid();}void CClientSocket::Dump(CDumpContext& dc) const{ CSocket::Dump(dc);}#endifIMPLEMENT_DYNAMIC(CClientSocket,CSocket)
    2.5 程序运行结果服务器端运行界面


    客户端运行结果


    2 评论 67 下载 2018-11-07 16:20:51 下载需要8点积分
  • 基于MFC实现的AES加密解密程序

    1 算法背景及介绍1.1 背景高级加密标准(Advanced Encryption Standard,AES)作为传统对称加密算法标准DES的替代者,由美国国家标准与技术研究所(NIST)于1997年提出征集该算法的公告。1999年3月22日,NIST从15个候选算法中公布了5个候选算法进入第二轮选择:MARS,RC6,Rijindael,SERPENT和Twofish。
    2000年10月2日,以安全性(稳定的数学基础,没有算法弱点,算法抗密码分析的强度,算法输出的随机性)、性能(必须能在多种平台上以较快的速度实现)、大小(不能占用大量的存储空间和内存)、实现特性(灵活行、硬件和软件实行性、算法的简单性等)为标准而最终选定了两个比利时研究者Vincent Rijinmen和Joan Daemen发明的Rijndael算法,并于2001年正式发布了AES标准。
    1.2 AES加密算法AES算法本质上是一种对称分组密码体制,采用代替/置换网络。AES算法主要包括三个方面:轮变化、圈数和密钥扩展。
    1.2.1 圈变化AES每一个圈变换由以下三个层组成:

    非线性层——进行Subbyte变换,非线性层由16个S盒并置起到混淆的作用
    线行混合层——进行ShiftRow和MixColumn运算,线性混合层确保多轮之上的高度扩散
    密钥加层——进行AddRoundKey运算,密钥加密层将子密钥异或到中间状态

    Subbyte变换是作用在状态中每个字节上的一种非线性字节转换,可以通过计算出来的S盒进行映射。
    ShiftRow是一个字节换位。它将状态中的行按照不同的偏移量进行循环移位。
    在MixColumn变换中,把状态中的每一列看作GF(28)上的多项式a(x)与固定多项式c(x)相乘的结果。b(x)=c(x)*a(x)的系数这样计算:*运算不是普通的乘法运算,而是特殊的运算,即 b(x)=c(x) • a(x)(mod x4+1) 算法如下图:

    对于逆变化,其矩阵C要改变成相应的D,即b(x)=d(x)\*a(x)。
    密钥加层运算(addround)是将圈密钥状态中的对应字节按位“异或”。
    根据线性变化的性质,解密运算是加密变化的逆变化。
    1.2.2 轮变化对不同的分组长度,其对应的轮变化次数是不同的,这里要介绍的密钥长度为128位的轮变化数为10轮;密钥长度为192位的轮变化数为12轮;密钥长度为256位的轮变化数为14轮。
    1.2.3 密钥扩展AES算法利用外部输入密钥K(密钥串的字数为Nk),通过密钥的扩展程序得到共计4(Nr+1)字的扩展密钥。它涉及如下三个模块:

    位置变换(rotword)——把一个4字节的序列[A,B,C,D]变化成[B,C,D,A];
    S盒变换(subword)——对一个4字节进行S盒代替;
    变换Rcon——Rcon表示32位比特字[xi-1,00,00,00]。这里的x是(02),如 Rcon[1]=[01000000];Rcon[2]=[02000000];Rcon[3]=[04000000]……

    扩展密钥的生成:扩展密钥的前Nk个字就是外部密钥K;以后的字W[]等于它前一个字W[i-1]与前第Nk个字W[i-Nk]的“异或”,即W[]=W[i-1]⊕W[i- Nk]。但是若i为Nk的倍数,则W=W[i-Nk]⊕Subword(Rotword(W[i-1]))⊕Rcon[i/Nk]。
    2 系统设计2.1 系统主要目标基本要求部分:

    在深入理解AES加密/解密算法理论的基础上,设计了一个AES加密/解密软件系统
    完成一个明文分组的加解密,明文和密钥是十六进制,长度都为128比特(32个16进制数),按照标准输入明文和密钥,输出密文,进行加密后,能够进行正确的解密
    程序运行时,输出每一轮使用的密钥,以及每一轮中字节替代、行移位、列混合,密钥加等每一步操作之后的16进制表示的值

    较高要求部分:

    如果明文不止一个分组,程序能完成分组,然后加密;最后一个分组长度不足时填充0;密钥长度不足时填充0,过长则自动截取前面部分
    密钥可以采用16进制ASCII码或英文字符输入,明文输入信息可以是16进制数值或英文,任意字符(不包括汉字),或者是文本文档,进行加密后,能够进行正确的解密
    程序代码有比较好的结构,模块划分合理,通过调用类的成员函数实现加密解密功能,函数的参数及返回值设置合理。
    界面友好

    2.2 主要软件需求(运行环境)
    本软件适用VC语言编写,编译成功后的EXE文件可以在装有Windows系统的任何计算机上使用
    测试平台:Windows XP Professional
    使用软件:Visual C++ 6.0

    2.3 功能模块与系统结构加密/解密的大致结构图:


    加密/解密主要流程图:

    3 系统功能程序设计本程序中用到2张表格:Sbox[256],iSbox[256]和Rcon[32];均采用一维数组存放;明文分组plaintext[16]和初始密钥key[16]也均为一维数组;但在处理过程中仍把Sbox[256]和iSbox[256]看做16行16列的矩阵;把Rcon[32]看做8行4列的矩阵;把plaintext[16]和key[16]看做4行4列的矩阵,则第i行j列的数在一维数组中的位置为4i+j。扩展密钥采用二维数组w[44][4]存放。由于明文和密钥装入数组为顺序装入,即相当于AES算法中按列装入的矩阵的转置,所以进行对应的行变换即应该进行相应的列变换。
    3.1 基本要求部分3.1.1 字节替换Sbox[256],plaintext[16]均采用一维数组存放,plaintext中存放的为转化为16进制的操作数,进行字节替换时是取plaintext存放的数据的二进制值的高4位做行坐标i,低四位做列坐标j来取Sbox中对应位置的数据替换,而plaintext的值恰好为16i+j,所以plaintext的值即为对应的替换值在Sbox中的位置。
    void CAESDlg::SubByte(){ int i; for(i=0;i<16;i++) plaintext[i]=Sbox[plaintext[i]];}
    3.1.2 行移位Plaintext[16]采用一维数组存放操作数,把它看做每行4列的矩阵,所以第k行i列即为plaintext[4*k+i ]。由于AES采用列存放数据,而这里plaintext采用顺序存放,相当于行存放,即为列存放的转置矩阵,所以进行行移位时即应该进行相应的列移位:
    列变换(行移位)情况如下图所示:

    void CAESDlg::ShiftUp(int i){ int j,k,temp; for(j=0;j<i;j++) { temp=plaintext[i]; for(k=0;k<3;k++) plaintext[4*k+i]=plaintext[4*(k+1)+i]; plaintext[i+12]=temp; }}void CAESDlg::ShiftRows(){ int i; for(i=1;i<4;i++) ShiftUp(i);}
    3.1.3 列混合把一维数组plaintext[16]看做4行4列,则i行j列即为4*i+j , 列混合即为两个矩阵相乘,由于AES采用列存放数据,而这里plaintext采用顺序存放,相当于行存放,即为列存放的转置矩阵,所以另一个矩阵也转置,相乘后仍然是AES列混合后的转置矩阵:
    相当于下面两个矩阵相乘:

    int CAESDlg::gfmultby02(int b){ if (b<0x80) //(0x80=OB10000000) return (b<<1); else return (((b<<1)-256)^(0x1b)); //(0X1b=OB00011011)}int CAESDlg::gfmultby03(int b){ return (gfmultby02(b)^b);}void CAESDlg::MixColumns() { int i,temp[16]; memcpy(temp,plaintext,64); for(i=0;i<4;i++) { plaintext[4*i]=gfmultby02(temp[4*i+0]) ^ gfmultby03(temp[4*i+1]) ^ temp[4*i+2] ^ temp[4*i+3]; plaintext[4*i+1]=temp[4*i+0] ^ gfmultby02(temp[4*i+1]) ^ gfmultby03(temp[4*i+2]) ^ temp[4*i+3]; plaintext[4*i+2]=temp[4*i+0] ^ temp[4*i+1] ^ gfmultby02(temp[4*i+2]) ^ gfmultby03(temp[4*i+3]) ; plaintext[4*i+3]=gfmultby03(temp[4*i+0]) ^ temp[4*i+1] ^ temp[4*i+2] ^ gfmultby02(temp[4*i+3]); }}
    3.1.4 密钥加密钥w[44][4]依次存的为初始密钥和扩展后的10轮轮变换的密钥,round为加密的轮数,w[4*round+r][c]即为第round轮的密钥第r行c列。把一维数组plaintext看做4行4列,则r行c列即为4*r+c,分别行取值异或,即为密钥加:
    void CAESDlg::AddRoundKey(int round){ int r,c; for(r=0;r<4;++r) for(c=0;c<4;++c) plaintext[4*r+c]=(plaintext[4*r+c]^w[4*round+r][c]);}
    3.1.5 密钥扩展rowtem%flag==0时即为每轮密钥开始的行数,它的前一行移位RotWord后查表Sbox再和前4行密钥异或,第一列再和Rcon异或;当不为轮开始的第一行密钥时,直接取前一行和前四行异或:
    void CAESDlg::InitKey(){ int inkey[16]; int temp[4],flag=4; memcpy(inkey,key,64); //内存COPY函数,(目的,源,大小) for(int row=0;row<4;row++) { w[row][0] = inkey[4*row]; w[row][1] = inkey[4*row+1]; w[row][2] = inkey[4*row+2]; w[row][3] = inkey[4*row+3]; } for(int rowtem=flag;rowtem<44;rowtem++) { temp[0] = w[rowtem-1][0]; temp[1] = w[rowtem-1][1]; temp[2] = w[rowtem-1][2]; temp[3] = w[rowtem-1][3]; if (rowtem%flag==0) { RotWord(temp); SubWord(temp); temp[0] = (temp[0]^Rcon[rowtem/flag]); } // w[row] = w[row-Nk] xor temp w[rowtem][0] = ( w[rowtem-flag][0] ^ temp[0] ); w[rowtem][1] = ( w[rowtem-flag][1] ^ temp[1] ); w[rowtem][2] = ( w[rowtem-flag][2] ^ temp[2] ); w[rowtem][3] = ( w[rowtem-flag][3] ^ temp[3] ); }//loop}void CAESDlg::RotWord(int *word ){ int temp; temp=word[0]; word[0] = word[1]; word[1] = word[2]; word[2] = word[3]; word[3] = temp;}void CAESDlg::SubWord(int* word ){ word[0] = Sbox[ (word[0] >> 4)*16+(word[0] & 0x0f)]; word[1] = Sbox[ (word[1] >> 4)*16+(word[1] & 0x0f)]; word[2] = Sbox[ (word[2] >> 4)*16+(word[2] & 0x0f)]; word[3] = Sbox[ (word[3] >> 4)*16+(word[3] & 0x0f)];}
    3.1.6 逆字节替换与字节替代类似,iSbox[256],plaintext[16]均采用一维数组存放,plaintext中存放的为转化为16进制的操作数,进行字节替换时是取plaintext存放的数据的二进制值的高4位做行坐标i,低四位做列坐标j来取iSbox中对应位置的数据替换,而plaintext的值恰好为16i+j,所以plaintext的值即为对应的逆替换值在iSbox中的位置。
    void CAESDlg::InvSubBytes(){ int i; for(i=0;i<16;i++) plaintext[i]=iSbox[plaintext[i]];}
    3.1.7 逆行移位与行移位类似,Plaintext[16]采用一维数组存放操作数,把它看做每行4列的矩阵,所以第k行i列即为plaintext[4*k+i ]。由于AES采用列存放数据,而这里plaintext采用顺序存放,相当于行存放,即为列存放的转置矩阵,所以进行逆行移位时即应该进行相应的逆列移位:
    逆列变换(逆行移位)情况如下图所示:

    void CAESDlg::ShiftDown(int i){ int j,k,temp; for(j=0;j<i;j++) { temp=plaintext[12+i]; for(k=2;k>=0;k--) plaintext[4*(k+1)+i]=plaintext[4*k+i]; plaintext[i]=temp; }}void CAESDlg::InvShiftRows(){ int i; for(i=1;i<4;i++) ShiftDown(i);}
    3.1.8 逆列混合与列混合类似,把一维数组plaintext[16]看做4行4列,则i行j列即为4*i+j , 逆列混合即为两个矩阵相乘,由于AES采用列存放数据,而这里plaintext采用顺序存放,相当于行存放,即为列存放的转置矩阵,所以另一个矩阵也转置,相乘后仍然是AES列混合后的转置矩阵:
    相当于下面两个矩阵相乘:

    int CAESDlg::gfmultby09(int b){ return (gfmultby02(gfmultby02(gfmultby02(b)))^b );}int CAESDlg::gfmultby0b(int b){ return (gfmultby02(gfmultby02(gfmultby02(b)))^gfmultby02(b)^b);}int CAESDlg::gfmultby0d(int b){ return (gfmultby02(gfmultby02(gfmultby02(b)))^gfmultby02(gfmultby02(b))^(b));}int CAESDlg::gfmultby0e(int b){ return (gfmultby02(gfmultby02(gfmultby02(b)))^gfmultby02(gfmultby02(b))^gfmultby02(b) );}void CAESDlg::InvMixColumns() { int i,temp[16]; memcpy(temp,plaintext,64); for(i=0;i<4;i++) { plaintext[4*i]=gfmultby0e(temp[4*i+0]) ^ gfmultby0b(temp[4*i+1]) ^ gfmultby0d(temp[4*i+2]) ^ gfmultby09(temp[4*i+3]); plaintext[4*i+1]=gfmultby09(temp[4*i+0]) ^ gfmultby0e(temp[4*i+1]) ^ gfmultby0b(temp[4*i+2]) ^ gfmultby0d(temp[4*i+3]); plaintext[4*i+2]=gfmultby0d(temp[4*i+0]) ^ gfmultby09(temp[4*i+1]) ^ gfmultby0e(temp[4*i+2]) ^ gfmultby0b(temp[4*i+3]) ; plaintext[4*i+3]=gfmultby0b(temp[4*i+0]) ^ gfmultby0d(temp[4*i+1]) ^ gfmultby09(temp[4*i+2]) ^ gfmultby0e(temp[4*i+3]); }}
    3.1.9 加密先一轮密钥加AddRoundKey(0),再进入主循环,依次进行字节替换SubByte()、行移位ShiftRows()、列混合MixColumns()、密钥加AddRoundKey(round)运算,循环9次,再做一次字节替代SubByte()、行移位ShiftRows()、密钥加AddRoundKey(Nr)运算,完成加密:
    void CAESDlg::Cipher(){ …… AddRoundKey(0); for (int round = 1; round < Nr; ++round) // main round loop { SubByte(); ShiftRows(); MixColumns(); AddRoundKey(round); } // main round loop SubByte(); ShiftRows(); AddRoundKey(Nr);}
    3.1.10 解密先一轮密钥加AddRoundKey(Nr),再进入主循环,依次进行逆行移位InvShiftRows()、逆字节替换InvSubBytes()、密钥加AddRoundKey(round)、逆列混合InvMixColumns()运算,循环9次,再做一次逆行移位InvShiftRows()、逆字节替代InvSubBytes()、密钥加AddRoundKey(0)运算,完成解密:
    void CAESDlg::InvCipher(){ AddRoundKey(Nr); for (int round=Nr-1;round>=1;round--) // main round loop { InvShiftRows(); InvSubBytes(); AddRoundKey(round); InvMixColumns(); } // main round loop InvShiftRows(); InvSubBytes(); AddRoundKey(0);}
    3.2 较高要求部分3.2.1 明文分组实现输入的明文存在m_text中,length为输入的明文的总长度,每次循环Cipher()只处理128位,长于128位的暂不处理,留作下一轮处理,不足128位的在Cipher()处理的过程中已做了填充处理;每轮k加1,tag*k就指向m_text中没处理的明文的第一个字符,经过变换后,temp中的存放的就为没处理的明文,再将temp中的前128位取出处理,依次循环直到最后处理完明文为止。
    void CAESDlg::OnBUTTONCipher() {…………….. do{ temp=""; Cipher(); Show(); k++; if(length>tag*k) { for(int i=0;i<tag&&i<length-tag*k;i++) { test.Format("%c",m_text[tag*k+i]); temp+=test; } if(m_RadioInputTextHex==0) InputHex(temp,plaintext,Nb); else CharToHex(temp,plaintext,Nb); } }while(length>tag*k);…………………}
    3.2.2 明文最后分组的填充明文首先是以字符串形式读入的,每次处理一个分组,处理时再根据相应的输入模式调用相应的函数在字符串中取值存到plaintext[16]数组中进行处理。
    当为字符输入模式时,调用CharToHex()函数,每次处理取字符串的前16个字符换成ASCII码作为一个分组进行处理,直到最后一个分组,若不足16个字符,不足部分填充0;当为16进制输入模式时,调用InputHex ()函数,每次处理取字符串的前32个字符换成相应的16进制代码进行处理,直到最后一个分组,若不足32个字符时,不足部分填充0;
    void CAESDlg::CharToHex(CString str,int *array,int n){ int i; for(i=0;i<str.GetLength()&&i<n;i++) array[i]=str[i]; if(str.GetLength()<Nb) for(i=str.GetLength();i<n;i++) array[i]=0;}void CAESDlg::InputHex(CString strCS,int *array,int n){ int i,high[16],low[16]; string str; str=strCS; for(i=0;i<n;i++) { if(str[2*i]>=47 && str[2*i]<=57) high[i]=(int)str[2*i]-48; else if(str[2*i]>=65 && str[2*i]<=70) high[i]=(int)str[2*i]-55; else if(str[2*i]>=97 && str[2*i]<=102) high[i]=(int)str[2*i]-87; else high[i]=0; if(str[2*i+1]>=47 && str[2*i+1]<=57) low[i]=(int)str[2*i+1]-48; else if(str[2*i+1]>=65 && str[2*i+1]<=70) //大写字母A--F low[i]=(int)str[2*i+1]-55; else if(str[2*i+1]>=97 && str[2*i+1]<=102) //小写字母a---f low[i]=(int)str[2*i+1]-87; else low[i]=0; } for(i=0;i<n;i++) array[i]=high[i]*16+low[i];}
    3.2.3 密钥的填充与截取密钥的填充与明文的填充类似,不同的是密钥只处理一个分组。
    当为字符输入模式时,调用CharToHex()函数处理,若密钥长度不足16个字符时,在把密钥换成16进制ASCII码存入key[16]数组中后,不足部分填充0,填满后作为一个密钥再进行相应的处理,实现密钥的填充;若密钥长度大于16,则只取前16个字符换成16进制ASCII码存入key[16]数组中作为一个密钥,忽略后面的字符,实现密钥的截取;
    当为16进制输入模式时,调用InputHex ()函数处理,若密钥长度不足32个字符时,在把密钥换成16进制代码存入key[16]数组中后,不足部分填充0,填满后作为一个密钥再进行相应的处理,实现密钥的填充;若密钥长度大于32,则只取取前32个字符换成16进制代码存入key[16]数组中作为一个密钥,忽略后面的字符,实现密钥的截取;
    3.2.4 文本文件加密文本文件加密与字符加密大致相同。从文本文件中读入字符串,相当于字符加密的字符输入模式,然后再调用相应的加密函数对字符串进行分组加密,加密结果输出为16进制值,加密结束后再把加密结果写入一个新的文本文件(加密文件Hex.txt)中,完成文本文件的加密。
    void CAESDlg::OnBUTTONFileCipher() { ……………………………….. FileInitialize(); CharToHex(m_FileData,plaintext,Nb); InitKey(); m_progress.SetPos(50); tag=Nb; strFileHex=""; do{ temp=""; CipherFile(); for(i=0;i<Nb;i++) { test.Format("%02x",plaintext[i]); strFileHex+=test; } k++; if(length>tag*k) { for(int i=0;i<tag&&i<length-tag*k;i++) { test.Format("%c",m_FileData[tag*k+i]); temp+=test; } CharToHex(temp,plaintext,Nb); } }while(length>tag*k); ……………………….}
    3.2.5 文本文件解密文本文件解密与字符解密大致相同。从文本文件中读入字符串,相当于字符解密的16进制输入模式,然后再调用相应的解密函数对字符串进行相应的分组解密,解密结果输出为字符型,解密结束后再把解密结果写入一个新的文本文件(解密文件Char.txt)中,完成文本文件的解密。
    void CAESDlg::OnBUTTONFileInvCipher() { ………………………. FileInitialize(); InputHex(m_FileData,plaintext,Nb); InitKey(); m_progress.SetPos(50); tag=Nb*2; strFileChar=""; do{ temp=""; InvCipherFile(); for(i=0;i<Nb;i++) { test.Format("%c",plaintext[i]); strFileChar+=test; } k++; if(length>tag*k) { for(int i=0;i<tag&&i<length-tag*k;i++) { test.Format("%c",m_FileData[tag*k+i]); temp+=test; } InputHex(temp,plaintext,Nb); } }while(length>tag*k); ………………………….}
    3.3 程序界面预览为方便测试,设置明文和密钥的默认值为标准值。
    待处理的文本框输入明文或密文进行加密或解密;可以选择为16进制输入或字符输入;密钥输入框输入加密或解密密钥,可以选择为16进制输入或字符输入。若选择为16进制模式输入,若不为有效的16进制代码,则当做0处理;若选择为字符模式输入,可以输入任意英文字符。
    输入待处理明文/密文后,点击加密按钮或解密按钮进行加密或解密处理。
    处理后的结果有两种显示方法,即16进制显示(显示处理后的16进制值)和字符显示(显示处理后的16进制值对应的字符);
    两个换序按钮能方便的分别将处理后的两个结果框中对应的字符换到待处理的文本框中,进行验证加密/解密的正确性,或再进行多次加密处理。
    右边中间输出结果框显示了每一轮使用的密钥,以及每一轮中字节替代、行移位、列混合,密钥加等每一步操作之后的16进制表示的值。
    进度条显示加密的进度。
    初始化按钮能回到最初的默认状态。方便测试。
    文本加密,点击浏览按钮来选择文本路径。
    文件加密密钥输入同字符加密的密钥输入一样,可以选择为16进制输入或字符输入,输入密钥对文本文档进行处理。
    选择了文本文档路径,输入了文件加密/解密密钥后,点击对应的加密或解密按钮,进行文本文件加密或解密处理。

    4 测试报告4.1 字符加密/解密检测:
    明文:00112233445566778899aabbccddeeff (16进制输入模式)
    密钥:000102030405060708090a0b0c0d0e0f (16进制输入模式)
    加密结果:69c4e0d86a7b0430d8cdb78070b4c55a (16进制表示)

    对照标准,输入明文和密钥,经过加密后运行结果与标准相同,中间每步的处理结果也与标准相同,按下16进制显示框对应的换序按钮,再进行相应的解密能得到正确的明文。
    将Text输入方式和key输入方式换成字符输入模式,在明文输入框和密钥输入框中均输入超过1个分组长度的英文字符(包括英文特殊字符)进行加密:
    明文

    密钥

    加密结果

    点击16进制显示框对应的换序按钮,把加密结果的16进制值换到待处理文本输入框中进行解密:
    密文

    密钥

    解密结果

    将明文和密钥的输入方式换成字符输入模式,在明文输入框和密钥输入框中均输入超过1个分组长度的英文字符(包括英文特殊字符)进行加密,用加密得到的16进制值(在16进制显示框中)进行解密,能得到正确的字符(在字符显示框中显示)。
    4.2 文本文档加密/解密检测test.txt文件内容

    文件加密

    加密结果

    解密

    解密结果

    经过检测:

    本软件能对字符和文本文档进行正确的加密和解密,加密和解密结果没有错误
    对于不足128bit的明文分组,最后填充0补满128bit
    对于不足128bit的密钥,填充0补满128bit;对于超过128bit的密钥,只截取前128bit
    没有发现导致致命错误的操作方法

    5 结论通过这次的课程设计,对AES的算法有了更深入的了解:字节代换的仿射变换可用S盒表示;对于不同的分组行移位也是不同的;列混合中的计算则要用到GF(28)上的多项式,再与一个固定的多项式C(x)进行模X4+1的乘法,而C(x)是固定的,而且最后一轮没用列混合。虽然此软件能顺利完成对英文字符和文本文档的加密,但也还存在很多不足,如:不能对汉字进行处理,不能处理其他格式的文件、文件夹等,只支持128bit的密钥,没有实现192bit,256bit密钥长度的加密,还需要进一步完善。
    参考文献[1] 谭浩强. C程序设计(第二版). 清华大学出版社. 1999
    [2] 张海藩. 软件工程导论(第四版). 清华大学出版社. 2003
    [3] 杨波. 现代密码学. 清华大学出版社. 2003
    [4] 黄维通. Visual C++面向对象与可视化程序设计. 清华大学出版社. 2000
    [5] 张福泰. 密码学教程(第一版). 武汉大学出版社. 2006
    2 评论 63 下载 2018-12-02 17:07:14 下载需要7点积分
  • 基于C语言实现的校园导航

    一、设计目的现在的大学占地面积越来越大,建筑物越来越多,功能越来越多样,校内的道路也是纵横交错,校园导航系统可以帮助用户更加快速的了解学校的路线,建筑布局及建筑物的基本信息等(用户主要是新生、家长、教职工、外来参观人员等),在帮助用户了解校园路线、实现导航的功能的基础上,校园导航系统还录入了学校各个地点的相关信息,以供使用者更方便快捷的找到目的地。
    随着科学技术的不断发展,计算机科学日渐成熟,其强大的功能已为人们所深刻认识,它己进入人类社会的各个领域并发挥着越来越重要的作用。采用计算机进行校园导航已成为衡量校园数字化的重要标志。校园导航效率的好坏对于来校参观的客人和学校管理者来说都至关重要,在很大程度上影响着校园的数字化建设和学校的影响力。因此,本次课程设计研究的校园导航系统具有一定的使用价值和现实意义。
    二、设计内容该校园导航的使用者分为游客和管理者,功能如下:

    游客

    针对游客的校园导航使用说明查看校园全景图,附有校园地点的所有路线情况输入任意地点,查询该地点的信息,包括地点介绍和相关路线输入任意两地点,输出两点之间的所有简单路线输入任意两地点,输出两点之间的一条中转次数最少的最短路线输入任意两地点,输出两点之间的一条带权路径最短的最有路线输入任意地点,输出从该点出发的最佳布网方案
    管理员(除游客功能外,还有以下功能)

    使用管理员功能首先需要登录,登陆成功方可使用导航管理员功能可以在地图中添加新地点可以在地图中添加新路线可以在地图中撤销旧路线注册新的管理员帐号

    三、概要设计3.1 功能模块图
    3.2 各个模块详细的功能描述
    导航使用说明:描述该导航应该如何使用,具有什么功能
    校园平面简图:输出一张有校园所有地点的平面图,可以直观的看出校园地点的分布。这是利用了每个地点所存储的坐标,通过对矩阵元素的遍历,输出了各地点的具体方位。并且在平面图下面以这样的形式附有校园两地点相连的所有路线信息:起点<—->终点:xxx m
    查看地点信息:任意输入一个地点序号,输出该地点的介绍,以及所有与该地点连通的路线及其距离
    查询简单路径:任意输入两个地点,输出两地点间所有的简单路径。利用图的深度搜索遍历,用栈将经过的地点序号存起来,然后每条路线的地点逐个输出,最后得到所有简单路径
    查询最短路径:任意输入两个地点,输出两地点间一条中转次数最少的路线。利用图的广度搜索遍历,用队列将要遍历的地点存起来,通过对队列的操作得到中转次数最少的路线
    查询最优路径:任意输入两个地点,输出两地点间一条带权路径最短的路线。利用迪杰斯特拉算法,通过对dist和 path的操作得出最终的最短路线
    最佳布网方案:任意输入一个地点,输出从该点出发的最佳布网方案。这是利用了最小生成树的思想,运用了Prim算法的思想
    添加新地点:输入新地点的名称和坐标,通过对文件增删改的操作,将新地点存储到文件里,就生成了一张新地图
    添加新路线:输入新路线的起点、终点 、距离,通过对文件增删改的操作,将新路线存储到文件里,就生成了一条新路线
    撤销旧路线:输入要撤销路线的起点、终点、距离,通过对文件增删改的操作,将改动后的路线信息存储到文件里
    管理员的登录:管理员可在此输入帐号和密码进行登录,在输入密码时也可以选择是否隐藏密码,如果输入帐号密码不对应,则可重新输入,若错误三次则自动退出系统。通过对用户输入的帐号密码和“admin.txt”文件里保存的帐号密码进行比较,如果相同则可登录
    管理员的注册:管理员可在此输入帐号和密码进行注册,密码需要输入两遍,相同则注册成功。通过对“admin.txt”文件增删改的操作,将新帐号和密码存储到文件里,就生成了一个新的管理员帐号
    队列的操作:有队列的判空、队列的初始化、出队、入队函数
    创建无向图:采用邻接矩阵的结构,通过对“路线信息”文件和“地点介绍”文件的读取,将信息存储到邻接矩阵中,然后创建出带权无向图
    游客和管理员菜单:游客和管理员可在其对应的菜单页面进行功能选择

    四、详细设计4.1 功能函数的调用关系图总体函数调用关系图

    所有简单路线函数:SearchDFS()

    中转次数最少路线函数:SearchBFS()

    带权路径最短路线函数:Shortcut()

    最佳布网方案函数:MiniSpanTree()

    4.2 重点设计及编码数据结构类型的选择:邻接矩阵
    #define MAXVEX 50#define INFINITY 32768typedef struct //保存地点信息的结构体{ int No; //校园地点序号 char name[20]; //校园地点名 char description[200]; //地点描述}Vextype;typedef struct //邻接矩阵{ int arcs[MAXVEX][MAXVEX]; //边集 Vextype vex[MAXVEX]; //顶点集 int vexnum; //顶点数目 int arcnum; //边数目}AdjMatrix;typedef struct //坐标矩阵{ int point; //该点是否有校园地点 char name[20]; //该点校园地点名 int No; //该点校园地点序号}SchoolMap;
    创建带权无向图
    int Create(AdjMatrix *G,SchoolMap M[MAXL][MAXC]){ int i,j,weight,m,n; FILE *fp1; fp1=fopen("路线信息.txt","r"); //从"路线信息.txt"文件中读取校园图的景点数目和路线数目 fscanf(fp1, "%d %d", &G->vexnum, &G->arcnum); //初始化邻接矩阵 for(i = 1; i <= G->vexnum; i++) for(j = 1; j<= G->vexnum; j++) { G->arcs[i][j] = INFINITY; } //读取"路线信息.txt"文件中两点序号及距离,并赋值给邻接矩阵 while(fscanf(fp1,"%d %d %d",&i,&j,&weight) != EOF) { G->arcs[i][j] = weight; G->arcs[j][i] = weight; } fclose(fp1); FILE *fp2; fp2 = fopen("地点介绍.txt", "rt"); //从"地点介绍.txt"文件中读取校园图中的景点名及描述 for(i = 1; i <= G->vexnum; i++) { G->vex[i].No = i; fscanf(fp2,"%s %d %d %s",G->vex[i].name,&m,&n,G->vex[i].description); M[m][n].point = 1; M[m][n].No = i; strcpy(M[m][n].name,G->vex[i].name); } fclose(fp2); return 1;}
    查询所有简单路径:深度搜索遍历DFS算法
    void DFS(AdjMatrix *G, int m, int i, int end){ int j,k; for(j = 1; j <= G->vexnum; j++){ if(G->arcs[i][j] != INFINITY && visited[j] == 0) { visited[j] = 1; if(j == end) { count++; printf("★%d.",count); for(k = 1; k < m; k++) { printf("%s->", G->vex[stack[k]].name); } printf("%s\n", G->vex[end].name); visited[j] = 0; } else { stack[m] = j; m++; DFS(G, m, j, end); m--; visited[j] = 0; } } }}
    查询中转次数最少路径:广度搜索遍历BFS算法
    void BFS(AdjMatrix *G, int start, int end){ int vis[INFINITY]; int i, num; int w, v; LinkQueue *Q; Q=(LinkQueue*)malloc(sizeof(LinkQueue)); if(start == end) return; memset(vis, 0, INFINITY); vis[start] = 1; InitQueue(Q); EnterQueue(Q, start); while(Q->front != Q->fear){ DeleteQueue(Q, &v); num = v; for(i = 1;i <= G->vexnum; i++){ if(G->arcs[num][i] != INFINITY) { w = i; //求出当前节点的第一个邻接点(求出序号) while(w != -1){ if(vis[w] == 0){ if(w == end){ BFS(G, start, num); printf("%s->",G->vex[num].name); return; } vis[w] = 1; EnterQueue(Q, w); w = NextAdjVertex(G, w, v);//是求的得第一个邻接点,V是相对w下一个邻接点(求出下一个邻接点的序号) }break; } } }}
    查询带权路径最短:Dijkstra算法
    void Dijkstra(AdjMatrix *G, int start, int end, int dist[], int path[][MAXVEX]){ int mindist, i, j, k, t = 1; for(i = 1; i <= G->vexnum; i++) { dist[i] = G->arcs[start][i]; //对dist数组初始化 if(G->arcs[start][i] != INFINITY) path[i][1] = start; //如果该弧存在,则path[i][1]为源点 } path[start][0] = 1; //start加入到S中 for(i = 2; i <= G->vexnum; i++) { //寻找各条最短路径 mindist = INFINITY; for(j = 1; j <= G->vexnum; j++) if(!path[j][0] && dist[j] < mindist) { k = j; mindist = dist[j]; } if(mindist == INFINITY) return ; path[k][0] = 1; //找到最短路径,将该点加入到S集合中 for(j = 1; j <= G->vexnum; j++) { //修改路径 if(!path[j][0] && G->arcs[k][j] < INFINITY && dist[k]+G->arcs[k][j] < dist[j]) { dist[j] = dist[k] + G->arcs[k][j]; t = 1; while(path[k][t] != 0) { path[j][t] = path[k][t]; t++; } path[j][t] = k; path[j][t+1] = 0; } } } for(i = 1; i <= G->vexnum; i++) if(i == end) break; printf("\n ★★★%s--->%s的最短路线为: 从%s",G->vex[start].name,G->vex[end].name,G->vex[start].name); for(j = 2; path[i][j] != 0; j++) { printf("->%s",G->vex[path[i][j]].name); } printf("->%s, 距离为%d m\n",G->vex[end].name,dist[i]); printf("\n\t\t\t\t\t按任意键返回..."); getch();}
    最佳布网方案:最小生成树Prim算法
    void Prim(AdjMatrix *G, int start){ struct { int adjvex; int lowcost; }closedge[MAXVEX]; int i, e, k, m, min; closedge[start].lowcost = 0; //对除了出发点以外deep所有顶点初始化对应的closedge数组 for(i = 1; i <= G->vexnum; i++) { if(i != start) { closedge[i].adjvex = start; closedge[i].lowcost = G->arcs[start][i]; } } for(e = 1; e <= G->vexnum-1; e++) //控制选中的n-1条符合条件的边 { //选择权值最小的边 min = INFINITY; for(k = 1; k <= G->vexnum; k++) { if(closedge[k].lowcost != 0 && closedge[k].lowcost < min) { m = k; min = closedge[k].lowcost; } } printf("\t\t\t\t\t从%s---%s:%d m\n", G->vex[closedge[m].adjvex].name,G->vex[m].name,closedge[m].lowcost); closedge[m].lowcost = 0; for(i = 1; i <= G->vexnum; i++) { if(i != m && G->arcs[m][i] < closedge[i].lowcost) { closedge[i].lowcost = G->arcs[m][i]; closedge[i].adjvex = m; } } } printf("\n\t\t\t\t\t按任意键返回..."); getch();}
    五、测试数据及运行结果5.1 正常测试数据和运行结果导航游客使用说明

    校园平面简图


    查看地点信息

    查询简单路径

    中转次数最少的路径

    带权路径最短

    最佳布网方案

    管理员登录


    导航管理员使用说明

    添加新地点

    添加新路线

    撤销旧路线

    注册新的管理员帐号

    主菜单

    5.2 异常测试数据和运行结果查看地点信息

    查询简单路径

    中转次数最少的路径

    带权路径最短

    最佳布网方案

    管理员登录

    添加新地点

    添加新路线

    撤销旧路线

    注册管理员

    主页面输入

    游客菜单输入
    1 评论 131 下载 2018-11-07 17:32:26 下载需要8点积分
  • 基于JSP实现的个人网站

    摘 要本报告是JSP程序设计的期末设计的课程设计报告。本网站基本满足了所有需要的内容和功能需求,包含了个人的简介,家乡的介绍,包括个人的信息,留言板等内容。
    也包含了数据库的增(用户注册,留言板的留言等),删(个人留言支持删除),改(个人信息的修改等),查(留言板的查看,个人信息的查看等)四个功能。数据库的3张表,包括用户登录信息表,用户个人信息表,留言板内容表。
    主题:JSP、增删改查、数据库、个人服务器
    1、系统设计背景意义1.1 开发背景随着WWW(World Wide Web)的普及,动态网页技术也急速发展。从原来的CGI(Common Gateway In-terface)到ASP(Active Server Page),都从某种程度上满足了网页开发人员对动态网页开发技术的需求。但是不管是CGI还是ASP都存在一定的局限性,如CGI对服务器资源的耗费,ASP只能同Microsoft IIS一起使用等,这些都限制了这些技术的使用范围,极大地阻碍了它们的推广。
    广大的页面开发人员都热切地盼望一种统一的页面开发技术,该技术应该具有的特点:

    与操作平台无关,能够在任何Web或应用程序服务器上运行
    将应用程序逻辑和页面显示分离
    提供代码重用,简化开发基于Web的交互式应用程序的过程

    JSP(Java Server Page)技术就是被设计用来满足这样的要求的。JSP是由Sun MicroSystem公司于1999年6月推出的新的网页开发技术,它是基于Java Serv-let以及整个Java体系的Web开发技术,是Servlet2.1API的扩展。利用这一技术,可以建立先进、安全和跨平台的动态网站。
    1.2 研究现状JSPJava语言以不依赖于平台、面向对象、安全等优良特性成为网络程序设计语言中的佼佼者。目前,许多与Java有关的技术得到了广泛的应用与认可,JSP(JavaServerPages)就是其中之一。JSP是基于Java语言的一种Web应用开发技术,可以建立安全、跨平台的先进动态网站。
    许多Web网站都使用了JSP技术。利用JSP技术创建的Web应用程序可以实现动态页面与静态页面分离,便于Web应用程序的扩展和维护。由于JSP是基于Java语言的Web技术,相对其他Web技术,JSP具有脱离硬件平台束缚、编译后运行等优点,已成为Internet上的主流Web技术之一。
    2 、需求分析2.1 系统需求分析设计一个个人网站,网站内容必须包括个人的基本信息(含个人照片),比如个人爱好,家乡特产、特色旅游等静态网页内容;必须调用数据库,且具备数据库的增删改查的功能,这是动态网页部分内容。
    2.2 数据需求需要一个数据库,包括三张数据表,分别记录用户的登录信息,记录用户每个人的用户信息,记录用户的留言内容。
    3 、系统设计3.1 系统原理
    3.2 数据库设计3.2.1 数据库概念结构设计数据库概念结构设计是在需求分析的基础上,设计出能够满足用户需求的各种实体,以及它们之间的关系,为后面的逻辑结构设计打下基础。用E-R图是描述数据实体关系的一种直观描述工具,所以本系统采用了E-R图的方法进行数据库概念结构设计。
    用户登陆E-R图

    用户实体E-R图

    留言板E-R图

    实体之间关系E-R图

    3.3.2 数据库逻辑结构设计概念结构是独立于实际数据模型的信息结构,必须将其转化为逻辑结构后才能进行数据库应用的设计。也就是要将概念上的结构转化为BP数据库系统所支持的实际数据模型。
    个人网站数据库中各个表格的设计结果如下面的四个表所示。每个表表示数据库中的一个表。
    用户登录表

    username:记录用户注册时的用户名
    password:记录用户注册时的密码

    且用户名和密码均不能为空值,所以在提交到数据库之前已经在网页中进行检查。


    用户留言板表

    username:记录留言的用户
    date:记录用户留言的时间,精确到秒。格式为“YYYY-MM-DD HH-MM-SS”
    message:记录用户留言的内容,格式为TEXT

    注:date的记录利用数据库自带的now()函数,方便网页的内容的传输。


    用户信息表

    username:记录个人信息的所有者
    gender:记录用户的性别
    age:记录用户的年龄
    phone_number:记录用户的联系方式
    school:记录用户的所在学校
    address:记录用户的地址



    3.4 系统模块设计
    4、系统实现4.1 欢迎页(index.jsp)本页是网站的第一页,可以选择用户登录(login.jsp)或者跳过登录直接进去主页(Home.jsp),如果没有注册,可以点击注册按钮,进入注册页面(register.jsp)。
    效果示意图:

    <%@ page language="java" contentType="text/html; charset=utf-8"%><!DOCTYPE html><html><head><style> body{ text-align:center; background: url("./img/bg.jpg") fixed center center no-repeat; background-size: cover; width: 100%; } #center{ margin:0 auto; border:1px soild #000; width:300px; height:100px } *{ padding: 0; margin: 0; } .black_half{ padding: 25px; background-color: rgba(0,0,0,0.5); } .black_half h1{ color: #FFFFFF; } .black_half a{ text-decoration:none; color: #FFFFFF; } .black_half a:hover{ text-decoration:underline; color: #FFFFFF; } .white h3{ color: #FFFFFF; }</style><title>欢迎——…的期末作业</title></head><body> <br><br> <div class="black_half"> <h1>W E L C O M E !</h1> </div> <div class="black_half"> <h2> <a href="login.jsp">用户登陆</a>   <a href="register.jsp" style="font-size:12px;">还没有账号?点此注册</a> </h2><br> <h2> <a href="Home.jsp">我是游客,跳过登录</a> </h2> </div> <br><br> <div class="white"> </div></body></html>
    4.2 主页(Home.jsp)本页面是网站的主页,内容比较简单。
    最上端的是导航栏,如果前面选择了登陆,则左上角会显示“您好,xxx”,可以选择退出登录,右边导航栏也会多一个“个人信息”按钮,可以进入个人信息页面(details.jsp)。
    如果未登录,会显示“您还未登陆,点击登录” ,可以选择登录按钮,进入(login.jsp)。
    右边导航栏的其他按钮还包括作者简介(profile.jsp)、家乡介绍(hometown.jsp)、留言板(board.jsp)、关于(about.jsp)、返回欢迎页(index.jsp)。
    效果示意图:

    <!DOCTYPE html><html><head> <title>主页</title><style> @import"home_style.css"</style></head><body style=" font-size: 16px; line-height: 1.4em; letter-spacing: 0.08em; padding: 0; margin: 0; background: url('./img/bg.jpg') fixed center center no-repeat; background-size: cover; width: 100%;"> <div class="ace-head-inner"> <div class="ace-head-container ace-container"> <div class="ace-head-row"> <div id="ace-head-col1" class="ace-head-col text-left"> <span> <% String username = (String)session.getAttribute("username"); if (username != null){ out.println("您好,"+username+" <a href='logout.jsp'>退出登陆</a>  "); } else{ out.println("您还未登陆 <a href='login.jsp'>点此登陆</a>  "); } %> </span> </div> <nav id="ace-main-nav"> <ul class="clear-list"> <% if (username != null){ out.println("<li><a href='details.jsp'>个人信息</a></li>"); } %> <li><a href="Home.jsp">主页</a></li> <li><a href="profile.jsp">作者简介</a></li> <li><a href="hometown.jsp">家乡介绍</a></li> <li><a href="board.jsp">留言板</a></li> <li><a href="about.jsp">关于</a></li> <li><a href="index.jsp">返回欢迎页</a></li> </ul> </nav> </div> </div></div><div class = white_box> <p style="font-size:200px;">你好。</p> <p style="font-size:200px;" align="right">欢迎。</p></div></body></html>
    4.3 注册(register.jsp/checkregister.jsp)本页面是网站的注册页面,包含两个jsp文件,register.jsp获取用户输入的表单,包括用户名和两次密码,在通过js函数判断(判断用户名、密码是否为空,两次密码是口相同)之后通过onsubmit的方法决定是否将表单传送给checkregister.jsp。
    如果通过判断,checkregister.jsp连接数据库并先用select查询是否存在用户名相同的用户,如果不存在用insert的sql语句把用户信息输入数据库,并返回注册成功或者失败的提示框,如果成功跳转到主页,如果失败跳转回注册页面。
    效果示意图:

    register.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><!DOCTYPE html><html><head><title>用户注册</title></head><style> @import"style.css"</style><script> function addCheck() { var username = document.regfrm.username.value; var password = document.regfrm.password.value; var double_times = document.regfrm.double_times.value; if (username == "") { alert("用户名不能为空!"); return false; } if (password == "") { alert("密码不能为空!"); return false; } if (password != double_times) { alert("两次输入密码不相同!"); return false; } } function validate() { var flag = addCheck(); if (flag == false) return false; return true; }</script><body> <div id = center> <form action="checkregister.jsp" method="post" name = "regfrm" onsubmit="return validate();"> <table class="hovertable"> <tr> <td colspan="5" align="center" style="font-size:30px;height:80px;width:300px;"><strong>注册</strong></td> </tr> <tr > <th>用户名:</th> <td><input type="text" name="username" value="输入16个字符以内" maxlength="16" onfocus="if(this.value == '输入16个字符以内') this.value =''"></td> </tr> <tr> <th>输入密码:</th> <td><input type="text" name="password" value="输入20个字符以内" maxlength="20" style="width:200px;" onfocus="if(this.value == '输入20个字符以内'){this.value =''; this.type='password'}"></td> </tr> <tr> <th>确认密码:</th> <td><input type="text" name="double_times" value="请再次输入密码" maxlength="20" style="width:200px;" onfocus="if(this.value == '请再次输入密码') {this.value =''; this.type='password'}"></td> </tr> <tr> <td colspan="2" align="center"> <input type="submit" value=" 注 册 "> <input type ="button" value=" 返回登陆 " onclick="location='login.jsp'"> </td> </tr> <tr> <td colspan="5" align="center"><a href="index.jsp"> 返 回 主 页 </a></td> </tr> </table> </form> </div></body></html>
    checkregister.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ page import = "java.sql.*" %><!DOCTYPE html><html><body> <% String user = new String(request.getParameter("username").getBytes("ISO8859_1"),"utf-8"); String pwd = new String(request.getParameter("password").getBytes("ISO8859_1"),"utf-8"); Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/user_data"; String um = "root"; String psw= "8876"; Connection conn = DriverManager.getConnection(url, um, psw); PreparedStatement pStmt = conn.prepareStatement("select * from user_data.user_info where username = '" + user + "'"); ResultSet rs = pStmt.executeQuery(); if(rs.next()){ out.println("<script language='javascript'>alert('该用户已存在,请直接登陆!');window.location.href='register.jsp';</script>"); } else{ PreparedStatement tmt = conn.prepareStatement("Insert into user_data.user_info values('" + user + "','" + pwd + "')"); int rst = tmt.executeUpdate(); if (rst != 0){ PreparedStatement tmt2 = conn.prepareStatement("Insert into user_data.details values('" + user + "',1,0,' ',' ',' ')"); tmt2.executeUpdate(); out.println("<script language='javascript'>alert('用户注册成功!');window.location.href='login.jsp';</script>"); } else{ out.println("<script language='javascript'>alert('用户注册失败!');window.location.href='register.jsp';</script>"); } } %></body></html>
    4.4 登陆(login.jsp/checklogin.jsp)本页面是网站的登陆页面,包含两个jsp文件,login.jsp获取用户输入的表单,包括用户名和两次密码,在通过js函数判断(判断用户名、密码是否为空)之后通过onsubmit的方法决定是否将表单传送给checklogin.jsp。
    如果通过判断,checklogin.jsp连接数据库并通过select的sql语句查询数据库中用户信息,如果成功显示登陆成功的消息框并跳转到主页,如果失败显示登陆失败的消息框跳转回登陆页面。
    效果示意图:

    login.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><!DOCTYPE html><html><head><title>用户登陆</title></head><style> @import"style.css"</style><script> function validateLogin() { var userName = document.frmLogin.username.value; var password = document.frmLogin.password.value; if ((userName == "") || (userName == "输入您的用户名")) { alert("请输入用户名!"); return false; } if ((password == "") || (password == "输入您的密码")) { alert("请输入密码!"); return false; } }</script><body> <div id = "center"> <form action="checklogin.jsp" method="post" name="frmLogin"> <table class="hovertable" > <tr> <td colspan="5" align="center" style="font-size:30px;height: 80px;width:300px;"><strong>登陆</strong></td> </tr> <tr> <th style="font-size:15px;">用户名:</th> <td style="font-size:15px;"><input type="text" name="username" value="输入您的用户名" maxlength="16" style="width:200px;" onfocus="if(this.value == '输入您的用户名') this.value =''"></td> </tr> <tr> <th style="font-size:15px;">密 码:</th> <td style="font-size:15px;"><input type="text" name="password" value="输入您的密码" maxlength="20" style="width:200px;" onfocus="if(this.value == '输入您的密码'){this.value =''; this.type='password'}"></td> </tr> <tr> <td colspan="5" align="center" style="font-size:15px;"> <input type="submit" value=" 登 录 " onclick="return validateLogin()"> <input type ="button" value=" 新用户注册 " onclick="location='register.jsp'"> </td> </tr> <tr> <td colspan="5" align="center"><a href="index.jsp"> 返 回 主 页 </a></td> </tr> </table> </form> </div></body></html>
    checklogin.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ page import = "java.sql.*" %><!DOCTYPE html><html><body> <% String username = new String(request.getParameter("username").getBytes("ISO8859_1"),"utf-8"); String password = new String(request.getParameter("password").getBytes("ISO8859_1"),"utf-8"); Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/user_data"; String um = "root"; String psw= "8876"; Connection conn = DriverManager.getConnection(url, um, psw); if(conn != null){ String sql = "select * from user_data.user_info where username='"+username+"' and password='"+ password + "'"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); if(rs.next()){ session.setAttribute("username",username); out.println("<script language='javascript'>alert('登录成功!');window.location.href='Home.jsp';</script>"); } else{ out.println("<script language='javascript'>alert('登录失败!');window.location.href='login.jsp';</script>"); } } %></body></html>
    4.5 个人信息(details.jsp/setdetails.jsp/getdetails.tag)本页面是网站的个人信息页面,每次打开页面getdetails.tag都会从数据库中查询个人信息(每个新注册的用户默认都是空数据的),并显示在details.jsp中。并且可以修改表中的数据,点击修改按钮,表中的数据会以表单的形式以post的方式传递给setdetails.jsp,该setdetails可以连接数据库并通过update方式修改数据库。
    效果示意图:

    details.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ taglib tagdir = "/WEB-INF/tags" prefix="getdetails" %><%@ page import = "java.sql.*" %><!DOCTYPE html><html><head> <title>个人信息</title> <style> @import"style.css" </style></head><body><getdetails:getdetails></getdetails:getdetails> <div id = center> <form action="setdetails.jsp" method="post" name="set_details"> <table class="hovertable"> <tr> <td colspan="5" align="center" style="font-size:30px;height: 80px;width:350px;"><strong>个人信息</strong></td> </tr> <tr> <th>性别:</th> <td> <label> <input type="radio" name="gd" id="" class="a-radio" value=1 <%= gender==1?"Checked":"" %> > <span class="b-radio"></span>男 </label> <label> <input type="radio" name="gd" id="" class="a-radio" value=0 <%= gender==0?"Checked":"" %> > <span class="b-radio"></span>女 </label> </td> </tr> <tr> <th>年龄:</th> <td> <label> <input type="text" type="text" name="age" value = <%=age %> style="width:200px;" maxlength="2"> </label> </td> </tr> <tr> <th>联系方式:</th> <td> <label> <input type="text" type="text" name="phone_number" style="width:200px;" maxlength="11" value = <%=phone_number %> > </label> </td> </tr> <tr> <th>所在学校:</th> <td> <label> <input type="text" type="text" name="school" style="width:200px;" maxlength="40" value = <%=school %> > </label> </td> </tr> <tr> <th>详细地址:</th> <td> <label> <input type="text" type="text" name="address" style="width:200px;" maxlength="40" value = <%=address %> > </label> </td> </tr> <tr> <td colspan="2"> <input type = "submit" value = " 修 改 "> <input type = "button" value = " 返 回 " onclick="location='Home.jsp'"> </td> </tr> </table> </form> </div></body></html>
    setdetails.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ page import = "java.sql.*" %><!DOCTYPE html><html><body> <% String gender = new String(request.getParameter("gd").getBytes("ISO8859_1"),"utf-8"); String age = new String(request.getParameter("age").getBytes("ISO8859_1"),"utf-8"); String phone_number = new String(request.getParameter("phone_number").getBytes("ISO8859_1"),"utf-8"); String school = new String(request.getParameter("school").getBytes("ISO8859_1"),"utf-8"); String address = new String(request.getParameter("address").getBytes("ISO8859_1"),"utf-8"); String username = (String)session.getAttribute("username"); int _gender = Integer.parseInt(gender); int _age = Integer.parseInt(age); Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/user_data"; String um = "root"; String psw= "8876"; Connection conn = DriverManager.getConnection(url, um, psw); if(conn != null){ PreparedStatement tmt2 = conn.prepareStatement("UPDATE user_data.details set gender="+ _gender +",age="+ _age +",phone_number='"+ phone_number +"',school='"+ school +"',address='"+ address +"' where username='"+username+"'"); int rst = tmt2.executeUpdate(); if(rst != 0){ out.println("<script language='javascript'>alert('修改成功!');window.location.href='details.jsp';</script>"); } else{ out.println("<script language='javascript'>alert('修改失败!');window.location.href='Home.jsp';</script>"); } } %></body></html>
    getdetails.tag
    <%@ tag language="java" pageEncoding="utf-8"%><%@ tag import="java.sql.*" %><%@ variable name-given="gender" variable-class="java.lang.Integer" scope="AT_END"%><%@ variable name-given="age" variable-class="java.lang.Integer" scope="AT_END"%><%@ variable name-given="phone_number" variable-class="java.lang.String" scope="AT_END"%><%@ variable name-given="school" variable-class="java.lang.String" scope="AT_END" %><%@ variable name-given="address" variable-class="java.lang.String" scope="AT_END"%><% String username = (String)session.getAttribute("username"); if (username != null){ Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/user_data"; String um = "root"; String psw= "8876"; Connection conn = DriverManager.getConnection(url, um, psw); if(conn != null){ String sql = "select * from user_data.details where username='"+username+"'"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); if(rs.next()){ String ss = rs.getString(1); int gender = rs.getInt(2); int age = rs.getInt(3); String phone_number = rs.getString(4); String school = rs.getString(5); String address = rs.getString(6); jspContext.setAttribute("gender", gender); jspContext.setAttribute("age", age); jspContext.setAttribute("phone_number", phone_number); jspContext.setAttribute("school", school); jspContext.setAttribute("address", address); } } } else{ out.println("<script language='javascript'>alert('请先登录!');window.location.href='login.jsp';</script>"); }%>
    4.6 作者简介(profile.jsp)本页面是本网站的个人简介页面,除了导航栏之外为静态网页,简单的自我介绍。
    效果示意图:

    profile.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><!DOCTYPE html><html><head> <title>作者简介</title><style> @import"home_style.css"</style></head><body> <div class="ace-head-inner"> <div class="ace-head-container ace-container"> <div class="ace-head-row"> <div id="ace-head-col1" class="ace-head-col text-left"> <span> <% String username = (String)session.getAttribute("username"); if (username != null){ out.println("您好,"+username+" <a href='logout.jsp'>退出登陆</a>  "); } else{ out.println("您还未登陆 <a href='login.jsp'>点此登陆</a>  "); } %> </span> </div> <nav id="ace-main-nav"> <ul class="clear-list"> <%if (username != null){out.println("<li><a href='details.jsp'>个人信息</a></li>"); } %> <li><a href="Home.jsp">主页</a></li> <li><a href="profile.jsp">作者简介</a></li> <li><a href="hometown.jsp">家乡介绍</a></li> <li><a href="board.jsp">留言板</a></li> <li><a href="about.jsp">关于</a></li> <li><a href="index.jsp">返回欢迎页</a></li> </ul> </nav> </div> </div></div><div class = white_box> <div style="text-align:center;"> <br> <h1><b>作者简介——我</b><br></h1> <br> <img src="./img/myphoto.jpg" style="display:block;max-height:200px;max-width:200px;margin:0 auto;"/><br> <br> <h2 style="display:inline;">name:</h2> <br><br> <h2 style="display:inline;">pingyin:</h2> <br><br> <h2 style="display:inline;">En-name:</h2>Ray8876 <br><br> <h2 style="display:inline;">birth:</h2>1998-08 <br><br> <h2 style="display:inline;">phone:</h2>158****2095 <br><br> <h2 style="display:inline;">e-mail:</h2> <br><br> <h2 style="display:inline;">school:</h2>中国计量大学现代科技学院 <br><br> <h2 style="display:inline;">major:</h2> <br><br> <h2 style="display:inline;">class:</h2> </div></div></body> </html>
    4.7 家乡介绍(hometown.jsp)本页面是本网站的家乡介绍页面,除了导航栏之外为静态网页,大部分内容摘自乌镇导游网。本页面源代码较长且为静态网页,这里省略
    效果示意图:

    4.8 留言板4.8.1 留言板(board.jsp/getboard.tag)本页面是网站的留言板网页,每次打开页面都会调用getboard.tag,从数据库中查询所有的留言内容(SELECT * FROM user_data.board order BY date DESC;),并且按照时间倒序排序,排在最上面的为最新留言。
    第一个白框是留言的模块,第二个白框是搜索模块(search.jsp)和我的留言的链接(myboard.jsp)。
    效果示意图:

    board.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ taglib tagdir = "/WEB-INF/tags" prefix="getboard" %><!DOCTYPE html><html><head> <title>留言板</title><style> @import"home_style.css"</style></head><body style=" font-size: 16px; line-height: 1.4em; letter-spacing: 0.08em; padding: 0; margin: 0; background: url('./img/bg4.jpg') fixed center center no-repeat; background-size: cover; width: 100%;"><getboard:getboard></getboard:getboard> <div class="ace-head-inner"> <div class="ace-head-container ace-container"> <div class="ace-head-row"> <div id="ace-head-col1" class="ace-head-col text-left"> <span> <%String username = (String)session.getAttribute("username");if (username != null){out.println("您好,"+username+" <a href='logout.jsp'>退出登陆</a>  ");}else{out.println("您还未登陆 <a href='login.jsp'>点此登陆</a>  ");} %> </span> </div> <nav id="ace-main-nav"> <ul class="clear-list"> <%if (username != null){out.println("<li><a href='details.jsp'>个人信息</a></li>");} %> <li><a href="Home.jsp">主页</a></li> <li><a href="profile.jsp">作者简介</a></li> <li><a href="hometown.jsp">家乡介绍</a></li> <li><a href="board.jsp">留言板</a></li> <li><a href="about.jsp">关于</a></li> <li><a href="index.jsp">返回欢迎页</a></li> </ul> </nav> </div> </div></div><div class = white_box> <form action="checkboard.jsp" method="post"> <textarea rows="5" cols="" name="txt"></textarea> <br><br><br> <center> <input type="submit" value=" 留 言 " style="font-size:20px;" > </center> </form></div><div class = white_box> <form action="search.jsp" method="post"> <center> <input type="text" value=" 留 言 搜 索 " style="font-size:20px; display: inline;" onfocus="if(this.value == ' 留 言 搜 索 ') this.value =''" name="src"> <input type="submit" value=" 搜 索 " style="font-size:20px;" > <input type ="button" value=" 我的留言 " onclick="location='myboard.jsp'" style="font-size:20px;" > </center> </form></div><%=content %></body></html>
    4.8.2 搜索留言(search.jsp/searchboard.tag)搜索留言与留言栏内容相似,唯一的差别就是tag文件可以接收input框中的搜索的内容并且通过select语句查询包含查询内容的留言内容并返回内容。
    效果示意图:

    search.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ taglib tagdir = "/WEB-INF/tags" prefix="searchboard" %><!DOCTYPE html><html><head> <title>留言板</title><style> @import"home_style.css"</style></head><body style=" font-size: 16px; line-height: 1.4em; letter-spacing: 0.08em; padding: 0; margin: 0; background: url('./img/bg4.jpg') fixed center center no-repeat; background-size: cover; width: 100%;"> <div class="ace-head-inner"> <div class="ace-head-container ace-container"> <div class="ace-head-row"> <div id="ace-head-col1" class="ace-head-col text-left"> <span> <%String username = (String)session.getAttribute("username");if (username != null){out.println("您好,"+username+" <a href='logout.jsp'>退出登陆</a>  ");}else{out.println("您还未登陆 <a href='login.jsp'>点此登陆</a>  ");} %> </span> </div> <nav id="ace-main-nav"> <ul class="clear-list"> <%if (username != null){out.println("<li><a href='details.jsp'>个人信息</a></li>");} %> <li><a href="Home.jsp">主页</a></li> <li><a href="profile.jsp">作者简介</a></li> <li><a href="hometown.jsp">家乡介绍</a></li> <li><a href="board.jsp">留言板</a></li> <li><a href="about.jsp">关于</a></li> <li><a href="index.jsp">返回欢迎页</a></li> </ul> </nav> </div> </div></div><% String search_message = new String(); try{ search_message = new String(request.getParameter("src").getBytes("ISO8859_1"),"utf-8"); } catch(Exception e){}%><div class = white_box> <form action="search.jsp" method="post"> <center> <input type="text" value=" 留 言 搜 索 " style="font-size:20px;display:inline;" onfocus="if(this.value == ' 留 言 搜 索 ') this.value =''" name="src"> <input type="submit" value=" 搜 索 " style="font-size:20px;" > </center> </form></div><searchboard:searchboard src="<%=search_message%>" /><%=content %></body></html>
    4.8.3 我的留言(myboard.jsp/myboard.tag/deleteboard.jsp)本页面是留言板内容中的我的留言网页,网页通过myborad.tag文件查询用户名为当前登录用户的数据库中的留言内容,并显示在网页上,并且显示删除按钮,点击就可以调取deleteboard.jsp来删除指定的留言内容。
    效果示意图:

    myboard.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ taglib tagdir = "/WEB-INF/tags" prefix="myboard" %><!DOCTYPE html><html><head> <title>留言板</title><style> @import"home_style.css"</style></head><body style=" font-size: 16px; line-height: 1.4em; letter-spacing: 0.08em; padding: 0; margin: 0; background: url('./img/bg4.jpg') fixed center center no-repeat; background-size: cover; width: 100%;"> <div class="ace-head-inner"> <div class="ace-head-container ace-container"> <div class="ace-head-row"> <div id="ace-head-col1" class="ace-head-col text-left"> <span> <%String username = (String)session.getAttribute("username");if (username != null){out.println("您好,"+username+" <a href='logout.jsp'>退出登陆</a>  ");}else{out.println("您还未登陆 <a href='login.jsp'>点此登陆</a>  ");} %> </span> </div> <nav id="ace-main-nav"> <ul class="clear-list"> <%if (username != null){out.println("<li><a href='details.jsp'>个人信息</a></li>");} %> <li><a href="Home.jsp">主页</a></li> <li><a href="profile.jsp">作者简介</a></li> <li><a href="hometown.jsp">家乡介绍</a></li> <li><a href="board.jsp">留言板</a></li> <li><a href="about.jsp">关于</a></li> <li><a href="index.jsp">返回欢迎页</a></li> </ul> </nav> </div> </div></div><% String search_message = new String(); try{ search_message = new String(request.getParameter("src").getBytes("ISO8859_1"),"utf-8"); } catch(Exception e){}%><myboard:myboard></myboard:myboard><%=content%></body></html>
    5、总结本网站基本满足了所有需要的内容和功能需求。
    包含了个人的简介,家乡的介绍,包括个人的信息,留言板等内容。也包含了数据库的增(用户注册,留言板的留言等),删(个人留言支持删除),改(个人信息的修改等),查(留言板的查看,个人信息的查看等)四个功能。数据库的3张表,包括用户登录信息表,用户个人信息表,留言板内容表。
    6、参考文献[1]耿祥义,张跃平.JSP实用教程(第三版),清华大学出版社
    [2]刘长生,谢强,丁秋林,Java应用中的乱码问题分析[J] 计算机技术与发展,2006,25(5):77-80.
    [3]飞思科技产品研发中心。JSP应用开发详解(第二版)[M].北京:电子工业出版社,2004
    [4]萨师煊,王珊。数据库系统概论(第三版)[M].北京:高等教育出版社,2000
    [5]张红梅,王磊。在JSP中访问数据库的方法[J].农业图书情报学刊,2006,18(12):142-144
    5 评论 58 下载 2019-04-12 14:24:51 下载需要12点积分
  • 基于JSP和MYSQL数据库实现的在线考试系统

    1 系统概述1.1 功能模块教学部需要考试系统,该考试系统需要完成如下功能:

    考试系统只针对于Java课程,题目全部为单项选择,共10题
    学生注册、登录
    后台管理员功能:题库管理、录入试卷、修改试卷
    试卷生成
    考试
    试卷评分
    分数查看


    1.2 软件环境
    操作系统:WindowsXP、Windows2000 Server,windows server 2003,Linux
    数据库系统:MYSQL5.1及以上版本
    CASE工具: Rational Rose、Visio
    开发工具: Eclipse
    编程语言:Java
    支撑软件:JDK1.5及以上版本、Tomcat,JBoss或其他应用服务器

    1.3 基本设计概念和处理流程
    1.4 系统总体结构
    2 系统功能
    2.1 详细功能2.1.1 注册用户信息



    字段名
    字段类型
    说明




    用户名
    字符串
    用户名,用于登陆,用户唯一标识


    密码
    字符串
    密码要求加密存放


    姓名
    字符串
    用户真实姓名


    性别
    字符串



    电话
    字符串
    可以写多个联系方式


    邮件地址
    字符串



    备注
    字符串



    用户进入首页,如果没有注册,点击注册可以进入注册页面,注册完后,进入登陆页面,并要求自己将注册用户名填入登陆界面的用户名框内。如果已存在用户名,则返回注册界面,提示用户名已存在。

    2.1.2 用户登陆用户进入登陆页面,输入用户密码,点击登陆。登陆成功进入用户首页,登陆失败,返回登陆页面。
    2.1.3 用户密码修改用户在自己界面菜单上点击密码修改,进入密码修改界面,输入原密码,输入新密码和新确认密码,检验成功后进行修改。

    2.1.4. 用户管理
    2.1.4.1 用户查询查询条件:用户名,姓名
    查询结果:显示用户名称、用户名、性别,电话、邮件、备注
    2.1.4.2 用户删除勾选用户后,弹出确认对话框,用户确定后删除,可以进行多条删除,删除用户将删除用户所有考试信息。删除失败将进入失败页面并提示信息。
    2.1.5 题库管理题库全是选择题,选择项数至少两项,至多五项。题库题目名称不能重复。
    题目



    字段名
    字段类型
    说明




    题目名称
    字符串



    答案
    字符
    A,B,C,D,E这样的单字母编号



    选项



    字段名
    字段类型
    说明




    选项编号
    字符
    A,B,C,D这样的编号


    选项名称
    字符串
    选项名


    所属题目ID
    数字
    题目的ID号,在建表时设计



    2.1.5.1 题目添加管理员添加题目到题库。从查询界面点击添加按钮,进入编辑界面,填写题目名称,动态添加选项,至少两项,至多五项,点击添加完成。
    2.1.5.2 题目删除在查询界面中,勾选查询结果,进行删除,删除失败将进入失败界面。不能删除已被试卷引用的题库
    2.1.5.3 题目修改在查询界面,点击要修改的记录,进入编辑界面,修改改相关信息,进行保存。
    2.1.5.4 题目查询查询条件:题目名称
    查询结果:题目列表及选项(展现方式自定)
    2.1.6 试卷管理试卷



    字段名
    字段数据类型
    说明




    试卷名称
    字符型



    考试开始时间
    日期型



    考试结束时间
    日期型



    试卷题目



    字段名
    字段类型
    说明




    题目名称
    字符串



    答案
    字符
    A,B,C,D,E这样的单字母编号


    所属试卷ID
    数字
    试卷的ID号



    试卷选项



    字段名
    字段类型
    说明




    选项编号
    字符
    A,B,C,D这样的编号


    选项名称
    字符串
    选项名


    所属试卷题目ID
    数字
    题目的ID号,在建表时设计



    2.1.6.1 试卷录入从查询界面,点击添加按钮进入添加试卷界面,填写题目信息,从题库的题目列表中选择题目。(此处具体方式可以灵活设计),点击添加完成。
    校验:要求考试结束时间必须大于考试开始时间,考试开始时间必须大于当前(服务器)系统时间30分钟以上。
    2.1.6.2 删除试卷试卷删除时,已考过或正在考的试卷不能删除。(已考过即是在考试结果中能查到该试卷,正在考检查系统服务器时间是否在考试区间内)
    在查询界面,勾选查询结果,点击删除,用户确认删除后,删除所选试卷。删除失败将进入失败界面并提示信息.
    2.1.6.3 修改试卷从查询界面,点击某条记录进入编辑界面。修改相关信息。已考过或正在考的试卷不能再修改。
    2.1.6.4 试卷查询查询条件:试卷名称
    查询结果:试卷名称,考试开始时间,考试结束时间
    2.1.7 考试结果查询


    字段名
    字段类型
    说明




    考试试卷
    字符串



    考生姓名
    字符串



    考试分数
    字符串



    管理员选择考试试卷,点击查询,显示该考试的结果,按分数自动排名,默认查询最近一次已结束的考试排名。
    显示结果:姓名、用户名、分数、排名
    2.1.8 管理员登陆参考用户登陆
    2.1.9 管理员密码修改参考用户密码修改
    2.1.10 考试用户登陆后,在考试列表中,能够查询到当前时间可以考试的试卷。选择试卷进入考试。在时间(取系统服务器时间)未到前,用户如果做完题目可以点击提交按钮提交。在考试时间到之后,系统将自动提交用户试卷。已考过的试卷不会出现在试卷查询列表。考试结束系统计算分数,自动跳转到分数查看界面。

    2.1.11 分数查看在菜单上点击分数查看,显示用户考试科目,日期及分数。
    查询结果:考试科目,日期,分数。
    4 评论 231 下载 2018-11-05 21:01:47 下载需要5点积分
显示 45 到 60 ,共 15 条
eject