简介:一套基于Java的面向本科毕业设计与课程设计的智能垃圾分类系统完整项目,适合计算机相关专业学生参考借鉴,也可作为项目实战练手素材。资源包共548个文件,整体约59.14MB:含74个Java后端源码、28个前端页面、16个小程序页面及17个样式文件,同时包含脚本、样式表、配置信息与SQL数据库脚本,并附说明文档与演示视频。已有93人学习。项目围绕垃圾分类场景,核心功能涵盖垃圾类别维护、分类信息检索、用户提交记录、识别结果展示和数据统计等,演示视频展示完整运行流程,数据库脚本与各类配置可辅助快速搭好运行环境。源码按前端、后端、配置等结构分目录存放,模块边界清晰,便于按需阅读、部署和二次开发;配套说明对系统设计也有梳理,适合毕业设计说明书撰写与答辩准备。
1. 这套Java垃圾分类毕业设计,不是算法项目,是一套完整可跑的Web系统
先说结论:这套名字带"智能"的垃圾分类系统,本质上不是算法项目,而是一套非常标准的Java Web后台管理系统。业务主题是垃圾分类,实现方式是管理员维护垃圾类别、用户查询分类规则、投放记录留痕,配上数据库脚本、说明文档和一个操作演示视频,属于"拿来就能跑、跑完能答辩"的成果。它适合两类人:一类是正在赶课程设计或毕业设计,需要一个完整可运行系统去打底的在校生;另一类是刚学完Java SE,想知道数据库、后端、前端怎么凑成一个闭环的初学者。你不需要懂机器学习,也不用会写神经网络,把Java Web这一条链路走通,这个系统就是你的了。
2. 翻资源包看设计:layui静态资源表就是技术栈说明书
2.1 从CSS文件名反推前端架构
拆包的时候,我习惯先不碰Java源码,先翻静态资源文件。这套包里躺着一排CSS,基本已经能复现前端的选型:
| 文件 | 作用 | 判断依据 |
|---|---|---|
| layui.css | layui 主框架样式 | 页面栅格、按钮、表单美化的基础 |
| layer.css | 弹窗组件样式 | layer 是 layui 生态里最常用的弹出层 |
| laydate.css | 日期控件样式 | 统计查询里选时间范围时用 |
| zyupload-1.0.0.min.css | 文件上传组件 | 管理员维护图片或台账时上传文件 |
| iconfont.css | 阿里图标库 | 菜单和按钮的图标来源 |
| font-awesome.css / font-awesome.min.css | Font Awesome 图标库 | 图标库冗余,两个保留一个即可 |
| layuimini.css | 后台布局框架 | 左侧菜单加顶栏加内容区的管理台骨架 |
| uni.css | 通用样式覆盖 | 通常是作者对默认样式的补充修正 |
这套组合说明前端没有上Vue或者React,而是经典的"服务端页面加layui"方案。Java后端把接口数据返回,前端通过AJAX渲染,表单提交、弹窗提示、日期选择、文件上传全部由layui生态搞定。选型理由也很现实:毕业设计求稳,layui不需要npm、不需要node_modules,一个静态目录扔进去就能用,学习成本比前后端分离低一个量级。
后端方面,我拆过的同批资源绝大多数是Spring Boot骨架,少数老项目是Spring MVC加JSP。拿到手第一步是找pom.xml或者build.gradle,看一眼依赖就知道是不是Spring Boot。这个动作很重要,因为Tomcat端口、静态资源放行逻辑、拦截器配置都跟这个直接挂钩。
2.2 演示视频和说明文档的正确食用顺序
资源包里那个垃圾回收.avi,别到最后一天才打开。我第一版的使用顺序是:
- 先用播放器倍速过一遍演示视频,它会展示从登录到增删改查的完整操作路径,这比读说明文档快得多;
- 再打开说明文档,对着视频里的操作路径去源码里找对应位置,优先看登录校验和垃圾类别管理两个模块;
- 最后再动手改代码,不要上来就改,先把原版跑通再动刀。
视频是AVI封装,老编码格式,直接双击打不开的情况很常见。我一般会用PotPlayer或VLC试播,如果提示缺解码器,就转成MP4再看,转码命令在后面的避坑章节里统一给。这一步看着小,但每次答辩之前都会卡人。
3. 环境与部署:在本地把整套系统跑起来
3.1 JDK、MySQL、IDE版本怎么搭配才不打架
先给结论:Java后端项目最稳的组合是JDK 8加MySQL 5.7加一个支持Maven的IDE,Spring Boot版本对应2.x的都跑得起来。JDK 11或17也能跑大多数项目,但部分老依赖在JVM参数上会有兼容性警告,答辩现场环境不稳定是大忌。
为什么强调JDK 8?因为这类毕业设计源码大量使用javax命名空间,JDK 8是最后一代原生支持javax的版本。Spring Boot 2.x系列官方也明确支持到JDK 8。MySQL选5.7是因为它的sql_mode比较宽松,导入导出SQL脚本不容易翻车;MySQL 8的时区和认证插件改过,老脚本直接导入经常报错。
IDE方面,IDEA和Eclipse都行。区别在于IDEA对Maven的支持更顺滑,导入pom.xml之后会自动识别项目结构;Eclipse需要手动转换成Maven项目。如果你机器上同时装了多个JDK,记得在IDEA的Project Structure里把Project SDK指到JDK 8,不然编译报错的时候你会怀疑人生。
还有一个容易被忽略的点:Maven仓库。国内网络拉依赖经常超时,我一般会在settings.xml里配好阿里云镜像,再去IDEA里reimport一次。这一步能省掉后面至少半个小时。
3.2 建库、导数据、改配置、启动后端
操作步骤如下:
- 在IDEA里用Maven导入根目录的pom.xml,等待依赖下载完成;
- 在MySQL中创建空数据库,字符集选择utf8mb4;
- 执行包内的SQL脚本,导入表结构和测试数据;
- 打开配置文件,把数据库地址、账号、密码改成自己的;
- 启动后端,浏览器访问默认端口,进入登录页。
导入SQL脚本常见做法是直接拖进Navicat执行,命令行也是等价的:
mysql -u root -p # 进入MySQL客户端后依次执行 CREATE DATABASE IF NOT EXISTS garbage DEFAULT CHARSET utf8mb4; USE garbage; SOURCE /your/path/garbage.sql;需要留意的是SOURCE后面的路径要写绝对路径。SQL脚本里面如果有外键约束,导入顺序错了会影响执行。导入完成之后,用SELECT COUNT(*)看几张核心表的数据量,确认不是空库再往下走。
接下来看配置文件。Spring Boot的配置通常长这样:
spring: datasource: url: jdbc:mysql://localhost:3306/garbage?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver关键参数说明:
- useUnicode和characterEncoding:保证中文不乱码,前端到后端再到数据库,全链路全靠这两个参数兜底;
- serverTimezone:不加的话,新版MySQL驱动会报时区错误,典型的报错是CST与UTC的八小时偏差;
- driver-class-name:MySQL 5.7配5.x驱动,MySQL 8必须用com.mysql.cj.jdbc.Driver,版本不对直接抛ClassNotFound。
改完配置启动后端,别急着点页面。看启动日志里出现Started ... in X seconds才算真正起来了。如果端口被占,最常见的是8080被别的进程抢了,具体定位命令后面避坑章讲。
3.3 登录进去先看哪几个页面验收
系统跑起来之后,先不要急着乱点,按验收顺序来:
- 登录页:验证正确账号能进、错误密码有明确提示,这是拦截器生效的基础证明;
- 首页后台布局:确认左侧菜单能展开、能折叠、能跳转,这是layuimini渲染结果的直接检验;
- 垃圾分类查询页:输入关键词,看结果是否正常落库、中文是否正常显示;
- 管理后台的垃圾类别列表:能增删改查,CRUD闭环通了,才说明后端接口真的连上了。
这一套走完,基本能确定这套系统在你的环境里是健康的。之后再谈改需求,不要在一个没跑通的项目上直接动刀。
4. 核心逻辑:垃圾分类查询、积分和后台管理怎么串起来
4.1 分类规则的存储模型与查询链路
垃圾分类系统的核心不是算法,是数据表设计。常见做法是把垃圾类别主表和分类明细表拆开:主表存类别类型,比如可回收垃圾、有害垃圾、厨余垃圾、其他垃圾;明细表存具体物品名称、所属类别、投放提示和处置说明。
查询链路的典型流程是:前端搜索框输入关键词,后端Controller接收参数,调用Service层查询明细表,返回匹配列表,前端用layui的table组件渲染。核心Service方法的写法大致如下:
@Service public class GarbageCategoryService { @Autowired private GarbageItemMapper garbageItemMapper; public List<GarbageItemVO> searchItems(String keyword) { // 关键词为空时返回空列表,避免全表扫描 if (keyword == null || keyword.trim().isEmpty()) { return new ArrayList<>(); } // 这里走的是数据库模糊查询,而不是遍历内存 return garbageItemMapper.selectByKeyword("%" + keyword.trim() + "%"); } }这段代码说明两个问题:一是查询走的是MyBatis的Mapping文件,SQL里的LIKE条件配合前后百分号实现模糊匹配;二是Service层做了入参校验,空关键词直接返回空列表。很多初学者喜欢把全部数据查出来再在Java里遍历过滤,数据量小看不出问题,数据量一大就卡死,答辩现场最容易翻车。
对应的SQL大约是:
SELECT id, item_name, category_type, dispose_tips FROM garbage_item WHERE item_name LIKE #{keyword} OR category_type LIKE #{keyword} ORDER BY category_type ASC, id DESC;这里有个细节:ORDER BY先按类别排序,再按ID倒序。这样同类垃圾会聚在一起,页面上展示更整齐。如果按ID正序,新增的垃圾分类会排在最后,体验反而不如倒序好。
4.2 管理端CRUD与上传组件闭环
管理端是整个系统的重头戏。管理员登录后台后,要对垃圾类别做增删改查,这个闭环绕不开上传组件和表单校验。
以新增一条垃圾分类为例,前端用layui的弹窗表单收集数据,图片上传走zyupload组件,后端接收MultipartFile保存到本地目录,同时把文件路径写进数据库。这里最容易踩的坑有两个:一是保存文件的物理路径和数据库里存的路径不一致,二是上传目录没有写权限导致文件保存失败。
上传保存逻辑常见写法如下:
@PostMapping("/admin/garbage/save") @ResponseBody public Result saveGarbage(@RequestParam("file") MultipartFile file, GarbageItem item) throws IOException { // 文件原名带路径,必须截取文件名部分,否则会有路径注入问题 String originalFilename = file.getOriginalFilename(); String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")); String newFileName = UUID.randomUUID().toString().replace("-", "") + suffix; // 保存到项目外的独立上传目录,避免打包后路径失效 String realPath = System.getProperty("user.dir") + "/upload/"; File dir = new File(realPath); if (!dir.exists()) { dir.mkdirs(); } file.transferTo(new File(dir, newFileName)); item.setImagePath("/upload/" + newFileName); garbageItemService.insert(item); return Result.success(); }参数要点:
- UUID重命名:避免用户上传的图片文件名带中文或空格,造成URL访问乱码和路径解析失败;
- 上传目录用System.getProperty("user.dir")拼出项目运行目录,而不是写死绝对路径,这样换机器不用改代码;
- 数据库存的是相对路径/upload/xxx.jpg,页面访问时通过静态资源映射去磁盘上找文件,路径一旦不一致图片就裂了。
这里我多说一句:很多毕设项目在IDEA里跑得好好的,打成jar包部署到服务器就找不到上传文件了,根因就是用了target目录内的相对路径。用user.dir拼上传目录能避开一半的问题,另一半靠后续避坑章里的静态资源映射配置解决。
4.3 登录会话与权限区分
这套系统里通常有两类角色:普通用户和管理员。普通用户能查分类、看积分;管理员能维护垃圾类别、处理投放记录。区分角色的常见实现方式是在用户表里加role字段,登录成功后把用户信息和角色塞进Session,前端根据角色决定菜单显示项,后端用拦截器做权限校验。
后端拦截器的关键逻辑如下:
public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object user = request.getSession().getAttribute("loginUser"); if (user == null) { // 这里不能直接转发,要区分AJAX请求和页面跳转 if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) { response.sendError(401, "未登录"); } else { response.sendRedirect("/login.html"); } return false; } return true; } }这个拦截器是很多项目的基础骨架。注意里面区分了AJAX请求和普通页面跳转:如果是layui的table组件发AJAX拉数据,遇到未登录时返回401状态码,前端统一弹登录提示;如果是普通页面访问,直接重定向到登录页。很多新手拦截器不区分这两种请求,导致登录超时后table接口返回一堆登录页HTML,前端渲染直接崩掉。
权限控制不要每行代码都去判断角色,而是把角色信息存进Session,前端菜单按角色渲染,后端在需要管理员权限的Controller方法上单独校验。这样既保证普通用户看不到管理菜单,又不能绕过前端直接调管理接口。
5. 避坑记录:答辩前最容易翻车的五个地方
5.1 中文乱码:从URL到MySQL字符集全链路排查
现象:页面上输入中文搜索垃圾类别,结果全是问号或者乱码。
原因:字符集链路断了。前端页面编码、后端请求编码、数据库连接编码、数据库表编码四处只要有一处不一致,中文就保不住。
解决:从前到后统一成UTF-8。前端页面在head标签里加charset声明,后端在配置里保证characterEncoding=utf8,MySQL建库时指定utf8mb4,连接串里带上useUnicode=true和characterEncoding=utf8。改完重启服务,重新导入SQL。如果还乱码,用MySQL的SET NAMES utf8mb4再执行一遍SQL。
5.2 启动闪退与端口占用的定位思路
现象:IDEA点击运行,控制台闪一下就停;或者报APPLICATION FAILED TO START,提示Port 8080 was already in use。
原因:闪退通常是配置错误或依赖缺失,端口占用则是本地已经有进程霸占了8080。
解决:先在命令行确认端口占用:
netstat -ano | findstr 8080 taskkill /PID 上面查到的PID /F占用进程也可能是你自己上次启动没停干净,直接任务管理器结束对应Java进程。如果端口没被占但还是闪退,看日志前几行,重点找Caused by后面的异常描述,八成是数据库连不上或者配置项写错。这时候别慌,从上往下读日志,第一条Caused by才是根因。
5.3 演示视频AVI打不开
现象:双击垃圾回收.avi,播放器提示无法解码,或者只有声音没有画面。
原因:老编码格式的AVI没有对应的解码器,Windows自带的播放器经常兼容不了。
解决:用FFmpeg转成MP4,这一步兼容性最好:
ffmpeg -i 垃圾回收.avi -c:v libx264 -c:a aac 垃圾回收.mp4参数说明:libx264是通用H.264编码,aac是通用音频编码,转出来的MP4在主流播放器和PPT里都能放。如果不想装FFmpeg,也可以用格式工厂或PotPlayer自带转换功能。转完记得在答辩用的电脑上提前试播一遍,别在讲台上才第一次打开。
5.4 页面样式全丢:静态资源路径与拦截器冲突
现象:登录能进,但页面加载出来没有CSS,纯HTML文字排成一列,控制台一堆404。
原因:两个方向排查。一是静态资源路径引用不对,resources目录下的CSS路径和页面里写的路径不一致;二是Spring Security或拦截器把CSS请求也拦住了,导致静态资源被302到登录页。
解决:先看控制台404的URL,如果路径对不上,改页面里的引用路径,让css、js、img目录落在Spring Boot默认识别的static目录下。再看拦截器配置,放行静态资源路径,常见写法是这样:
registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/login", "/register", "/css/**", "/js/**", "/images/**", "/upload/**");excludePathPatterns里的路径一定要和实际访问路径匹配。很多人漏掉/upload/**,导致上传的图片在页面上全部403。
5.5 数据库时间差了八个小时
现象:后台录入一条投放记录,列表里显示的时间比实际时间早8个小时。
原因:JDBC连接串没加serverTimezone参数,MySQL驱动默认用服务器本地时区解析,和本机系统时间差了时区。
解决:在数据库连接串末尾加上serverTimezone=Asia/Shanghai,然后重启后端。如果时间已经存错了,用SQL批量修正:
UPDATE recycle_record SET create_time = DATE_ADD(create_time, INTERVAL 8 HOUR) WHERE create_time < '2020-01-01 00:00:00';需要注意这个修正条件要按你实际导入数据的时间边界去调,千万别全表更新,否则会把正常数据也改歪。
6. 答辩前做减法:清空演示数据、把垃圾类别换成你自己的
6.1 数据重置:保留表结构清掉业务数据
这套包自带的数据库里会预置不少测试数据,平时练习没问题,答辩演示的时候很尴尬——老师一看就是别人的数据。我的习惯是答辩前做一次数据重置,保留表结构,清空所有业务数据:
SET FOREIGN_KEY_CHECKS = 0; TRUNCATE TABLE recycle_record; TRUNCATE TABLE garbage_item; TRUNCATE TABLE user_info; SET FOREIGN_KEY_CHECKS = 1;TRUNCATE和DELETE的区别在于,TRUNCATE清空后自增ID从1重新开始,页面展示更干净。如果系统里有些表是字典表,比如垃圾类别主表,不要清,只清业务数据表。清完自己重新造几条贴近你学校场景的垃圾分类数据,比如你们校区的垃圾桶分布、常见外卖包装分类,演示的时候讲起来顺很多。
6.2 改分类字典与前端文案
垃圾分类系统的演示效果很大程度靠分类字典和文案。我的习惯是顺着演示流程把页面上的固定文案全部过一遍:登录页标题、首页欢迎语、垃圾类别名称、投放提示语。这些文案通常集中在数据库字典表和前端HTML里,用IDEA全局搜索关键词能快速定位。
改完文案之后重新走一遍演示顺序:登录、查一个具体物品、看分类结果、录一条投放记录、去管理后台审核。保证每一步都有真实数据支撑,而不是录完就卡在空列表页。从那以后我每次接手这类毕设源码包,第一件事永远是先重置演示数据、替换成自己的业务样本,跑通一遍验收流程再录视频、再写说明文档。整个过程看着麻烦,但能让你在答辩场上少被追问十分钟。希望帮到你。
本文还有配套的精品资源,点击获取