每年到了三四月份,我的私信里就会被同一类问题塞满:“学长,毕设选什么题目好?”“SSM的框架能不能做个商城项目?”“球鞋交易的平台有没有参考?”今年也一样,而且明显感觉问球鞋交易平台的人比往年更多了。原因不难猜——这类题目自带话题度,技术栈又刚好落在很多高校Java课程的主线上,再加上“源码+论文”整套交付物齐全,对想平稳毕业、又想给简历留点内容的同学来说,确实是个很顺的选择。
今天这篇就把这个选题从里到外拆一遍。从为什么值得选、系统怎么改、数据库怎么建,到SSM整合的真实踩坑、核心业务代码怎么写,最后聊论文和答辩怎么过关。内容按一套能落地的球鞋交易平台来展开,目标人群是准备做JavaWeb方向毕设的本科生,以及想拿SSM练手但不想看一堆枯燥文档的朋友。你不需要一开始就会Spring,只要认真跟完这篇,至少能把整个项目的地图装进脑子里。
1. 选题前后想清楚的几件事:为什么球鞋交易平台适合当毕设
毕设选题这件事,表面看是“挑个名字”,实际上是在挑三样东西:业务你熟不熟、技术栈能不能覆盖课程要求、工作量会不会失控。球鞋交易平台在这三方面都卡得刚刚好。
1.1 产品定位天然带有“可写性”
球鞋交易平台的本质是什么?是面向球鞋爱好者的交易系统。但它跟普通商城不一样的地方在于,用户买一双鞋之前,会关心真伪、会看市场价格、会翻别人的上脚评价。所以这个系统天然是“电商+社区”的混合体,前台有商品展示、购物车、订单,后台有商品审核、鉴定管理、订单处理。
这种“比普通商城多一层鉴定和社区”的业务模型,放在毕业论文里特别占便宜。需求分析章节有的写,系统设计章节有得画,系统实现章节也有东西可截图。反观图书管理系统、班级管理系统这类题目,业务逻辑太单薄,写到第三章需求分析就开始编,根本撑不起页数。
1.2 技术覆盖度刚好是JavaWeb教学的主线
SSM是Spring、SpringMVC、MyBatis的缩写。这三个框架放到今天的视角看,确实没有Spring Boot那么“现代化”,但高校课程和很多实训项目至今仍然在用它们讲分层架构,就是因为SSM把一个Web系统拆得非常清晰:Spring管业务对象和事务,SpringMVC管请求路由和参数绑定,MyBatis管SQL和结果映射。
用SSM做球鞋交易平台,你几乎能把大学四年JavaWeb相关的所有知识点全部串起来。IOC容器、AOP事务、拦截器、Session、动态SQL、分页、文件上传、事务隔离级别——这些词看起来多,但每一个都是一个明确的模块,论文里各写一段,工作量非常好看。而且答辩的时候老师问“Spring和SpringMVC分别负责什么”“MyBatis动态SQL怎么用的”,你都能拿真实代码去回答。
顺带说一句:如果学校没有强制指定技术栈,用Spring Boot做确实更省事。但如果题目已经写死“SSM”,不要慌,SSM不是劣势,反而能让论文里多出一节“SSM与Spring Boot的对比分析”,这是一个天然的加分小节。
1.3 对比常见选题:差异感就是优势
每年最不缺的毕设题目就是“在线商城系统”“图书管理系统”“二手交易平台”。不是说这些题目不行,而是你答辩的时候,老师可能已经看了三份一模一样的了。球鞋交易平台本质上还是电商,但它的业务包装让整个系统看起来有具体的用户群体和场景——球鞋收藏、潮流文化、二级市场价格波动,这些都是真实存在的内容,导师一眼就能看出你不是在空造需求。
我在给学生的选题建议里通常还会加一句:不用去写那些看起来特别“高大上”的题目,比如什么“基于深度学习的球鞋图片识别系统”。那类题目标题的确亮眼,但里面涉及算法训练、数据标注、模型部署,根本不是一个人毕设周期能搞定的。球鞋交易平台是“看起来普通、做起来不难、写出来不缺东西”的稳妥路线。
1.4 控制在合理的工作量范围内
一个能顺利毕业的球鞋交易平台,工作量大概是这样:8到10张核心表,30到50个后端接口,前台页面10到15个,后台页面8到10个。一个人全职做的话,框架环境搭好以后,每天写4到6个小时,大概三到四周能把核心业务全部跑通。如果算上写论文,整个周期控制在8到10周是很舒服的节奏。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 功能模块与角色权限:别把简单业务做成大杂烩
很多同学做毕设有一个通病,一开始脑洞很大,今天想加社区论坛,明天想加直播间,后天又想搞秒杀。结果代码越写越乱,论文也收不了口。我的建议非常直接:先锁死核心交易闭环,其他功能一律当成加分项,能不做就不做。
2.1 三类角色来划分权限边界
这套系统里有三类人:普通用户、卖家、管理员。为了方便论文里的用例图绘制,我一般建议把“买家”和“卖家”合并成同一个用户角色,用用户在平台内的行为来区分身份。换句话说,每个用户都可以浏览商品、下单购买,也可以发布商品出售,而管理员是独立角色,负责平台整体运营。
这样设计的好处很多,最明显的就是用户表不需要拆成两张,登录注册只写一套逻辑,表关系也清爽。如果你还是希望买家卖家分开,那也完全可以,但在你的论文里要多画好几张用例图,并且要解释为什么分开,工作量会膨胀。对毕设来说,合并角色是性价比更高的选择。
2.2 前台功能清单
前台主要服务的是“逛鞋、买鞋、卖鞋”这三个动作。最核心的模块是商品模块、购物车模块、订单模块和用户中心。商品模块负责列表展示、关键词搜索、分类筛选和商品详情;购物车负责加购、修改数量、结算;订单模块负责提交订单、模拟支付、查看订单状态、确认收货;用户中心负责个人信息维护、收货地址管理、我的收藏、我发布的商品,以及我发起的鉴定申请。
额外可以做的模块是求购板块和评论板块。求购板块让买家发布“想买某双鞋”的需求,卖家看到后可以联系;评论板块是用户在订单完成后对商品做评价。这两个模块对业务闭环是一种补全,而且实现难度很低,各加一张表就能撑起来,属于性价比极高的加分项。
2.3 后台功能清单
后台是给管理员用的,功能一般包括:用户管理(查看用户列表、禁用账号)、商品管理(审核新发布的商品、下架违规商品)、订单管理(查看全平台订单、处理退款申请)、鉴定管理(审核用户提交的鉴定申请,给出鉴定结果)、数据统计(用一个图表展示商品销量或用户增长)。如果怕太复杂,数据统计可以不做,但如果做了,建议用ECharts画柱状图或折线图,视觉效果好,论文截图也漂亮。
后台和前台建议用两个不同的路径前缀区分,比如前台走/product/list,后台走/admin/product/list,这样拦截器配置起来非常顺手,权限控制也直观。
2.4 鉴定流程:真正体现“球鞋”特色的地方
球鞋交易和普通二手交易最大的区别在于真伪问题,所以鉴定功能是这套系统的灵魂。毕设里鉴定流程建议做成这样:普通用户在提交订单时或者收到货后,可以对自己购买的商品发起鉴定申请,上传球鞋照片;管理员在后台看到鉴定申请后,根据照片给出“通过”或者“未通过”的结论;用户在前台查看鉴定结果。
这个流程不需要引入任何真实的外部API,管理员人工审核就够论文用了。你可以在论文的展望部分提一句“后续可以接入第三方鉴定机构的AI识别接口”,这就够了。不要真去做调用外部接口,那只会给自己挖坑。
2.5 模块边界怎么控制才能不拖期
我见过太多人做电商项目,做着做着就想加优惠券、加充值、加轮播广告、加积分系统。这些功能每一个单看都很简单,但合在一起就会拖垮你的进度。我自己定的边界是:用户能在平台上完成“注册→浏览→下单→支付→收货→评价”的完整链路,就已经达到了毕设合格线;后台能完成“商品审核→订单发货→鉴定审核”的闭环,就已经超过了良好线。限量发售、抽签购买、加价购这类球鞋电商特有的玩法,不要动,那些是答辩时嘴上说说“未来可以扩展”的素材。
3. 数据库设计的取舍:从用户表到订单明细表的落地思路
数据库设计是整套系统的地基。地基歪了,后面代码写起来处处别扭;地基正了,很多业务逻辑其实就是对表的增删改查。球鞋交易平台的表设计并不复杂,但有几个地方需要想清楚再做,尤其是订单主表和明细表的关系、商品库存的扣减方式、以及图片字段的存储策略。
3.1 整体表结构概览
我建议的核心表有九张:用户表、收货地址表、球鞋分类表、球鞋信息表、购物车表、订单主表、订单明细表、收藏表、鉴定记录表。如果你想加评论功能,再加一张评论表;想加求购功能,再加一张求购表。这些表的命名建议用下划线风格,Java实体类里用驼峰风格,MyBatis里开启驼峰映射,两端就能自动对齐。
| 表名 | 作用 | 归属模块 |
|---|---|---|
| t_user | 用户账号、角色、密码、头像 | 用户中心 |
| t_address | 用户收货地址 | 用户中心 |
| t_category | 球鞋分类(篮球鞋/跑鞋/板鞋等) | 商品模块 |
| t_shoes | 球鞋商品信息 | 商品模块 |
| t_cart | 购物车记录 | 购物车模块 |
| t_order | 订单主表 | 订单模块 |
| t_order_item | 订单明细表 | 订单模块 |
| t_favorite | 收藏记录 | 用户中心 |
| t_identify | 鉴定记录 | 鉴定模块 |
3.2 用户表:密码安全不能省
用户表是最基础的表,字段大概是这样:主键id、用户名、密码、昵称、手机号、邮箱、头像、角色、状态、创建时间。密码这块,不要明文存数据库,但也不需要搞复杂的加密算法。毕设里常见做法是MD5加盐,也就是把密码和一个随机生成的字符串拼接后再做MD5计算。你可以在用户表里加一个salt字段存这个随机串,也可以在注册时生成统一盐,前者更规范。
角色字段建议用int类型:0代表普通用户、1代表管理员。状态字段用1和0表示正常和禁用。当你做登录的时候,除了校验密码,还要判断状态是否为1,否则被管理员封号的人还能继续登录,这会在答辩时被老师揪出来。
3.3 球鞋商品表:一个商品一个SKU足够了
球鞋商品表的主要字段有:主键id、商品标题、分类id、卖家id、品牌、型号/货号、颜色、尺码、价格、库存量、封面图url、商品描述、上架状态、浏览量、创建时间。
这里有一个很关键的取舍。在真实的电商系统里,“一双鞋”往往对应多个SKU,也就是同一款鞋有不同尺码和不同价格,每个SKU单独计算库存。但毕设系统里如果做成多SKU,需要新增一张商品规格表,前后端逻辑也会复杂不少。我强烈建议第一版只做一个商品对应一个SKU,把尺码当作商品的一个普通字段存进去,库存直接存在商品表里。这样你在论文里写“本系统设计了一对一简化的商品模型,便于聚焦交易核心流程”,完全说得通。
库存扣减的问题后面会细讲,但设计表的时候就要注意,库存字段是int类型,并且要求非负。建议在数据库层面加约束stock >= 0,这样即便代码里万一漏了判断,数据库也能兜底。
3.4 购物车表:唯一索引防重复加购
购物车表字段比较简单:主键id、用户id、商品id、数量、加购时间。这里最容易犯的错误是让同一用户同一商品插入多行记录。你可以在用户id和商品id上建一个联合唯一索引,或者在Service层加判断:如果存在记录就执行数量加一,否则插入新记录。
我在实际开发中习惯两个都做。Service层判断是业务逻辑,联合唯一索引是兜底,两者配合,数据脏不了。
3.5 订单主表和明细表:为什么要拆成两张表
这是数据库设计里最值得在论文里写清楚的一点。一个订单可以包含多件商品,如果用一张表存订单,每行都得重复存收货人、联系电话、订单总额、订单状态这些信息,冗余严重。所以必须拆成订单主表和订单明细表。
订单主表存的是一次交易的整体信息:订单id、订单编号、用户id、收货地址id(或者直接冗余收货人信息)、订单总金额、订单状态、下单时间、支付时间、发货时间、完成时间。订单明细表存的是这个订单里的每一件商品:明细id、订单id、商品id、商品标题、商品图片、商品单价、购买数量、小计金额。注意,明细表里要存商品标题和商品图片,这就是“快照”思想。因为商品以后可能改名、改价、甚至下架,但订单作为历史数据,必须保持提交那一刻的样子。
订单状态字段建议用int类型:0待付款、1待发货、2待收货、3已完成、4已取消。这个状态机要放在论文的流程图里,是整个订单模块的核心。
3.6 鉴定记录表:连接交易和平台信任
鉴定记录表建议字段:主键id、用户id、商品id、订单id、用户提交的图片url、鉴定状态(0待审核、1通过、2未通过)、管理员备注、提交时间、审核时间。这里商品id和订单id可以允许为空,因为用户可能针对任意一双鞋发起鉴定,不一定非得是已购买的商品。但最常规的业务依然是下单后购买鉴定服务,所以两者关联起来最自然。
3.7 索引和外键的取舍
索引方面,用户表手机号建议建唯一索引,订单表的用户id建普通索引,商品表的标题字段如果你想支持搜索,可以建普通索引。实际上两个小项目用不到特别复杂的索引策略,但有索引和没索引,写论文的时候你都能多写一小节。
外键方面,我建议表之间不要物理外键,而是用逻辑外键,也就是在Java代码里维护关联关系。原因很简单:物理外键会在删除数据时带来一堆约束问题,调试起来很痛苦,而毕设系统数据量小,删除脏数据时反而很麻烦。答辩时如果老师问为什么不用外键,你可以回答“考虑到系统的灵活性和大数据量下的性能开销,采用逻辑外键由应用层维护数据一致性”,这个答案非常标准。
4. SSM项目初始化踩坑:pom、web.xml、三个配置文件的整合顺序
SSM整合的坑,十个人有九个踩过,而且踩的坑高度一致。我记得自己当年配环境的时候,光是404就折腾了一天,后来才发现是静态资源被DispatcherServlet拦截了。这里我把一套稳定的整合步骤和容易卡住的地方全部列出来,你可以直接照抄。
4.1 Maven工程结构
建议用一个标准的Maven webapp工程,项目名就叫shoes-mall。包结构按分层来:com.example.shoes.controller、com.example.shoes.service、com.example.shoes.mapper、com.example.shoes.entity、com.example.shoes.common(放常量、统一返回结果类、拦截器、工具类)。资源目录下放spring配置文件、mybatis核心配置和mapper xml文件。
pom.xml里的核心依赖大概有这些:spring-context、spring-webmvc、mybatis、mybatis-spring、mysql-connector-java、druid(或者hikari)、jackson-databind、pagehelper、jstl、javax.servlet-api和javax.servlet.jsp-api(scope为provided)、commons-fileupload。版本不要随便找最新的,建议用经过验证的稳定版本组合,比如Spring 5.3.x、MyBatis 3.5.x、MyBatis-Spring 2.0.x。这一套组合资料最多,出问题也好搜。
4.2 web.xml:入口配置的三个必选项
web.xml是SSM整合的入口,里面有三个东西必须配好。
第一个是ContextLoaderListener,它负责启动Spring的IOC容器,加载spring.xml。第二个是DispatcherServlet,它负责启动SpringMVC容器,加载springMVC.xml。这里有个非常容易犯的错:<url-pattern>写成了*.do,那你的所有请求路径都得带.do后缀,很丑,而且不符合REST风格。建议直接写/,这样所有请求都会进SpringMVC。
第三个是CharacterEncodingFilter,编码过滤器。这东西忘记配的话,你前台传中文参数到后台,轻则乱码,重则数据库写入直接变问号。配置成UTF-8,并且把forceEncoding设为true,保证请求和响应都统一编码。
4.3 spring.xml 和 springMVC.xml:职责绝对不能混
这两个配置文件的分工是很多初学者栽跟头的地方。spring.xml里配置的是数据源、事务管理器、SqlSessionFactory、Mapper扫描、Service层和Repository层的Bean。springMVC.xml里配置的是Controller扫描、注解驱动、视图解析器、静态资源处理。一句话总结:业务相关放spring.xml,Web相关放springMVC.xml。
这里有个经典大坑:有人在springMVC.xml里顺手把Service也扫描了,结果项目启动时出现两个同名Bean,或者事务失效。你只要记住一个原则,springMVC.xml的<context:component-scan>只扫描controller包,spring.xml的component-scan只扫描service和mapper包,就不会出问题。
4.4 MyBatis配置的细节
MyBatis这块,我建议用“Mapper接口+XML文件”的方式。在spring.xml里配置MapperScannerConfigurer,指定basePackage为com.example.shoes.mapper,这样MyBatis会自动为每个Mapper接口生成实现类,你只需要在Service里@Autowired就能注入。
在application的MyBatis配置里,有几个开关强烈建议打开。第一个是map-underscore-to-camel-case设为true,这样数据库的create_time字段会自动映射到JavaBean的createTime,省去一堆resultMap。第二个是log-impl设为StdOutImpl,开发时能在控制台直接看到SQL语句,排查问题效率翻倍。第三个是mapper-locations指向classpath:mapper/*.xml,这样XML和接口才能配对成功。
4.5 静态资源的放行
当你把DispatcherServlet的url-pattern配置成/之后,静态资源会被拦截。如果不处理,你的页面样式全部加载不出来,图片也全是裂图。在springMVC.xml里加这么两行就行:
xml复制<mvc:resources mapping="/static/**" location="/static/"/>
然后把你的CSS、JS、图片放在webapp目录下的static文件夹里,页面里引路径时以/static/开头。
4.6 启动期症状速查表
| 症状 | 可能原因 | 首选排查动作 |
|---|---|---|
| 启动直接报BeanCreationException | Mapper接口扫描失败或XML文件不合法 | 检查MapperScannerConfigurer的basePackage,检查XML命名空间 |
| 404且Tomcat日志无警告 | 静态资源被拦截,或访问路径没匹配Controller | 先看控制台有没有请求日志,再看springMVC.xml的静态资源声明 |
| 中文参数乱码 | CharacterEncodingFilter没配或配置错误 | 检查web.xml,确认forceEncoding为true |
| 查询结果字段全是null | 驼峰映射没开启 | 在mybatis配置里加map-underscore-to-camel-case |
| SQL能查但事务不生效 | Service没加@Transactional,或事务管理器没配 | 确认spring.xml里有DataSourceTransactionManager并开启注解驱动 |
5. 核心功能实现的套路:登录鉴权、商品搜索、购物车与订单流转
框架整合完毕,接下来就是业务代码。这一章我按一个用户从注册到完成交易的顺序来讲,代码逻辑能直接复用的就照抄,每个环节我都会说清楚为什么这样做。
5.1 注册登录与拦截器链
注册功能的核心在于密码处理和参数校验。密码不要明文存,建议用MD5加盐处理,盐值可以存一个固定的常量字符串,也可以每个用户随机生成。毕设用固定盐就够了,但为了显得更专业,我建议注册时生成一个UUID作为盐,保存到用户表里。登录时,把用户输入的密码拼接上这个盐再做一次MD5,和数据库里的密文对比。
登录成功之后,把用户对象塞进Session,这样后续所有请求都能知道当前登录的是谁。Session的key可以定义一个常量叫LOGIN_USER,方便在不同拦截器里复用。
登录状态校验用一个拦截器实现,实现HandlerInterceptor接口,重写preHandle方法:
java复制@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("LOGIN_USER");
if (loginUser == null) {
response.sendRedirect(request.getContextPath() + "/login");
return false;
}
return true;
}
然后在springMVC.xml里注册这个拦截器,并且配置拦截和放行路径。我的建议是:/user/**、/cart/**、/order/**、/admin/**都拦截,/login、/register、/index、/product/**以及静态资源放行。管理员路径单独加一个角色校验拦截器,判断Session里的用户角色不是1就跳转403页面。
5.2 商品发布与图片上传
商品发布是卖家的核心动作。表单里有标题、分类、价格、库存、描述,还有一张封面图。文件上传需要配置CommonsMultipartResolver,在springMVC.xml里声明这个Bean,并设置maxUploadSize。
上传接口里,把MultipartFile的字节写入指定目录,文件名建议用UUID + 原始文件名后缀重新生成,避免中文文件名和同名覆盖。存储路径上,开发环境建议存到项目根目录下的upload文件夹,数据库里存相对路径,比如/upload/xx.jpg。页面渲染时用request.getContextPath()拼接出完整地址。这里有个容易踩的坑:如果你把图片存到了target目录下,重启Tomcat后图片会被清掉,所以上传目录最好独立在项目文件夹之外,或者通过Tomcat配置虚拟映射。我通常会在服务器上建一个/data/upload目录,然后加一个配置映射,本地开发就直接用项目里创建的upload文件夹。
5.3 商品搜索与分页
商品列表页需要支持关键字搜索和分页。搜索用MyBatis动态SQL,在Mapper XML里写:
xml复制<select id="searchShoes" resultType="com.example.shoes.entity.Shoes">
select * from t_shoes
<where>
<if test="keyword != null and keyword != ''">
and title like concat('%', #{keyword}, '%')
</if>
<if test="categoryId != null">
and category_id = #{categoryId}
</if>
and status = 1
</where>
order by create_time desc
</select>
这里用concat('%', #{keyword}, '%')而不是直接like '%${keyword}%',是为了防止SQL注入。加在where标签里的status = 1是过滤掉下架商品,这个细节很多人会漏。
分页建议用PageHelper插件,用法极其简单:
java复制PageHelper.startPage(pageNum, pageSize);
List<Shoes> pageList = shoesMapper.searchShoes(keyword, categoryId);
PageInfo<Shoes> pageInfo = new PageInfo<>(pageList);
PageInfo里自动带了总记录数、总页数、当前页数据等属性,前端分页条直接靠它渲染。注意PageHelper的原理是拦截下一条SQL语句拼接limit,所以startPage后面必须紧跟Mapper查询,中间不能穿插其他数据库操作。
5.4 购物车到订单:事务里藏着四个操作
购物车加购非常简单,但提交订单是整个项目事务最集中的地方。当用户点击“提交订单”时,后台Service方法需要同时完成四件事:插入订单主表、插入订单明细表、扣减库存、清空购物车。这四步任何一步失败,前面成功的操作都要回滚,否则会出现订单有了但库存没扣的脏数据。
所以Service方法上必须加@Transactional注解。代码结构大概是这样:
java复制@Transactional(rollbackFor = Exception.class)
public Long createOrder(OrderCreateDTO dto) {
// 1. 插入订单主表,拿到订单id
// 2. 遍历购物车商品,插入订单明细表
// 3. 扣减库存
// 4. 清空购物车
}
rollbackFor = Exception.class一定要写上,因为Spring默认只在RuntimeException时回滚,而你在代码里抛出的多半是自定义的业务异常,不加这个参数可能不触发回滚。
扣减库存这一步,建议用带条件的update,这是一道经典的高频面试题,也是防御超卖最简单有效的方案:
sql复制update t_shoes set stock = stock - #{num}
where id = #{shoesId} and stock >= #{num}
这样即使两个用户同时下单,数据库也会保证只有一个人扣减成功。如果这个update返回的影响行数为0,说明库存不足,业务层直接抛出“库存不足”的异常就好。
模拟支付可以做一个独立的页面,用户下单后跳转到模拟收银台,点“确认支付”就把订单状态从0改成1,同时记录支付时间。这套流程虽然简单,但足够写进论文,而且演示时很有画面感。
5.5 订单状态机与后台发货
前台用户能触发的状态变化是:取消订单(待付款和待发货时)、确认收货(待收货时)。后台管理员能触发的状态变化是:发货(待发货时改成待收货)。取消订单时要注意恢复库存,因为之前创建订单已经扣过库存了。这个恢复动作同样要放在事务里,并且要在状态变更和库存恢復两条数据上都操作成功。
建议在订单Service里把所有状态变更操作收敛成独立方法,比如cancelOrder(Long orderId)、payOrder(Long orderId)、confirmReceive(Long orderId)、deliver(Long orderId)。每个方法内部先校验当前状态是否符合流转条件,再更新状态,最后做附加操作。答辩时你提到“状态变更统一走状态机校验”,老师会觉得你确实理解了业务而不仅仅是在堆代码。
5.6 后台管理员模块的权限控制
管理员的商品审核其实就是修改商品状态:0代表待审核,1代表上架,2代表审核不通过。用户发布新商品时status默认0,管理员在后台看到待审核列表,可以上下架、拒绝。
这里比较容易被忽视的是权限控制不能只靠前端菜单隐藏,必须后端拦截器也判断角色。因为用户完全可以自己拼接URL去访问后台接口,如果拦截器没判断,那后台就形同虚设。我的做法是写一个AdminInterceptor,先判断是否登录,再判断Session里的用户角色是否为1(管理员),不满足的直接跳到403页面。
6. 把代码变成论文:框架、图表和查重三个关口
代码写完只完成了一半,你的毕业设计还有一半是论文。如果你前期代码写得规范,论文后半部分其实就是一个“翻译”过程。但每年都有代码写挺好、论文被老师打回的情况,问题几乎都出在结构混乱、图表缺失、大段抄模板上。
6.1 论文框架这么搭最稳
一篇标准的本科毕设论文建议按这个顺序走:
| 章节 | 内容要点 |
|---|---|
| 摘要 | 一句话说背景,一段话写系统功能,一段话写技术路线 |
| 绪论 | 选题背景、意义、国内外研究现状、本文主要工作 |
| 相关技术介绍 | SSM框架、MySQL、前端技术、Maven |
| 需求分析 | 角色分析、功能需求、非功能需求、用例图 |
| 系统设计 | 总体架构图、功能模块图、业务流程、E-R图、数据库表设计 |
| 系统实现 | 每个核心模块配截图、关键代码、功能描述 |
| 系统测试 | 测试环境、功能测试用例表、测试结论 |
| 总结与展望 | 总结已完成工作,提出不足之处和改进方向 |
第一章选题背景和意义,你完全可以用第1节里聊的内容来扩充。球鞋市场的规模、球鞋爱好者的交易需求、互联网交易平台在信息展示与真伪鉴定上的重要性,这些都是公开信息,整理成逻辑顺畅的几个段落即可。
6.2 三类关键图提前画好
论文里最核心的三类图是:架构图、用例图、流程图。
架构图画成四层结构,最上面是View层(JSP页面),往下是Controller层,再往下是Service层,最底层是Mapper和MySQL。每层之间用箭头标出调用方向。这个图画起来很快,但信息量很足,能直观体现你理解了分层架构。
用例图用UML画,画三个角色各有哪些操作。普通用户有注册、登录、浏览商品、加购物车、下单、支付、收货、评价;卖家除了用户的操作还有发布商品、管理商品;管理员有用户管理、商品审核、订单管理、鉴定审核。用例图画好之后,需求分析章节几乎是自动生成的。
流程图重点画两个:一个是从用户提交订单到支付完成的时序流程,一个是管理员审核商品的状态流转流程。状态机的图建议用表格或者简单的流转箭头表示,清晰即可。
工具方面,ProcessOn和draw.io都免费,Visio在学校电脑上也常见。画图最重要的是一致性,所有图的字体、箭头、矩形样式保持统一,不要一会儿圆角一会儿直角。
6.3 系统实现章节的关键代码怎么放
这个章节最忌讳“贴完整代码”。老师想看的不是你把源码搬上去,而是你能挑重点说明。我的经验是每个模块放一到两个代码片段,加上三四行说明。比如需求分析里讲了订单模块有四个核心操作,那实现章节就可以贴createOrder方法,并在注释里标清楚第一步到第四步分别做了什么,然后配一张下单成功页面的截图。代码本身不超过30行,读者就能看懂你的实现思路。
图片方面,每张功能都需要一张界面截图,截图记得用浏览器打开系统实际页面去截,不要用开发工具里的预览,也不要截一半。关键按钮最好用红框圈出来,方便老师定位。
6.4 查重降重的心得
说实话,知网和维普的查重机制对这类项目论文特别不友好,因为“相关技术介绍”和“需求分析”这种章节,几乎所有人写的都是很像的内容。降低重复率的几个办法:把所有技术介绍尽量用表格呈现,比如“Spring与SpringMVC的职责对比”这种形式,可以显著降低连续字符重复;代码块的重复也会算重,所以每个代码片段都要换掉默认变量名,加上自己的注释,而不是从网上原样拷贝;多结合球鞋交易平台的具体业务来描述,例如把“用户管理模块用于管理用户信息”写成“管理员登录后台后,可查看全平台注册用户列表,对违规账号进行禁用操作”,这样既具体又不容易和模板句子撞车。整体重复率控制在15%左右,基本所有学校都能过。
7. 答辩前的高频追问与演示准备
代码写完、论文交上去,最后一道关是答辩。答辩时间通常只有五到十分钟,老师未必有时间运行你的系统,所以演示和回答问题的质量,往往直接决定成绩。很多人代码做得辛苦,却因为不会演示被老师质疑,很亏。
7.1 五分钟演示脚本怎么排
我建议按时间切成五段,每段做一件事。第一分钟,一句话说清项目背景:这是一个基于SSM的球鞋交易平台,面向球鞋爱好者提供在线交易和鉴定服务,我负责全部前后端代码和数据库设计,使用Spring、SpringMVC、MyBatis三大框架实现。第二分钟,演示注册登录,重点展示权限差异,先登录管理员后台,再退出登录普通用户前台。第三分钟,演示商品浏览和搜索,顺便展示分页效果。第四分钟,演示发布商品和购物车下单,最好走完整个订单流程,包括模拟支付。最后一分钟,展示后台商品审核和订单发货,能够把订单状态从待付款推进到待发货即可。
整个演示过程不要追求把每个功能都点一遍,而要展示最核心的交易闭环和权限控制。老师最怕看到一个学生登录后什么都不敢点,干站在那里解释。
7.2 必问的几个技术问题
我整理了答辩时最容易出现的几个问题,建议提前过一遍。
为什么用SSM而不是Spring Boot? 回答思路:SSM是我校Java课程体系里要求的框架组合,同时通过SSM我可以更清晰地理解Spring核心思想和SpringMVC的请求流程;Spring Boot本质上是简化配置的框架,掌握了SSM以后再去用Spring Boot会更容易理解底层原理。这个答案既大方又坦诚。
事务放在哪一层?怎么配置? 回答:事务放在Service层,通过Spring的@Transactional注解声明式管理,在spring.xml中配置了DataSourceTransactionManager和<tx:annotation-driven>。
订单为什么拆成两张表? 回答:因为一个订单可以包含多件商品,每件商品的名称、图片、单价、数量都不同。用明细表存储商品快照,既避免了主表大量冗余字段,也保证了历史订单数据的完整性。
库存超卖怎么解决? 回答:采用带条件更新的乐观锁方案,update t_shoes set stock = stock - #{num} where id = #{shoesId} and stock >= #{num},通过数据库的行锁机制保证并发情况下库存不会为负。
拦截器和过滤器的区别? 回答:过滤器是Servlet规范的一部分,在SpringMVC的DispatcherServlet之前执行;拦截器是SpringMVC框架内部的机制,在Handler执行前后执行,可以访问Controller上下文。项目里用拦截器做登录和权限校验,比过滤器更贴合SpringMVC的编程模型。
如果你能在答辩时把这些话说得清楚流畅,老师基本不会再追问更偏的问题。如果被问到没准备的问题,也不要慌,坦诚表示“这个点我还没深入考虑,后续会继续研究”,远比硬编一个答案强。
7.3 不同时间底线的推进建议
2026届毕业的时间线,如果你现在刚开始,正常节奏是:调研选题一周,搭建框架和数据库一周,核心前台业务两周,后台功能一周,测试和修复一周,论文撰写三到四周。整套下来大概八到十周,时间很充裕。
如果时间只剩一个月,建议砍掉所有非核心功能,只保留“商品、购物车、订单、用户、后台审核”这几个模块,把代码写完的时间压缩到三周,最后一周狂写论文和做演示。如果只剩两周,那就别管论文的“系统测试”章节了,把交易闭环跑通,截图补齐,直接进入“完成度很高”的状态去答辩。
最后说点实际操作的体会
陆陆续续带过好几个做球鞋平台的学生,我发现真正让项目卡住的从来不是业务代码,而是那些看起来不起眼的配置问题。Tomcat启动不了、Maven依赖下载失败、JDK版本不匹配、数据库连接串写错,每一件都能消耗你大半天。所以我的建议是,拿到题目后第一个下午别急着写代码,先花两个小时把环境彻底跑通:Maven能编译、Tomcat能启动、数据库能连上、页面能显示hello world。这四个条件满足了,后面就是填砖头。
另外一个额外建议是,从开发第一天起就把每个模块的页面截图存好,命名清晰一些。到了写论文和做PPT的时候,你会发现这些截图就是你的素材库,能省出整整两天时间。答辩现场如果能准备一个两分钟的项目运行视频录屏,遇到临时环境问题还能兜底。
这个选题能不能拿到好成绩,说到底就看你想不想把“球鞋”这两个字真正用起来。把它当普通商城做,能毕业;把它当球鞋爱好者的交易社区做,你的需求分析、交互设计、论文描述都会明显高一个台阶。
