@TOC
ssm473校园失物招领网站的研发+jsp
第一章 绪论
1.1 选题背景
如今的信息时代,对信息的共享性,信息的流通性有着较高要求,尽管身边每时每刻都在产生大量信息,这些信息也都会在短时间内得到处理,并迅速传播。因为很多时候,管理层决策需要大量信息作为参考依据,也有些时候,各大企业或学校也需要使用工具宣传自身的文化理念等等,所以信息能够得到迅速传播并带给人们一定的参考价值,充分发挥信息本身的作用是很有必要的,而这些恰恰是传统模式所不能相比的。因此,借助工具让信息系统化,流程化,规范化是最终的发展结果,而这个工具则是计算机软件。本次设计实现的计算机软件校园失物招领网站,让其遵循实际操作流程的情况下,对失物招领实施规范化处理,让失物招领通过电子的方式进行保存,无论是管理人员检索失物招领,维护失物招领都可以便利化操作,真正缩短信息处理时间,节省人力和信息管理的成本。
1.2 选题意义
为了让失物招领的管理模式进行升级,也为了更好的维护失物招领,校园失物招领网站的开发运用就显得很有必要,因为它不仅可以让失物招领的管理人员统一完成信息管理,而且还会在保证失物招领处于安全状态的情况下,让失物招领的处理流程缩短,让信息的管理工作量减少,让失物招领的录入和后期维护缩短时间,以及节省管理失物招领需要投入的精力与资金。由于校园失物招领网站运用的技术比较成熟,所以它本身就具备了稳定的性能,连续24小时运行都毫无压力。而且还可以保证数据处理的质量。另外,校园失物招领网站为了满足易用性的用户需求,特意在页面的设计上合理布局各元素,让重要内容和导航功能在关键区域展示,让操作系统的用户可以毫不费力的完成系统的操作。总的说来,校园失物招领网站实现了信息资源的共享,让信息可以以更好的方式进行传播,让管理员的管理水平得到提升的同时,也让失物招领计算机化。
1.3 研究内容
根据校园失物招领网站设计与实现的流程来对整个系统进行说明。本文将从下述6个部分介绍系统。
第一部分:介绍选题的动因,包括介绍课题背景和意义等。
第二部分:介绍本系统选用的开发手段,包括编程语言,后台支持的数据库,开发类技术等。
第三部分:介绍系统的分析内容,包括投资决策必须的可行性研究,用户对功能的要求,系统运行的性能要求等知识。
第四部分:介绍系统的设计。包括对系统功能结构的设计,数据表结构设计等。
第五部分:介绍系统的实现。包括各模块实现的具体运行效果。
第六部分:介绍系统测试。包括检查系统功能,测试知识点的介绍等。
第二章 开发环境
对校园失物招领网站进行开发,需要了解开发技术的理论与实际运用,对开发工具,尤其是数据库的使用方法需要进行掌握。
2.1 SSM框架
SSM框架不是一个框架的名称,而是三个框架的首字母缩写,分别是Spring框架、SpringMVC框架、MyBatis框架。是目前Java开发者中学习的首选框架。
Spring框架继承了JavaEE和EJB框架的优点,在依赖注入方面去掉了臃肿的配置,在面向切面方面也简化了代码数量,提高了代码品质。依赖注解进行配置,让所有的依赖都可以通过程序的自动配置和寻找,减少了代码写作数量,提高了代码阅读性。
SpringMVC框架与Spring只是一个公司的,在底层代码结构上可以复用,但是最主要的功能是对数据提交请求进行过滤,并且对数据的返回进行过滤,不限于页面是jsp技术,也可以是其他的技术,更容易大型开发的集合技术。
MyBatis框架摒弃了Hibernate框架的配置臃肿方面,有时候Hibernate框架业务比较复杂的时候,代码量反而增加,性能下降,无法对底层的数据库语句优化,而MyBatis框架则有效的解决了这个方面,可以通过Java语句,对数据库操作语句进行优化,代码更简洁,执行效率更高,并且可以生产一些模块化代码,解决了开发过程中容易出现的实体映射方面的操作。
2.2jsp技术
JSP全名为Java Server Pages,其根本是一个简化的Servlet设计。它是在传统的网页HTML文件中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件。
JSP与Servlet一样,是在服务器端执行的。通常返回给客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览。就像其他普通的网页一样,您的浏览器发送一个HTTP请求给服务器。
Web服务器识别出这是一个对JSP网页的请求,并且将该请求传递给JSP引擎。通过使用URL或者.jsp文件来完成。
JSP引擎从磁盘中载入JSP文件,然后将它们转化为servlet。这种转化只是简单地将所有模板文本改用println()语句,并且将所有的JSP元素转化成Java代码。
JSP引擎将servlet编译成可执行类,并且将原始请求传递给servlet引擎。
Web服务器的某组件将会调用servlet引擎,然后载入并执行servlet类。在执行过程中,servlet产生HTML格式的输出并将其内嵌于HTTP response中上交给Web服务器。
Web服务器以静态HTML网页的形式将HTTP response返回到您的浏览器中。
Web浏览器处理HTTP response中动态产生的HTML网页,就好像在处理静态网页一样。
2.4 HTML简介
HTML是超文本标记语言,都是用各种声明以及对称性的的特殊符号作为标记,用以浏览器解析。HTML还有一些基本标签,比如根元素标签就是,而文档元数据一般都写在了标签里面,标题就是浏览器左上角的显示的网页内容,用的是
HTML作为一种超文本标记语言,是目前学习网站必须学习的第一门语言,要熟悉里面很多种标记,这种标记就是网页专属标记,只有这样浏览器才能解析相关信息。HTML里面包含了整整一套的标签,各种标签都有自己的功能,并且可以循环嵌套这些标签,比如一个表格里套着两个小小的表格。HTML一般文件名称的后缀都是html作为后缀,文档一般叫做web页面,里面的描述性标记语法被称为代码。
2.5 MyEclipse开发工具
MyEclipse是功能最全面的Java IDE。Java语言发展至今,已经与好多语言相互配合,并且各种语法都不一样,实现的效果不一样,造成现在的程序开发人员需要学习很多种语言,出现问题就解决问题,这是各种新的工具产生的一些动力。刚开始的Java需要自己安装开发环境和运行环境,然后手动新建文本,一句话一句话的进行编写,这样的功底需要极其的扎实,效率也是相当的低下,所以各种文本编辑工具就开始像雨后春笋一样的冒了出来,经过互联网的传播,大家使用后经过口碑,自然优胜略汰,大浪淘沙,到现在为止MyEclipse开发工具已经牢牢地占据了Java开发的半壁江山。MyEclipse的立足就是为了企业人员用的,企业开发讲究效率,不可能让所有的开发人员来了从电脑安装软件先开始,配置环境又需要花费太久的时间,MyEclipse就解决了这样的烦恼,只要安装了软件,各种Java程序都可以进行开发,可以对各种语法自动的进行检测,有效的提示细节处错误,并且可以在写作上面让对一些整段代码的移动复制都很便利,应用部署也是一键到位。
第三章 系统分析
提前通过各种渠道,比如图书馆,电脑上的网站等渠道获取跟本系统有关联的资料,同时设计调查问卷,让系统的使用者参与调查,了解其对系统的需求,然后进行系统的分析,确定本系统的开发可行性,确定本系统的功能等内容。
3.1可行性分析
这部分内容主要从开发的角度和运行使用的角度等层面研究系统,确定是否投资系统,为进一步开展工作提供理论依据。
3.1.1技术可行性
本系统采用的技术和开发类语言都具备丰厚的理论基础,同时这些开发技术和开发语言在市面上都得到了广泛运用,很多功能实现的源码都以模块化的方式通过网络进行了公开,所以本系统可以参考这些代码实现功能。因此,系统开发技术可行。
3.1.2操作可行性
校园失物招领网站根据用户阅读习惯对系统内容进行排版布局,把系统页面中的关键位置用来设置导航条,可以方便用户第一时间找到需要的内容,同时,页面中也会设置一些提示,用于帮助用户操作系统,因此,系统操作可行。
3.1.3经济可行性
本系统需要在硬件设备上配置开发环境,就可以开展系统的开发工作。由于本系统并不是商业化程序,所以本人学习用的笔记本,或机房电脑都符合要求。对于开发环境的配置问题,可以通过网络直接下载安装,期间并不收取费用。因此,系统经济可行。
以上就是从技术,操作,经济的层面研究系统,最终确定系统可以开展。
3.2系统流程分析
要访问校园失物招领网站,需要符合要求的身份,证明访问者身份的信息就是在登录界面需要填写的信息,其中有用户名,有密码。在登录界面,系统后台也有专门编写的安全验证机制,只有信息匹配的访问者才有资格进入系统。具体流程见下图。如果访问者提供的信息在数据库中没有记录,就表明该访问者没有权限,也就无法享受系统提供的服务。
图3-1 操作流程图
在校园失物招领网站里面,任何填充的数据都要经过合法性验证,具体流程见下图。只有符合条件的数据才可以保存。
图3-2 添加信息流程图
经过时间的改变,系统里面的很多数据也需要更新,更新时,同样需要检查更新的数据是否合法,具体流程见下图。只有判断符合要求的数据最终才可以保存。
图3-3 修改信息流程图
为了避免操作者大意误删数据,任何需要删除的数据,都需要反复确认,具体流程见下图。删除的数据将不会在页面中显示。
图3-4 删除信息流程图
3.3系统性能分析
用户使用系统,一是为了阅读需要的信息;二是为了享受系统提供的服务。因此一个质量较好的系统就更容易让用户频繁使用。而能够反馈系统的质量的信息就是系统的性能。常见的能够表示系统性能的指标有安全性,系统可扩展性,数据完整性等。接下来就对这些指标进行介绍。
3.3.1数据完整性
只要是系统中的数据,其长期保存在数据库里面,就要求其具备可靠性。这样才能发挥出数据具备的参考价值。一般来说,为了保证数据信息是准确的,并且可靠的,在数据处理上,包括录入数据,编辑数据等,都要求数据信息是完整登记的。同时,系统中的数据其自身需要具备完整性外,也要求数据之间产生的关系也要具备完整性。另外,在数据库中填充信息时,同样的信息应该以同样的方式出现在不同的表中。对于数据进行完整性定义,也是方便后期对数据的使用和查看。
3.3.2系统可扩展性
站在当前用户需求的角度考虑问题具有一定的局限性,由此设计的系统也一样。为了保护开发系统的财产,同时也为了让系统长远立足市场,系统开发人员就需要充分预留系统的空间,让系统在未来的日子里可以扩充功能,并进行更新和升级。这就是系统具备可扩展性的表现。
3.3.3系统安全性
系统在投入使用中,用户与系统的交互会产生数据,比如插入数据,编辑数据等操作都会产生数据。而作为系统的后台支持的数据库,主要任务就是保存这些数据。为了不让数据信息被窃取或者泄露,也是为了对系统的安全性进行保证,所以市面上也出现了很多的加密技术,其中MD5单向加密技术在系统中运用得最多。其原因有三点:
第一点,面对任意两段明文,在经过MD5加密处理后,它们的密文不一样;
第二点,面对任意一段明文,进行MD5加密处理后,其密文不变;
第三点,破解MD5加密的数据非常困难;
目前,关于MD5加密技术的代码已经可以从网站上下载,可以直接将模块化的代码在系统中直接引用。一般来说,用户注册的数据还有管理员登录系统使用的数据都是很重要的资源,所以这部分数据常常会经过加密处理,这样也就消除了系统安全上的隐患。
第四章 系统设计
设计一个系统不单单是设计系统的页面,可以说系统设计其本质是一个结合了众多设计过程的比较复杂的系统工程。一般来说,在完成系统设计时,需要了解和掌握很多设计的知识,有界面布局技术的知识,页面采用的字体和颜色的运用,还有页面空白的规范使用等,如何将这些元素进行组合,让页面可以直观表达信息内容的同时,也能维持页面整体的美观。
4.1 系统设计思想
系统开发必然需要统一设计思想。根据这个设计思想指导系统的开发,可以加快系统开发进程。根据目前用户对校园失物招领网站的需求,确定下述原则即为本系统的设计思想。
(1)实用性:本系统依照用户需求设计功能,遵循用户使用方便的原则,把用户在实际工作中的各个操作细节也充分考虑进来,让使用者在没有系统操作说明书的情况下,也能很容易的完成系统的操作。
(2)先进性:为了让本系统具备高性能,设计时,需要把目前的各种成熟技术加以考虑,比如软件开发技术也要考虑进去,比如计算机技术也需要进行考虑。对于系统结构的选择,本系统将毫不犹豫的选择成熟先进的B/S结构,方便开发的同时,对于后期的维护也提供了便利。
(3)高安全性:设计本系统时,对于一些系统的关键数据要严加看管,比如管理员本人的账号和密码,一定要加密保存在数据库里面。除此以外,也需要充分使用安全措施对用户的共享资源进行保护。
(4)可维护性:设计时,要提前考虑本系统的可维护性,因为一个便于维护的系统在后期产生的维护成本将会大大降低。维护一般包括软硬件的维护还有对于网络的维护等。
(5)可扩展性:重新开发一个新系统相比在原有系统上升级,会花费大量的资金和精力,由此,一个好的系统必定具备良好的可扩展性。在用户需求变动的情况下,可以通过系统的更新和升级来持续满足用户需求,这样的系统就具备了可扩展性。
4.2功能结构设计
这部分内容使用结构图这样的工具,显示设计结果,设计的管理员功能见下图。管理员为用户忘记密码时可以重置用户密码,管理失物招领、物品挂失、光荣榜、公告信息、及失物认领,
校园失物招领网站
用户信息管理
光荣榜管理
失物认领管理
商物品挂失管理
商失物招领管理
用用户信息修改
用用户信息新增
商失物招领添加
商失物招领删除
商失物招领修改
商物品挂失添加
商物品挂失修改
商物品挂失删除
商光荣榜添加
商光荣榜删改
商光荣榜删除
商失物认领添加
商失物认领修改
商失物认领删除
新
公告信息管理
新公告信息修改
新公告信息删除
新公告信息添加
图4-1 管理员功能结构图
4.3 数据库设计
开发一个系统也需要提前设计数据库。这里的数据库是相关数据的集合,存储在一起的这些数据也是按照一定的组织方式进行的。目前,数据库能够服务于多种应用程序,则是源于它存储方式最佳,具备数据冗余率低的优势。虽然数据库为程序提供信息存储服务,但它与程序之间也可以保持较高的独立性。总而言之,数据库经历了很长一段时间的发展,从最初的不为人知,到现在的人尽皆知,其相关技术也越发成熟,同时也拥有着坚实的理论基础。
4.3.1 数据库概念设计
这部分内容需要借助数据库关系图来完成,也需要使用专门绘制数据库关系图的工具,比如Visio工具就可以设计E-R图(数据库关系图)。设计数据库,也需要按照设计的流程进行,首先还是要根据需求完成实体的确定,分析实体具有的特征,还有对实体间的关联关系进行确定。最后才是使用E-R模型的表示方法,绘制本系统的E-R图。不管是使用亿图软件,还是Visio工具,对于E-R模型的表示符号都一样,通常矩形代表实体,实体间存在的关系用菱形符号表示,实体的属性也就是实体的特征用符号椭圆表示。最后使用直线将矩形,菱形和椭圆等符号连接起来。接下来就开始对本系统的E-R图进行绘制。
(1)下图是用户实体和其具备的属性。
图4.1 用户实体属性图
(2)下图是光荣榜实体和其具备的属性。
图4.2 光荣榜实体属性图
(3)下图是字典表实体和其具备的属性。
图4.3 字典表实体属性图
(4)下图是失物招领实体和其具备的属性。
图4.4 失物招领实体属性图
(5)下图是物品挂失实体和其具备的属性。
图4.5 物品挂失实体属性图
(6)下图是失物招领留言实体和其具备的属性。
图4.6 失物招领留言实体属性图
(7)下图是论坛实体和其具备的属性。
图4.7 论坛实体属性图
(8)下图是失物认领实体和其具备的属性。
图4.8 失物认领实体属性图
(9)下图是公告实体和其具备的属性。
图4.9 公告实体属性图
(10)下图是物品挂失留言实体和其具备的属性。
图4.10 物品挂失留言实体属性图
(11)下图是用户表实体和其具备的属性。
图4.11 用户表实体属性图
4.3.2 数据库表结构
很多时候,在进行数据表的存储结构的设计时,都会遇到一些困扰,比如每张数据表如何命名,如何设计每张数据表里面的字段,如何为各个字段进行命名,以及如何设置字段的取值范围等信息。很多初学者,在进行表结构设计时,无论是对表进行命名,还是对字段进行命名,都是采用中文的方式,导致在编码阶段,在对数据进行操作时,总是报错,影响编码人员的开发速度,而且一旦数据表结构建立之后,后期进行修改也比较麻烦。因为设计数据表的结构,就意味着程序中需要长期保存的数据都是根据这样的结构进行保存的,在后面的使用中,无论是程序数据往数据表中写入,还是需要编辑或删除数据,都是按照这个规则进行。如此说来,设计数据库也是非常重要的任务,它关系到后面程序的开发,也关系到程序的运行使用。
通常在设计数据表结构时,会把前面设计的E-R图进行表结构的转化。把实体用来代表数据表,把其属性,也就是椭圆形代表的内容用来表示数据表中的字段,然后根据程序对于数据的存储要求,设计字段的类型和长度。比如用户的年龄可以用int(整数型),设置其长度为4或者6等。总之,数据表结构一旦建立,就可以往里面填充数据了。
表4.1字典表表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | dic_code | String | 字段 | 是 |
3 | dic_name | String | 字段名 | 是 |
4 | code_index | Integer | 编码 | 是 |
5 | index_name | String | 编码名字 | 是 |
6 | super_id | Integer | 父字段id | 是 |
7 | beizhu | String | 备注 | 是 |
8 | create_time | Date | 创建时间 | 是 |
表4.2论坛表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | forum_name | String | 帖子标题 | 是 |
3 | yonghu_id | Integer | 用户 | 是 |
4 | forum_content | String | 发布内容 | 是 |
5 | super_ids | Integer | 父id | 是 |
6 | forum_state_types | Integer | 帖子状态 | 是 |
7 | insert_time | Date | 发帖时间 | 是 |
8 | update_time | Date | 修改时间 | 是 |
9 | create_time | Date | 创建时间 | 是 |
表4.3光荣榜表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | guangrongbang_name | String | 标题 | 是 |
3 | yonghu_id | Integer | 用户 | 是 |
4 | shiwuzhaoling_id | Integer | 物品 | 是 |
5 | guangrongbang_photo | String | 图片 | 是 |
6 | guangrongbang_content | String | 详情 | 是 |
7 | create_time | Date | 创建时间 | 是 |
表4.4公告表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | news_name | String | 公告名称 | 是 |
3 | news_types | Integer | 公告类型 | 是 |
4 | news_photo | String | 公告图片 | 是 |
5 | insert_time | Date | 公告时间 | 是 |
6 | news_content | String | 公告详情 | 是 |
7 | create_time | Date | 创建时间 | 是 |
表4.5失物认领表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | shiwuzhaoling_id | Integer | 失物id | 是 |
3 | yonghu_id | Integer | 认领用户 | 是 |
4 | yesno_types | Integer | 审核 | 是 |
5 | shiwurenling_text | String | 详情 | 是 |
6 | insert_time | Date | 认领时间 | 是 |
7 | create_time | Date | 创建时间 | 是 |
表4.6失物招领表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | shiwuzhaoling_uuid_number | String | 失物编号 | 是 |
3 | shiwuzhaoling_name | String | 物品名称 | 是 |
4 | shiwuzhaoling_types | Integer | 物品类型 | 是 |
5 | status_types | Integer | 物品状态 | 是 |
6 | yonghu_id | Integer | 用户 | 是 |
7 | shiwuzhaoling_photo | String | 物品图片 | 是 |
8 | shiwuzhaoling_time | Date | 拾遗时间 | 是 |
9 | shiwuzhaoling_dizhi | String | 拾遗地址 | 是 |
10 | shiwuzhaoling_content | String | 详情 | 是 |
11 | create_time | Date | 创建时间 | 是 |
表4.7失物招领留言表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | shiwuzhaoling_id | Integer | 物品 | 是 |
3 | yonghu_id | Integer | 用户 | 是 |
4 | shiwuzhaoling_liuyan_text | String | 留言内容 | 是 |
5 | reply_text | String | 回复内容 | 是 |
6 | insert_time | Date | 留言时间 | 是 |
7 | update_time | Date | 回复时间 | 是 |
8 | create_time | Date | 创建时间 | 是 |
表4.8物品挂失表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | wupinguashi_name | String | 物品名称 | 是 |
3 | shiwuzhaoling_types | Integer | 物品类型 | 是 |
4 | status_types | Integer | 物品状态 | 是 |
5 | wupinguashi_photo | String | 物品图片 | 是 |
6 | wupinguashi_time | Date | 丢失时间 | 是 |
7 | yonghu_id | Integer | 用户 | 是 |
8 | wupinguashi_dizhi | String | 丢失地址 | 是 |
9 | wupinguashi_content | String | 详情 | 是 |
10 | create_time | Date | 创建时间 | 是 |
表4.9物品挂失留言表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | wupinguashi_id | Integer | 物品 | 是 |
3 | yonghu_id | Integer | 用户 | 是 |
4 | wupinguashi_liuyan_text | String | 留言内容 | 是 |
5 | reply_text | String | 回复内容 | 是 |
6 | insert_time | Date | 留言时间 | 是 |
7 | update_time | Date | 回复时间 | 是 |
8 | create_time | Date | 创建时间 | 是 |
表4.10用户表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | yonghu_name | String | 用户姓名 | 是 |
3 | yonghu_id_number | String | 身份证号 | 是 |
4 | yonghu_phone | String | 手机号 | 是 |
5 | yonghu_photo | String | 照片 | 是 |
6 | create_time | Date | 创建时间 | 是 |
表4.11用户表表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | username | String | 用户名 | 是 |
3 | password | String | 密码 | 是 |
4 | role | String | 角色 | 是 |
5 | addtime | Date | 新增时间 | 是 |
第五章 系统实现
前面做的所有工作,都是为了给系统实现做准备。在系统实现期间,需要根据设计方案执行,通过运用编码技术实现一个可以处理事务的系统。
5.1用户信息管理
如图5.1显示的就是用户信息管理页面,此页面提供给管理员的功能有:用户信息的查询管理,可以删除用户信息、修改用户信息、新增用户信息,
还进行了对用户名称的模糊查询的条件
图5.1 用户信息管理页面
5.2 失物招领管理
如图5.2显示的就是失物招领管理页面,此页面提供给管理员的功能有:查看已发布的失物招领数据,修改失物招领,失物招领作废,即可删除,还进行了对失物招领名称的模糊查询 失物招领信息的类型查询等等一些条件。
图5.2 失物招领管理页面
5.3失物认领管理
如图5.3显示的就是失物认领管理页面,此页面提供给管理员的功能有:根据失物认领进行条件查询,还可以对失物认领进行新增、修改、查询操作等等。
图5.3 失物认领管理页面
5.1公告信息管理
如图5.4显示的就是公告信息管理页面,此页面提供给管理员的功能有:根据公告信息进行新增、修改、查询操作等等。
图5.4 公告信息管理页面
结 论
从设计到制作完成,本系统已经花了三四个月时间,这期间也得到了导师的帮助。不然我不可能在这么短时间完成。校园失物招领网站的开发,是一个运用理论知识来指导实际工作的任务。尽管已经充分把大学期间,从书本上学习的知识运用了进来,但还是发现自身知识的匮乏。不过比较有收获的事情就是,通过本系统的开发,我对计算机软件的开发有了重新的见解,也知道它实现的具体流程,并且自己通过实际操作,不仅重新回顾和补充了以往学习的书本知识,也知道理论和实际操作之间的相互关系,并能够在一定环境下,让理论指导实践。项目能够完成,也代表着我自身开发能力的进步。
项目制作期间,我觉得最关键的环节就是系统的分析和设计,分析系统具备的功能需要多查找同类型系统的资料,并把用户需求进行参考,才可以得出本系统的需求。设计时也是在需求分析的基础上开展,也是对功能的具体细分,同时还有设计保存数据的数据库,不但要创建合适的数据表,也需要认真对表结构进行构思,尤其是表的字段设计,还有表关系的设计也是很关键的设计环节。因为后期的编码都是根据设计文档开展下去的。编码虽然对编程技术的要求较高,但是一些良好的编程习惯也不能忽视,比如注释代码,这样便于后期的程序维护。还有学会如何对变量取名,因为程序里面涉及到的变量有很多,一个方便记忆,又容易与其它变量区分的变量名称是非常有益的,可以节省编码和测试过程的时间。
校园失物招领网站完全根据需求文档设计制作,可以在数据处理上发挥它的优势,而且使用者也能轻松完成对系统的操作。从界面设计的角度来看,校园失物招领网站始终遵循简单大方的原则,让使用者一进入系统界面,不会产生压抑等负面情绪,而是比较愉悦的心情去操作系统。从程序编码的角度来看,本系统设计的结构比较清晰,而且编码的方式也比较规范化,在关键处也都进行了代码注释。从数据存储的角度来看,本系统选用的MySQL数据库,本身比较轻盈,但能短时间完成大量数据的处理,其提供的功能不可小觑。
作为毕设进行制作的校园失物招领网站,其缺陷也是显而易见的,只能说需求文档要求的大致功能都得到实现,但是程序的有些操作逻辑还是比较复杂,并没有进行优化,在今后的时间里,将会继续学习新技术,利用重构的方式设计本系统,使之具备更强的可扩展性,让系统日趋完善。
致 谢
大学生活真的很美好,不仅可以学到很多本专业的知识,还能在本校交到兴趣相投的朋友,还有身边授课的老师也都很好,他们虽然扮演着老师的角色,但课堂下却像朋友一样交流相处。所以,在即将毕业的时刻,我又突然很庆幸来到了这里上大学。
在大学里,我觉得自己的知识增加了很多,遇到问题可以想办法去解决,锻炼了我的知识运用能力。看到自己的成长,内心非常激动,同时也想对本校的老师表示感谢。还有对我的大学校园表示感谢,以及对我的舍友和同学表示感谢。
感谢校园的授课老师和指导我毕业的老师,他们把自身所学知识都教给了我们,我们才会获取知识并取得进步,指导我毕业的老师,在我的项目制作,和后期的文档编写阶段,都尽最大努力帮助我,对我遇到的问题,他都耐心告诉我怎么去解决,让我自己在本项目制作中,得到锻炼。我也从指导老师那里学到了很多知识,在此,感谢他的帮助和引导,我才可以在短短几个月时间设计实现我的项目。
陪着我一起努力的还有我的舍友和同学,我们多次面对面交流如何寻找资料,以及一些编程的小技巧等知识,正因为我们互相帮助,才可以节省项目制作的时间,也让我有足够的精力去完善自己制作的项目。
最后,感谢学校提供的读书环境,以及给我学习锻炼的机会。
ShiwuzhaolingController.java
package com.controller;
import java.io.File;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.JSONObject;
import java.util.*;
import org.springframework.beans.BeanUtils;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.ContextLoader;
import javax.servlet.ServletContext;
import com.service.TokenService;
import com.utils.*;
import java.lang.reflect.InvocationTargetException;
import com.service.DictionaryService;
import org.apache.commons.lang3.StringUtils;
import com.annotation.IgnoreAuth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.entity.*;
import com.entity.view.*;
import com.service.*;
import com.utils.PageUtils;
import com.utils.R;
import com.alibaba.fastjson.*;
/**
* 失物招领
* 后端接口
* @author
* @email
*/
@RestController
@Controller
@RequestMapping("/shiwuzhaoling")
public class ShiwuzhaolingController {
private static final Logger logger = LoggerFactory.getLogger(ShiwuzhaolingController.class);
@Autowired
private ShiwuzhaolingService shiwuzhaolingService;
@Autowired
private TokenService tokenService;
@Autowired
private DictionaryService dictionaryService;
//级联表service
@Autowired
private YonghuService yonghuService;
/**
* 后端列表
*/
@RequestMapping("/page")
public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){
logger.debug("page方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));
String role = String.valueOf(request.getSession().getAttribute("role"));
if(StringUtil.isEmpty(role))
return R.error(511,"权限为空");
else if("用户".equals(role))
params.put("yonghuId",request.getSession().getAttribute("userId"));
if(params.get("orderBy")==null || params.get("orderBy")==""){
params.put("orderBy","id");
}
PageUtils page = shiwuzhaolingService.queryPage(params);
//字典表数据转换
List<ShiwuzhaolingView> list =(List<ShiwuzhaolingView>)page.getList();
for(ShiwuzhaolingView c:list){
//修改对应字典表字段
dictionaryService.dictionaryConvert(c, request);
}
return R.ok().put("data", page);
}
/**
* 后端详情
*/
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id, HttpServletRequest request){
logger.debug("info方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
ShiwuzhaolingEntity shiwuzhaoling = shiwuzhaolingService.selectById(id);
if(shiwuzhaoling !=null){
//entity转view
ShiwuzhaolingView view = new ShiwuzhaolingView();
BeanUtils.copyProperties( shiwuzhaoling , view );//把实体数据重构到view中
//级联表
YonghuEntity yonghu = yonghuService.selectById(shiwuzhaoling.getYonghuId());
if(yonghu != null){
BeanUtils.copyProperties( yonghu , view ,new String[]{ "id", "createDate"});//把级联的数据添加到view中,并排除id和创建时间字段
view.setYonghuId(yonghu.getId());
}
//修改对应字典表字段
dictionaryService.dictionaryConvert(view, request);
return R.ok().put("data", view);
}else {
return R.error(511,"查不到数据");
}
}
/**
* 后端保存
*/
@RequestMapping("/save")
public R save(@RequestBody ShiwuzhaolingEntity shiwuzhaoling, HttpServletRequest request){
logger.debug("save方法:,,Controller:{},,shiwuzhaoling:{}",this.getClass().getName(),shiwuzhaoling.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
if(StringUtil.isEmpty(role))
return R.error(511,"权限为空");
else if("用户".equals(role))
shiwuzhaoling.setYonghuId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));
Wrapper<ShiwuzhaolingEntity> queryWrapper = new EntityWrapper<ShiwuzhaolingEntity>()
.eq("shiwuzhaoling_uuid_number", shiwuzhaoling.getShiwuzhaolingUuidNumber())
.eq("shiwuzhaoling_name", shiwuzhaoling.getShiwuzhaolingName())
.eq("shiwuzhaoling_types", shiwuzhaoling.getShiwuzhaolingTypes())
.eq("status_types", shiwuzhaoling.getStatusTypes())
.eq("yonghu_id", shiwuzhaoling.getYonghuId())
.eq("shiwuzhaoling_dizhi", shiwuzhaoling.getShiwuzhaolingDizhi())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
ShiwuzhaolingEntity shiwuzhaolingEntity = shiwuzhaolingService.selectOne(queryWrapper);
if(shiwuzhaolingEntity==null){
shiwuzhaoling.setCreateTime(new Date());
shiwuzhaolingService.insert(shiwuzhaoling);
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
/**
* 后端修改
*/
@RequestMapping("/update")
public R update(@RequestBody ShiwuzhaolingEntity shiwuzhaoling, HttpServletRequest request){
logger.debug("update方法:,,Controller:{},,shiwuzhaoling:{}",this.getClass().getName(),shiwuzhaoling.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
// if(StringUtil.isEmpty(role))
// return R.error(511,"权限为空");
// else if("用户".equals(role))
// shiwuzhaoling.setYonghuId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));
//根据字段查询是否有相同数据
Wrapper<ShiwuzhaolingEntity> queryWrapper = new EntityWrapper<ShiwuzhaolingEntity>()
.notIn("id",shiwuzhaoling.getId())
.andNew()
.eq("shiwuzhaoling_uuid_number", shiwuzhaoling.getShiwuzhaolingUuidNumber())
.eq("shiwuzhaoling_name", shiwuzhaoling.getShiwuzhaolingName())
.eq("shiwuzhaoling_types", shiwuzhaoling.getShiwuzhaolingTypes())
.eq("status_types", shiwuzhaoling.getStatusTypes())
.eq("yonghu_id", shiwuzhaoling.getYonghuId())
.eq("shiwuzhaoling_dizhi", shiwuzhaoling.getShiwuzhaolingDizhi())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
ShiwuzhaolingEntity shiwuzhaolingEntity = shiwuzhaolingService.selectOne(queryWrapper);
if("".equals(shiwuzhaoling.getShiwuzhaolingPhoto()) || "null".equals(shiwuzhaoling.getShiwuzhaolingPhoto())){
shiwuzhaoling.setShiwuzhaolingPhoto(null);
}
if(shiwuzhaolingEntity==null){
// String role = String.valueOf(request.getSession().getAttribute("role"));
// if("".equals(role)){
// shiwuzhaoling.set
// }
shiwuzhaolingService.updateById(shiwuzhaoling);//根据id更新
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Integer[] ids){
logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());
shiwuzhaolingService.deleteBatchIds(Arrays.asList(ids));
return R.ok();
}
/**
* 批量上传
*/
@RequestMapping("/batchInsert")
public R save( String fileName){
logger.debug("batchInsert方法:,,Controller:{},,fileName:{}",this.getClass().getName(),fileName);
try {
List<ShiwuzhaolingEntity> shiwuzhaolingList = new ArrayList<>();//上传的东西
Map<String, List<String>> seachFields= new HashMap<>();//要查询的字段
Date date = new Date();
int lastIndexOf = fileName.lastIndexOf(".");
if(lastIndexOf == -1){
return R.error(511,"该文件没有后缀");
}else{
String suffix = fileName.substring(lastIndexOf);
if(!".xls".equals(suffix)){
return R.error(511,"只支持后缀为xls的excel文件");
}else{
URL resource = this.getClass().getClassLoader().getResource("static/upload/" + fileName);//获取文件路径
File file = new File(resource.getFile());
if(!file.exists()){
return R.error(511,"找不到上传文件,请联系管理员");
}else{
List<List<String>> dataList = PoiUtil.poiImport(file.getPath());//读取xls文件
dataList.remove(0);//删除第一行,因为第一行是提示
for(List<String> data:dataList){
//循环
ShiwuzhaolingEntity shiwuzhaolingEntity = new ShiwuzhaolingEntity();
// shiwuzhaolingEntity.setShiwuzhaolingUuidNumber(data.get(0)); //失物编号 要改的
// shiwuzhaolingEntity.setShiwuzhaolingName(data.get(0)); //物品名称 要改的
// shiwuzhaolingEntity.setShiwuzhaolingTypes(Integer.valueOf(data.get(0))); //物品类型 要改的
// shiwuzhaolingEntity.setStatusTypes(Integer.valueOf(data.get(0))); //物品状态 要改的
// shiwuzhaolingEntity.setYonghuId(Integer.valueOf(data.get(0))); //用户 要改的
// shiwuzhaolingEntity.setShiwuzhaolingPhoto("");//照片
// shiwuzhaolingEntity.setShiwuzhaolingTime(new Date(data.get(0))); //拾遗时间 要改的
// shiwuzhaolingEntity.setShiwuzhaolingDizhi(data.get(0)); //拾遗地址 要改的
// shiwuzhaolingEntity.setShiwuzhaolingContent("");//照片
// shiwuzhaolingEntity.setCreateTime(date);//时间
shiwuzhaolingList.add(shiwuzhaolingEntity);
//把要查询是否重复的字段放入map中
//失物编号
if(seachFields.containsKey("shiwuzhaolingUuidNumber")){
List<String> shiwuzhaolingUuidNumber = seachFields.get("shiwuzhaolingUuidNumber");
shiwuzhaolingUuidNumber.add(data.get(0));//要改的
}else{
List<String> shiwuzhaolingUuidNumber = new ArrayList<>();
shiwuzhaolingUuidNumber.add(data.get(0));//要改的
seachFields.put("shiwuzhaolingUuidNumber",shiwuzhaolingUuidNumber);
}
}
//查询是否重复
//失物编号
List<ShiwuzhaolingEntity> shiwuzhaolingEntities_shiwuzhaolingUuidNumber = shiwuzhaolingService.selectList(new EntityWrapper<ShiwuzhaolingEntity>().in("shiwuzhaoling_uuid_number", seachFields.get("shiwuzhaolingUuidNumber")));
if(shiwuzhaolingEntities_shiwuzhaolingUuidNumber.size() >0 ){
ArrayList<String> repeatFields = new ArrayList<>();
for(ShiwuzhaolingEntity s:shiwuzhaolingEntities_shiwuzhaolingUuidNumber){
repeatFields.add(s.getShiwuzhaolingUuidNumber());
}
return R.error(511,"数据库的该表中的 [失物编号] 字段已经存在 存在数据为:"+repeatFields.toString());
}
shiwuzhaolingService.insertBatch(shiwuzhaolingList);
return R.ok();
}
}
}
}catch (Exception e){
return R.error(511,"批量插入数据异常,请联系管理员");
}
}
/**
* 前端列表
*/
@IgnoreAuth
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params, HttpServletRequest request){
logger.debug("list方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));
// 没有指定排序字段就默认id倒序
if(StringUtil.isEmpty(String.valueOf(params.get("orderBy")))){
params.put("orderBy","id");
}
PageUtils page = shiwuzhaolingService.queryPage(params);
//字典表数据转换
List<ShiwuzhaolingView> list =(List<ShiwuzhaolingView>)page.getList();
for(ShiwuzhaolingView c:list)
dictionaryService.dictionaryConvert(c, request); //修改对应字典表字段
return R.ok().put("data", page);
}
/**
* 前端详情
*/
@RequestMapping("/detail/{id}")
public R detail(@PathVariable("id") Long id, HttpServletRequest request){
logger.debug("detail方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
ShiwuzhaolingEntity shiwuzhaoling = shiwuzhaolingService.selectById(id);
if(shiwuzhaoling !=null){
//entity转view
ShiwuzhaolingView view = new ShiwuzhaolingView();
BeanUtils.copyProperties( shiwuzhaoling , view );//把实体数据重构到view中
//级联表
YonghuEntity yonghu = yonghuService.selectById(shiwuzhaoling.getYonghuId());
if(yonghu != null){
BeanUtils.copyProperties( yonghu , view ,new String[]{ "id", "createDate"});//把级联的数据添加到view中,并排除id和创建时间字段
view.setYonghuId(yonghu.getId());
}
//修改对应字典表字段
dictionaryService.dictionaryConvert(view, request);
return R.ok().put("data", view);
}else {
return R.error(511,"查不到数据");
}
}
/**
* 前端保存
*/
@RequestMapping("/add")
public R add(@RequestBody ShiwuzhaolingEntity shiwuzhaoling, HttpServletRequest request){
logger.debug("add方法:,,Controller:{},,shiwuzhaoling:{}",this.getClass().getName(),shiwuzhaoling.toString());
Wrapper<ShiwuzhaolingEntity> queryWrapper = new EntityWrapper<ShiwuzhaolingEntity>()
.eq("shiwuzhaoling_uuid_number", shiwuzhaoling.getShiwuzhaolingUuidNumber())
.eq("shiwuzhaoling_name", shiwuzhaoling.getShiwuzhaolingName())
.eq("shiwuzhaoling_types", shiwuzhaoling.getShiwuzhaolingTypes())
.eq("status_types", shiwuzhaoling.getStatusTypes())
.eq("yonghu_id", shiwuzhaoling.getYonghuId())
.eq("shiwuzhaoling_dizhi", shiwuzhaoling.getShiwuzhaolingDizhi())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
ShiwuzhaolingEntity shiwuzhaolingEntity = shiwuzhaolingService.selectOne(queryWrapper);
if(shiwuzhaolingEntity==null){
shiwuzhaoling.setCreateTime(new Date());
// String role = String.valueOf(request.getSession().getAttribute("role"));
// if("".equals(role)){
// shiwuzhaoling.set
// }
shiwuzhaolingService.insert(shiwuzhaoling);
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
}
NewsServiceImpl.java
package com.service.impl;
import com.utils.StringUtil;
import org.springframework.stereotype.Service;
import java.lang.reflect.Field;
import java.util.*;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import com.utils.PageUtils;
import com.utils.Query;
import org.springframework.web.context.ContextLoader;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import com.dao.NewsDao;
import com.entity.NewsEntity;
import com.service.NewsService;
import com.entity.view.NewsView;
/**
* 公告 服务实现类
*/
@Service("newsService")
@Transactional
public class NewsServiceImpl extends ServiceImpl<NewsDao, NewsEntity> implements NewsService {
@Override
public PageUtils queryPage(Map<String,Object> params) {
if(params != null && (params.get("limit") == null || params.get("page") == null)){
params.put("page","1");
params.put("limit","10");
}
Page<NewsView> page =new Query<NewsView>(params).getPage();
page.setRecords(baseMapper.selectListView(page,params));
return new PageUtils(page);
}
}
FileController.java
package com.controller;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.annotation.IgnoreAuth;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.ConfigEntity;
import com.entity.EIException;
import com.service.ConfigService;
import com.utils.R;
/**
* 上传文件映射表
*/
@RestController
@RequestMapping("file")
@SuppressWarnings({"unchecked","rawtypes"})
public class FileController{
@Autowired
private ConfigService configService;
/**
* 上传文件
*/
@RequestMapping("/upload")
public R upload(@RequestParam("file") MultipartFile file, String type,HttpServletRequest request) throws Exception {
if (file.isEmpty()) {
throw new EIException("上传文件不能为空");
}
String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
String fileName = new Date().getTime()+"."+fileExt;
File dest = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+fileName);
file.transferTo(dest);
if(StringUtils.isNotBlank(type) && type.equals("1")) {
ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
if(configEntity==null) {
configEntity = new ConfigEntity();
configEntity.setName("faceFile");
configEntity.setValue(fileName);
} else {
configEntity.setValue(fileName);
}
configService.insertOrUpdate(configEntity);
}
return R.ok().put("file", fileName);
}
/**
* 下载文件
*/
@IgnoreAuth
@RequestMapping("/download")
public void download(@RequestParam String fileName, HttpServletRequest request, HttpServletResponse response) {
try {
File file = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+fileName);
if (file.exists()) {
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName+"\"");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setContentType("application/octet-stream; charset=UTF-8");
IOUtils.write(FileUtils.readFileToByteArray(file), response.getOutputStream());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
声明
本博客适用于广泛的学术和教育用途,包括但不限于个人学习、开发设计,产品设计。仅供学习参考,旨在为读者提供深入理解和学术研究的材料。