本文介绍了我在开发工具——核酸截图格式化管理网站时使用的两种设计方法,分别通过python的flask框架和java的springboot框架完成开发。文章将对两种框架进行对比分析,方法汇总,同时分享对于两个语言和框架的个人开发感受。
项目名称:核酸截图格式化管理网站后端(py&java)
完成时间:2022年7月26日
记录时间:2022年9月20日
作者前言
记录这个项目时距最后开发过去近两个月了,当我抽出时间写文章时,有些许内容以及想法已经记得不是很清楚了,只能尽印象写下当时的开发实记,同时我尽量简化了文章的代码解释,去更多的记录自己的开发感受。
- 首先需要在此声明:
本工具并非我独自一人完成,整个项目是与另一位大佬合作开发的,我只负责了后端开发,前端部分非我创作,对接部分由我们共同完成。本工具可以归类为公益开发,后端已经移交给负责收截图的同学管理,网站服务托管在我的个人服务器上。日常中,我仅作为设计开发者、维护者以及班级中的一员的身份参与到每天的收集和管理中。
本工具的初代版本后端基于Python的flask框架,前端基于layui框架,数据库使用的是mysql。因为小学期需要java项目,再经过完善后我将后端代码重写为java,使用springboot框架,其他不变。Python版本开发于2022年4月,用时大概4-5天(课余时间),完善系统用了近一周时间;在五月初的二次开发中,我们优化了后端的格式化、正则代码,加入了第二种截图的格式化收集,并完善了管理界面。Java版本开发于2022年7月,将py代码优化重写为java代码,用时3天,并附上了项目报告。
在此特别感谢与共同开发的大佬,在百忙之中抽出时间完成本项目,在我邀请他之前已经提出开发目的仅是为了解决同学们的一点小麻烦并没有其他的成果收获,最后我们还是愉快的完成了此次开发;感谢同学们对本项目的支持,在日常使用中的反馈以及积极反应,以及对开发过程的理解和提供的帮助。
- 后面是一些我想写到博客里的闲谈:
其实开发这个工具本是无心之举。其实仅仅只是因为我觉得收核酸截图这道工序完全多余,费时费力还两边不讨好。本来大家每天都得核酸已经非常烦躁了,然而每次核酸后还得分时间段收集两张截图。如此,不仅让收截图的同学两头着急:一边交不上来图片,交上来的又会出很多的问题(格式凌乱、截图错误、不按要求等),一边又被老师催收,自己也没法安心干自己的事,甚至还会受限于地点和工具等问题;而对于交截图的同学,可能会因为自己的事忘交、漏交或者导致错交,又可能受限于设备或技术无法按要求交,每天两次地被反复催。
作为一名被收作业折磨已久的学委,我在大二上学期用编程基本解决了收作业、查作业、格式化命名的问题(记录在去年的文章上)。但在此之前,我也因收文件的问题苦恼不已,而对于如此频率的核酸截图收集,我想收截图的同学更是如此。
当然这些原因还不是驱动我做这个项目的真正原因……
真实原因可能是:在某一天早上我忍着困意关掉闹铃 打开智慧健康截图 然后去改名发现手机重命名不能相同 而困意满满我又找不到重复命名的截图 让我不得不爬下床去电脑上改名后 又被提醒交错截图了又滚下去重新操作……
此刻就像压倒大象的最后一根稻草一样究极地厌恶到了我,遂爬起来写了这个网站。
Fanqie
2022年9月记
项目摘要
注:内容摘自Java版项目设计文档:
自从新冠病毒爆发以来,核酸检测已经成这两年最火热的话题之一。根据国家的防疫政策,新疆大学一直积极配合防疫要求,按期进行核酸检测。尽管随着时间的推移,核酸检测的方式越来越完善,但依旧还是会给大家带来一些不便。为了解决核酸截图收集的问题,开发一个可以格式化管理集体核酸截图的网站显得愈发重要。
核酸截图格式化管理网站合理运用系统科学,管理科学,计算机科学,神经网络等知识,可以实现核酸截图的自动格式化命名,收集情况反馈,集体打包等功能。该网站可以解决集体收集核酸截图的管理、格式等问题,帮助了收集者更好的收集,方便了提交者的快速提交,让管理者一目了然收集情况。
该网站基于Python的Flask(Java的Springboot)进行开发,前端用到了layui等web框架,已经可以方便的做到核酸截图的收集管理,在日常的核酸收集任务中发挥独特的作用。
关键词:核酸截图;文件管理;Java;Python
开发背景
注:内容摘自Java版项目设计文档:
核酸检测作为冠状病毒疾病的诊断标准具有关键意义。核酸检测是间接找到病毒存在的证据,如果通过涂片或痰液采集的样本之中分离出病毒碎片,即检测结果为阳性,则表明该人已感染病毒。在彻底自然科学评估疫情风险和检测能力的基础之上,扩大核酸检测范围,不仅有利于精确防控,保护人民保健,也有利于合理流动人口,促进社会经济和生活秩序的彻底恢复。
随着我们对核酸检测的逐渐重视,同时也为工作人员、管理者带来了一定的麻烦,就比如我们平时要求核酸后收的两次截图,有时会耽误收集者的时间,占用一定的课上时间,造成不好的影响。不仅如此,频繁的收集给提交者也带来了一定的麻烦,譬如每次提交前要自主命名,要注重截图格式,要确保收集者是否收到等等。
针对以上问题,设计一款可以自动命名,格式管理的核酸截图收集网站,既方便了提交者的提交,又解决了收集者收集和管理的难题,保证了上交给管理者时文件的统一化和准确化,是一件很有必要的事情。
设计简述
注:
- 由于两次截图收集要求不同,故使用了两个网站,但结构和原理基本无异,这里以最简单的网站为例,后面不再赘述。
- Python和Java的设计方法基本一致,此部分内容摘自Java版项目设计文档:
收集功能:通过网页的upload页面实现。
格式识别功能:通过正则类regular部分实现。
图像识别功能:通过识别类OCR部分实现,调用了百度的图像识别API。
格式命名功能:通过命名类rename部分实现,此部分还负责了文件的存储等功能。
收集反馈功能:通过网页admin页面实现,反馈给收集者收集情况等,该类功能附带打包下载功能,具体在后端实现。
下图为格式化第一类截图(匹配本网站)的图片样张:
页面展示
注:部分内容摘自Java版项目设计文档:
upload.htmnl界面图,该界面是网站的主界面,作为上传地址分发给上传者负责完成上传工作:
admin.html界面图,该界面是管理者的操作界面,作为管理地址为给收集者提供帮助,负责完成管理及收集情况浏览工作:
upload界面上传成功图,本界面在文件上传成功后返回,看到该界面及完成识别上传成功:
后端测试
注:此部分内容取自真实使用环境:
测试环境以样张环境为例
打开网站upload界面,点击上传图片,选择一张未命名的核酸结果报告(见上文截图样张)。
点击上传,稍等片刻后显示上传成功(整个过程1s左右):
此时后端先进行OCR识别(以样张为例进行识别):
识别后进行格式判断(检测关键词,代码略)
若格式无误进行名字正则,以便于格式文件名
在规整文件的后,将通过mysql中的信息进一步重命名文件
同时文件信息将保存在mysql中,通过api反馈到前端上传页面和管理页面
此时即显示上传成功
在本地环境进行测试,多次上传成功后的存储文件夹如下:
打开管理界面(图例为某一测试情况,与上面测试无关)
截面图参照上文,点击只显示没交的:
可以发现此时列出的都是未提交的名单。
在本地环境进行测试,我们通过抓包此界面可以发现调用了接口/table。
该接口默认返回已经提及(是),也可以通过get请求过滤是否提交人:/table?is_submit=否(是)。可以发现如下json:
在本地环境进行下载演示,点击下载:
可以发现存放截图的文件夹,将重新命名,压缩打包并移动至网站的download路径下。
文件名的日期根据前一天设定(收集时在结果的次日),命名格式为学校固定的收集格式,可以反复下载。
在使用环境中点击下载按钮会调用浏览器下载功能进行下载,原件即为压缩包。
实用记录
注:此部分数据收集自网站后端:
在上学期的多个月的使用中,两个网站都进行了高频,有效的收集;起到了很大的帮助。下图为核酸结果截图网站的收集记录:
存储目录:
某一日期的收集记录:
下载缓存:
Java版开发日志
Java版开发于2022年6月,主要依赖于Springboot框架。
这里详细介绍一下网站的开发设计原理(Java):
接口设计:
根据springboot的使用文档,通过idea项目自动创建springboot框架,只需在框架的src/main文件夹中开始编辑即可。
在自动生成的HesuanApplication.java文件中进行接口编写,除了语言语法不同外,springboot的框架和Python的flask框架有异曲同工之妙,整体格式比较相近。在该文件中,为了保持代码的整洁性和调理性,主要设计为json的构造以及功能的调用。
根据需求,项目设计了4个接口:/upload;/table;/pack;/downloadzip
- upload接口绑定在upload.html界面,作为上传接口使用。文件通过接口上传后保存至本地(服务器),然后开始调用rename_s方法,进行功能的实现。如果没有抛出异常,网站将返回上传成功的json。
- table接口被admin.html界面绑定,主要用于收集者管理界面的表格数据填充。该接口首先调用mysql.java文件中的静态方法进行数据库查询,然后将全部信息构造成json反馈给前端。此处的json包含json数组,构造过程调用了Alibaba的开源方法,后又自己进行了拼接。
- pack接口主要用作打包zip,在admin.html界面调用,访问该接口会将文件进行压缩,并移动至download文件下保存,在今天内可以反复下载。需要注意的是,过时的文件需要管理员从服务器后台获取。该接口会返回打包成功的json信息。
- downloadzip接口在admin.html界面被绑定到pack后,点击打包会调用pack接口并弹出下载界面,点击下载按钮将跳转至downloadzip接口下载文件。该接口将制定文件读到流中返回至前端完成下载。
rename模块设计:
rename.java文件是后端的总体调用,其他模块都服务于该文件中rename类的静态方法rename_s。本文件设计了三个相关类:getData类、mvFile类、rename类,第一个类获取今日和昨日的日期,方便文件路径和文件存储地址的构造。第二个类对文件进行移动操作,将收集的文件从临时文件夹移动到存储文件夹,并保存文件的存储地址,便于改名。第三个类对文件进行格式化操作,在文件移动后进行ocr识别,识别完成进行关键点正则,对正则结果进行判断,无误则开始文件格式化。上传的文件统一为jpg格式(jpg、jpeg和png互相兼容)命名会根据正则得到的名字与数据库进行比对,从数据库获取规范文件需要的信息,进行格式化命名。
需要注意的是,重命名不限于单个文件,可以同时对临时文件夹的多个文件格式化,但在设计后端时为了保证高效率,设置为提交后自动识别。另外,该模块涉及的功能需要数据库查询操作mysql类和其他模块的支持。
识别和正则模块设计:
识别和正则文件构建在OCR.java和regular.java文件中,OCR文件由三个类组成,其中baiduapi类取自百度api的官方文档,用以获取token等数据,Baseimg64类用来将图片转换为base64格式,OCR类用于构造请求,进行图片识别,该类将返回未经处理的识别结果。
正则模块只有regular一个类,其中设计了三个静态方法,分别是对名字,格式判断以及对结果进行正则,正则完会返回姓名,再调用名字判断方法。
识别模块和正则模块配合使用,用以获取图片信息,并拦截垃圾图片和错误格式图片。
打包和下载模块设计:
打包和下载模块都保存在download.java中,其中download类用构造方法重写了文件打包前后的地址以便于downloadzip接口和pack接口的调用,以及下载模块使用。zip_file类包含了一套完整的zip打包方法,其思路为根据提供的地址逐层查找文件夹和文件,若发现文件夹则进行递归操作继续查找,并通过当中zip方法对每个文件进行压缩,最终返回一个完整的压缩文件。
打包和下载模块配合使用,能将文件完整的压缩成zip,下载模块在其他接口中被调用,来提供压缩和下载的路径构造。
数据库操作:
java的JDBC操作,没有什么特殊设计,包含以下函数:
- getNameAndStunum():获取mysql中的姓名和学号,返回二维数组
- getALL(String submit):获取提交/非提交列表全部信息,默认提交,返回二维数组
- getSUBandUNSUB():获取提交和未提交的数量,返回int数组
- updateIS_SUB():更新是否提交
- resetIS_SUB():重置提交信息全部为否
文件结构(左侧):
注:右侧为重命名的main函数调用。
Python版开发日志
Python版本开发于2022年4月,主要依赖于flask框架。
由于开发的日期过早且Java版是Py版的复写,所以这里对比一下和Java版的不同:
ps. Python的flask框架下挂了两个网站,java由于是作业只写了一个
接口设计:
同java部分不一样,flask设计了3个接口:/upload;/table;/pack
download函数直接在pack接口被调用,py版本的打包和下载是一个整体操作,而不是分开的接口;springboot的主界面只设计了接口调用,而flask的主界面包含了download函数和接口调用。
其他部分设计思路基本一样,主要区别在代码的写法以及数量上。
rename文件:
因为java代码较为复杂的原因,java版本的rename文件单纯负责改名及其相关操作;而Python代码较为简单且Py的第三方库较多,所以raname文件包含了java的OCR、regular、rename模块。
即rename文件中大概包含了以下函数:
- ocr()函数:调用百度API进行识别,功能与OCR.java相同,参见上文识别和正则模块设计。
- end()函数:移动文件函数,功能与rename.java中的mvFile类相同,参见上文rename模块设计
- regular()以及相关正则、判断函数:正则、判断截图格式与识别结果,功能与regular.java相同,参见上文识别和正则模块设计。
- rename()函数:重命名,功能与rename.java中的rename类相同,参见上文rename模块设计。
- init()函数:即为重命名的调用函数,相当于rename.java中的rename_s和main函数。
mysql文件(数据库操作):
Python的mysql操作,调用pymysql库,包含以下函数:
- getHesuanSituation(args):获取是/否提交相关人员全部信息,默认为否;以及全部人、未上交人的数量。直接构造了json并return。
- updateSubmitStudent(name):更新指定人员为已提交,与java不同处为接收了name参数,但使用方法相同。直接构造了json并return。
- resetSubmitStatus():重置提交信息全部为否。
- readmysql():获取mysql中的姓名和学号,返回元组。
由于代码复杂度原因以及其他原因,此处相比java简化了数据库的部分操作,见对比图:
下图为java的获取全部列表(不包含是否提交以及数量返回):
下图为python的获取全部列表(包含是否提交以及相关数量):
文件结构(左侧):
注:右侧为重命名的main函数调用。
Springboot使用感受
注:以下感受仅为我的主观臆断
- 取决于java面向对象的复杂性,用springboot进行开发代码量会很大
- java的开发难度更大,很多地方不好简写,只能把功能展开写
- 第一次用java开发这种项目,装环境挺费事,不过IDEA确实有效减少了xml配置难度
- springboot的依赖很多,java包有些也比较乱,用法差别很大,需要不断的查资料
- 直接使用springboot这种快速开发框架比自己写tomcat连接方便的多,比spring项目开发难度低很多。
- springboot接口配置需要学习的很多,我还不是很熟悉
Flask使用感受
注:以下感受仅为我的主观臆断
Py作为解释性语言,语法简单,处理数据方便,开发时代码量小
Py可以简单的做到功能合并,让一个函数直接解决多个问题而不占很多的代码
配置简单,部署服务器简单,直接跑代码就行
第三方库很多,很多方法都有现成的工具使用,而且安装很方便
由于我写的不规范,有些地方很乱,这个在java中有改善
flask比较轻便好理解,刚好适用于这种小型网站的开发,但是可玩性不大
第一次写web使用flask,对新手非常友好,三天入门
flask与springboot的开发对比
结合上面的部分对两框架进行一下对比,仅代表个人观点:
相比于Java的springboot框架,我更偏向于使用Python的flask框架进行开发理由如下:
- Python在linux上的部署方便,目前主流的Linux如ubuntu、centos等都自带py3,只需要安装第三方库即可
- 我更偏向于python代码形式,码风简单,解决问题方便,数据处理快速,作为管理型网站的后端刚刚好
- 解释型语言编译基础低,网上也有很多现成的代码,读起来也更通俗易懂,学习成本低
- 使用flask的开发周期短,给人的思路更明确,适合自己开发;而springboot开发周期长,适合合作开发
- 本作品复写的java后端代码大概800行,Py后端代码大概300行,趋近于三分之一
- 在日常使用中我的Py经验更多,而java经验不够丰富
- 在不追求时间效率的情况下,小型网站用flask开发优势更明显
但在我眼里,相比于flask,springboot并非没有开发优势:
- 在开发非管理型(后代)网站时使用python代码并不一定占优势
- 若网站需要处理的数据较多,例如大型网站等,java相对较快
- 开发安卓接口应用接口时使用java更方便
- 尽管其他的还没遇到,但java作为主流的后端语言之一,比python更热门,一定有着自己独特的优势,后面我会继续学习
项目总结
注:部分内容摘自java版项目设计文档:
通过本项目的实践,进一步掌握了通过Python和Java写web后端的方法,填充了在flask与springboot上的的开发经历,拓宽了我的代码认知和代码量。本次项目我独立编写了基于python flask和java springboot的核酸截图格式化管理网站,后端思路取自我对前些项目开发后的代码经验以及设计经历,此项目已经为班级同学多个月以来的核酸截图收集做出了很大的贡献。因此我相信,本项目是有很大的实际应用意义的,相比于其他管理系统,更贴近我们的生活,切实解决了我们生活中的难题,我认为这就是编程的意义所在。
尽管前端使用了layui框架进行辅助,大大减少了前端设计的工作量,但其依旧保证了界面的简洁美观和使用,让我更多的注重到后端代码的实现中去。作为一名后端开发者,我认为本次项目的前后设计都满足了我的设计要求和初衷,是一个成功的项目。
后端的部分模块参考了网上论坛的一些代码,例如压缩,识别等部分,非常感谢这么多的无私奉献者对我的帮助,我也认真学习了这些部分,这些经验会在以后给我带来很大的帮助。
经此,我对Python以及Java有了更多的认识,在开发时也有了更多的选择和理解,相信会为后面的实践奠定基础,让我的代码之路更加辽阔。
作者:Fanqie 联系方式:2740908911@qq.com
注:本文及文中内容未经允许禁止私自转载或使用!
真棒!
psphjmarza 7 天前
谢谢
fanqie 3 天前 回复 @psphjmarza