ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

JSP校园旧物交易平台毕业设计实战:从数据库到部署答辩全解析

JSP校园旧物交易平台毕业设计实战:从数据库到部署答辩全解析 1. 毕业设计选题为什么是多鱼旧物交易平台1.1 选题背景与真实需求每年到了毕设季总有学弟学妹来问我同一个问题——有没有那种既不太难、又能拿得出手、老师还不会刁难的项目我的答案里旧物交易平台常年排在前三。原因很简单这类系统的业务链路足够完整用户注册登录、商品发布、浏览搜索、下单交易、留言互动、个人中心管理恰好覆盖了Web开发课程里几乎所有核心知识点。同时闲置物品循环利用本身就是一个贴近真实生活、有社会价值的话题答辩的时候比图书管理系统这种老掉牙的题目有话说多了。多鱼这个名字取自多余的谐音——把多余的东西放到平台上让它变成别人需要的宝贝。整个项目的定位是校园场景内的C2C旧物交易平台卖家拍照上传旧物信息买家浏览搜索、线上下单双方通过站内消息或预留联系方式沟通完成交易。这套东西做完不只是应付毕业简历上写独立设计并实现了一个包含完整交易闭环的Web系统面试官看了也能聊上几句。1.2 技术栈选型复盘JSP为什么仍然是个好选择很多同学一听说用JSP做毕设第一反应是这玩意儿不是过时了吗我理解这种焦虑但作为毕业设计选型逻辑和工业项目完全不同。JSP Servlet MySQL这套组合最大的优势是技术透明。你用Spring Boot框架帮你把请求分发、参数封装、事务管理全干了数据库操作有MyBatis自动映射写起来很爽但你未必说得清一个HTTP请求从浏览器到数据库再返回的完整路径。答辩老师问一句JSP页面是怎么被编译执行的用框架的同学经常卡壳而用JSP的同学反而能流利地讲出JSP翻译成Servlet → 编译成Class → 实例化处理请求 → 输出HTML响应这条链路。再说客观条件很多学校的Java Web课程教的就是JSP/Servlet毕业设计和课程知识无缝衔接不用额外花大量时间学框架。而且JSP项目部署简单一个Tomcat就搞定一切不像Spring Boot项目还要处理各种依赖冲突。我见过太多用SSH、SSM框架的同学最后两天被Maven依赖问题折磨到崩溃反观JSP项目几乎不会出现这种问题。当然选择JSP也要心里有数它的表现层逻辑偏重前后端不分离所以我会在后面的功能设计里尽可能用JSTL和EL表达式去规范页面代码避免在JSP里写大量Java脚本保持代码整洁。这套思路放在2024年的毕设里依然是很讨喜的做法。1.3 系统角色与核心业务流拆解在设计数据库之前先把人、事、物的关系理清楚。多鱼平台一共三类角色游客可以浏览商品列表、查看商品详情但下单、发布、留言都需要登录。游客路径的转换是注册 → 登录 → 成为正式用户注册页面要做用户名唯一性校验、密码二次确认、邮箱格式校验这些都是答辩的加分点。普通用户买家/卖家身份合一这是C2C平台和B2C平台最大的区别——每个人既能买也能卖。用户登录后可以发布旧物、修改自己发布的商品信息、上下架商品、下单购买别人的商品、处理自己商品的订单。所以业务上必须有我的发布和我的订单两个维度的数据展示。管理员负责用户管理禁用/启用账号、商品审核下架违规商品、分类管理、数据统计总用户数、总商品数、总订单数。管理端单独一套页面和前台用户端隔离。核心业务流我梳理成三条主线主线一卖家登录 → 发布商品填信息传图片 → 管理在售商品 → 收到订单 → 确认交易 → 商品标记已售 主线二买家登录 → 浏览/搜索商品 → 查看详情 → 下单生成订单 → 确认收货/取消订单 主线三管理员登录后台 → 审核商品 → 管理用户 → 查看统计报表这三条链路对应到代码层面就是后面要讲的UserServlet、GoodsServlet、OrderServlet三大核心处理模块。一张图理清所有跳转关系写代码的时候就不容易迷路。2. 数据库设计与项目骨架先跑起来再谈优化2.1 四张核心表和一张扩展表的字段设计旧物交易平台只要不是做得特别复杂五张表就够用户表、商品表、订单表、留言表、收藏表。我用一个具体的建表DDL给大家看这些字段都是经过实际调试验证的直接抄作业没问题。-- 用户表 CREATE TABLE t_user ( uid INT PRIMARY KEY AUTO_INCREMENT COMMENT 用户ID, username VARCHAR(30) UNIQUE NOT NULL COMMENT 用户名登录用唯一, password VARCHAR(64) NOT NULL COMMENT 密码建议MD5加密存储, nickname VARCHAR(30) DEFAULT COMMENT 昵称展示用, email VARCHAR(50) DEFAULT COMMENT 邮箱, phone VARCHAR(20) DEFAULT COMMENT 联系电话, avatar VARCHAR(200) DEFAULT default.jpg COMMENT 头像路径, status TINYINT DEFAULT 1 COMMENT 1正常 0禁用, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 商品表 CREATE TABLE t_goods ( gid INT PRIMARY KEY AUTO_INCREMENT COMMENT 商品ID, uid INT NOT NULL COMMENT 发布者ID关联t_user, title VARCHAR(100) NOT NULL COMMENT 商品标题, description TEXT COMMENT 商品描述, price DECIMAL(10,2) NOT NULL COMMENT 价格精度很重要, original_price DECIMAL(10,2) DEFAULT 0 COMMENT 原价/入手价体现新旧差价, category VARCHAR(30) DEFAULT 其他 COMMENT 分类数码/图书/生活/服饰等, image VARCHAR(200) DEFAULT COMMENT 商品主图路径, status TINYINT DEFAULT 1 COMMENT 1在售 2已下单未成交 3已售出 0下架, view_count INT DEFAULT 0 COMMENT 浏览量, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;订单表和留言表我就不全文贴了重点说几个容易踩坑的字段订单表必须包含order_no订单编号、goods_id关联商品、buyer_id买家、seller_id卖家、price成交价、status1待确认 2已完成 3已取消。注意goods_id和buyer_id、seller_id都要建索引因为订单查询基本都走这三个字段。留言表比较容易被忽略但它才是平台社区感的来源。字段设计上除了goods_id、user_id、content、create_time建议加一个reply_to字段记录回复的是哪条留言这样详情页才能做出一级回复的层次感而不是所有留言平铺。收藏表就是用户与商品的关联uidgidcreate_time联合唯一索引实现我收藏的商品功能。这张表虽然简单但它是个人中心我的关注页面的数据基础做了它系统功能完整度会明显上一个档次。字符集这里必须强调建库建表一定要用utf8mb4不要用utf8。否则商品描述里用户填了一个emoji表情数据库直接报错。我当年就因为这个bug排查了整整一个下午。2.2 三层架构与项目目录组织一个标准的JSP项目目录结构遵循MVC思想就够了不搞花活。我的组织结构是这样的src/main/java ├── com.duoyu.dao -- JDBC操作封装每个表对应一个DAO类 ├── com.duoyu.entity -- 实体类User、Goods、Order、Comment、Favorite ├── com.duoyu.servlet -- Servlet控制器UserServlet、GoodsServlet、OrderServlet ├── com.duoyu.util -- 工具类DBUtil连接池、MD5Util、UploadUtil webapp ├── index.jsp -- 首页商品列表热门分类 ├── login.jsp / register.jsp ├── goods │ ├── detail.jsp -- 商品详情 │ ├── publish.jsp -- 发布商品 │ └── edit.jsp -- 编辑商品 ├── user │ ├── center.jsp -- 个人中心 │ ├── my_publish.jsp -- 我发布的 │ └── my_orders.jsp -- 我的订单 └── admin ├── admin_login.jsp ├── user_manage.jsp └── goods_manage.jspDAO层不要每个方法都写一遍DriverManager.getConnection太蠢了。我用了一个简单的DBUtil封装基于Apache DBCP连接池项目启动的时候初始化数据源后续DAO拿连接就是一个dataSource.getConnection()的事。连接池配置写在dbcp.properties里初始连接数5、最大连接数20这个量级跑毕设Demo绰绰有余。2.3 环境准备从JDK到Tomcat的一站式说明环境这块我见过太多同学卡住环节明明很简单但就是启动报错。标准配置如下JDK 8注意不要用JDK 17高版本Tomcat兼容性没问题但有些老项目的Tomcat 8配JDK 17会有版本校验问题Tomcat 8.5 或 9.0Tomcat 10把javax.servlet改成了jakarta.servlet很多旧教程代码会编译报错新手千万别装Tomcat 10MySQL 5.78.0也可以用但驱动要换com.mysql.cj.jdbc.Driver连接串里加serverTimezoneAsia/ShanghaiIDE建议直接用Eclipse for Java EE版本内置了Tomcat插件Debug模式改完代码自动热部署数据库初始化脚本建议用Navicat执行执行前先DROP DATABASE IF EXISTS duoyu;再CREATE DATABASE duoyu DEFAULT CHARACTER SET utf8mb4;防止历史残留数据干扰。3. 核心功能实现把主干业务打通3.1 注册登录与Session管理注册逻辑要注意的点用户名唯一性校验要放到后端不能只靠前端提示。前端校验只是体验优化恶意用户绕过页面直接Post请求就会插入重复用户名。我的做法是注册Servlet里先SELECT * FROM t_user WHERE username?查一遍存在就直接返回该用户名已被注册。密码存储一定要做MD5加盐处理。很多人直接MD5(password)这在2024年跟明文差不多查表彩虹表一秒钟就反解出来。我用的方案是加固定盐public static String md5WithSalt(String password) { String salt duoyu2024; return DigestUtils.md5Hex(salt password salt); }盐不是神秘的密码学操作就是让相同的密码产生不同的哈希值增加攻击者穷举的成本。值得一提的是我在实际开发中还设置了登录连续失败的锁定机制——同一个用户名一个小时内在Redis里记录失败次数超过5次强制要求验证码。这块改动不大但在系统安全性的描述里写出来特别加分。登录成功后把用户对象放进Sessionrequest.getSession().setAttribute(loginUser, user);注意key不要用user这种笼统的命名尤其是多个Servlet模块共用Session的时候统一的key命名能避免很多为什么页面拿不到数据的迷惑bug。后续JSP页面里用${loginUser.username}就能直接取到登录用户名。退出登录就是session.invalidate()一了百了。3.2 商品发布与图片上传看似简单实则坑多商品发布页是多鱼平台里表单最复杂的页面——标题、描述、价格、原价、分类、图片每个字段都有讲究。首先是图片上传。JSP自带的解决方案是commons-fileupload和commons-io两个jar包核心代码如下// 前端表单一定要加 enctypemultipart/form-data DiskFileItemFactory factory new DiskFileItemFactory(); ServletFileUpload upload new ServletFileUpload(factory); ListFileItem items upload.parseRequest(request); for (FileItem item : items) { if (!item.isFormField()) { // 真实的文件名做处理防止路径穿越和重名 String fileName System.currentTimeMillis() _ new File(item.getName()).getName(); File uploadDir new File(getServletContext().getRealPath(/uploads)); if (!uploadDir.exists()) uploadDir.mkdirs(); item.write(new File(uploadDir, fileName)); // 数据库只存相对路径方便后续部署迁移 goods.setImage(uploads/ fileName); } }这里有两个关键经验第一文件名处理千万别直接用用户传的原名。一是中文文件名会导致URL编码问题二是两个用户上传了同名文件互相覆盖。我习惯用时间戳_原名的方式重命名一个用户在同一秒内上传两次的极端情况用毫秒时间戳基本不会碰到。第二数据库里不要存绝对路径比如D:/apache-tomcat/webapps/duoyu/uploads/xxx.jpg。因为一旦换电脑部署绝对路径就全废了。只存uploads/xxx.jpg这种相对路径页面上用${pageContext.request.contextPath}/uploads/xxx.jpg拼接完整访问URL代码移植性特别好。说句题外话很多毕业设计做文件上传只做到存一个路径但没有考虑用户根本没传图片的情况。我的做法是如果在商品发布时没选图片就用一个default_goods.jpg占位图兜底让页面永远有图可展示。就这一个细节我当时在系里的毕业设计预答辩现场被老师表扬过说平台观感很完整。3.3 首页信息流与商品搜索首页就是一个商品列表页展示所有status1在售的商品按创建时间倒序排列。如果数据库里的商品不多直接把全部查询出来一次渲染到页面上就行。搜索功能我做了两个维度关键词模糊查询 分类筛选。SELECT * FROM t_goods WHERE status 1 AND (title LIKE CONCAT(%, ?, %) OR description LIKE CONCAT(%, ?, %)) AND (category ? OR ? 全部) ORDER BY create_time DESC LIMIT 0, 12;这里用?占位符配合PreparedStatement目的很明确——防止SQL注入。很多同学觉得就一个搜索框而已哪有人会攻击毕业设计这个观念很危险。每次涉及用户输入拼SQL的地方都应该用PreparedStatement这是写代码的基本素养答辩时老师也爱问这个点。首页排版我参考了当时闲鱼的做法顶部是搜索框和大分类导航数码、图书、生活、服饰等下面是商品卡片瀑布流。每张卡片展示商品主图、标题、价格、浏览量点击进入商品详情。瀑布流我用的是CSS的column-count: 3实现比手写JavaScript判断位置简单得多而且JSP服务端渲染天然适合这种数据画好再输出的模式。3.4 订单流程从下单到确认收货的状态机订单是整个系统里逻辑最绕的部分因为涉及两个用户买家、卖家和一个商品的三方状态同步。我先定义状态机商品状态1在售 → 2已下单待确认 → 3已售出或恢复1 订单状态1待确认 → 2已确认/已完成 → 3已取消买家下单时不能只插入一条订单记录还必须去更新对应商品的status从1变2。如果不做这一步就会出现两个买家同时下单同一件商品的严重bug——这其实是一个并发问题。JSP传统项目里最简单的上锁方案是用数据库的悲观锁// 更新商品状态前先查询并锁定该行防止并发下单 SELECT * FROM t_goods WHERE gid ? FOR UPDATE; // 确认status1后才能继续 UPDATE t_goods SET status 2 WHERE gid ? AND status 1;这个AND status 1是关键的乐观锁保护。如果Update影响行数为0说明这个商品在查询和更新之间已经被别人下单了直接提示买家手慢了商品已售出。卖家可以操作的是确认订单把订单状态从1改为2商品状态从2改为3。买家可以操作的是取消订单订单状态改为3商品状态恢复为1。这两个操作分别对应卖家中心和买家订单页面里的按钮。我在实际程序里把订单号做成了yyyyMMddHHmmss 用户ID随机数格式的字符串。订单号一定不要用自增ID直接展示太容易暴露系统数据量了。虽然这不会造成安全隐患但会让人感觉不正规。3.5 个人中心三个列表页面打通数据闭环个人中心是功能模块最多的页面分三个Tab我发布的商品SELECT * FROM t_goods WHERE uid ?展示每个商品的当前状态在售的可以编辑、下架、删除已售出的只能删除。我的收藏关联收藏表和商品表做联表查询展示收藏的宝贝和收藏时间。我的订单这里还要再细分两个Tab——我买到的buyer_id 当前用户ID和我卖出的seller_id 当前用户ID。我买到的和我卖出的查询条件不一样但表结构相同。为了减少代码重复我在OrderServlet里做了分支处理if (buy.equals(request.getParameter(type))) { orderDao.findByBuyerId(user.getUid()); } else if (sell.equals(request.getParameter(type))) { orderDao.findBySellerId(user.getUid()); }页面模板共用一个my_orders.jsp传过去的List实体一样渲染逻辑完全通用这就体现了MVC分层的好处——视图只关心数据长什么样不关心数据怎么来的。4. JSP页面的四个高阶细节让前端体验不拉胯JSP被吐槽最多的就是页面丑、交互笨。但其实JSP配合成熟的CSS框架和少量JavaScript完全可以做出漂亮的前端。我在多鱼项目里沉淀了四个特别实用的小技巧都是热搜里高频出现的问题分享给大家。4.1 个人信息展示页面的数据渲染个人中心的信息展示区域最忌讳的是在JSP里写大段% ... %脚本。那简直是维护噩梦。正确做法是EL表达式 JSTL标签库% taglib prefixc urihttp://java.sun.com/jsp/jstl/core % div classuser-info img src${empty loginUser.avatar ? images/default.png : loginUser.avatar} / p昵称${loginUser.nickname}/p p用户名${loginUser.username}/p p注册时间fmt:formatDate value${loginUser.createTime} patternyyyy-MM-dd //p /div那个${empty xxx ? a : b}三元表达式的写法是处理字段为空时显示默认值最高效的手段省掉了Java代码里的一堆if判断。页面里永远不要出现out.println()这是JSP规范里的铁律也是答辩老师扫描页面代码时的评分点。4.2 图片上传后的坐标定位从绝对像素到相对比例搜索热词里jsp图片如何对坐标定位我猜提问者是做商品图片加标签功能或者遇到图片缩放后标注位置错乱的问题。JSP本身不提供任何定位能力——它只是服务端渲染HTML。真正管坐标定位的是CSS。正确做法是把图片定位和坐标分开处理图片用img标签加载坐标信息作为CSS百分比数值而不是固定像素。举个例子给商品图打瑕疵位置标签.tag { position: absolute; left: 34.5%; /* 水平位置占图片宽度比例 */ top: 52%; /* 垂直位置占图片高度比例 */ background: rgba(255, 0, 0, 0.8); border-radius: 50%; width: 18px; height: 18px; }为什么用百分比因为图片在不同设备上会被CSS压缩或拉伸用像素定位的话图片缩放后标签全错位了。百分比坐标和图片本身绑定无论怎么等比缩放标签都能准确落在原位置。具体到实现层面坐标数据应该和商品信息一起存入数据库。我在t_goods表额外加了mark_point_x和mark_point_y两个VARCHAR字段格式是字符串34.5,52用逗号分隔。页面渲染时用JSTL拆出来c:set varpoint value${fn:split(goods.markPoint, ,)} / span classtag styleleft:${point[0]}%;top:${point[1]}%;/span用户设置标签坐标的操作我是用一个隐藏的input 点击图片时把鼠标位置换算成百分比$(#goodsImage).click(function(e) { var rect this.getBoundingClientRect(); var x ((e.clientX - rect.left) / rect.width * 100).toFixed(1); var y ((e.clientY - rect.top) / rect.height * 100).toFixed(1); $(#markPoint).val(x , y); });这套方案完全绕开了后端坐标数据的存储和渲染全部就靠一个字符串字段但功能完成度很高做毕设绰绰有余。4.3 页面加载完成后自动刷新一次的正确姿势jsp页面让加载完后刷新一次这个需求常见于统计浏览量的场景。比如用户访问商品详情页页面每次刷新都希望浏览量加1但又不能无限刷新所以只在首次加载后自动刷一次。网上很多人给的方案是meta http-equivrefresh content0但这有两个问题一是零秒刷新在某些浏览器里会失效二是会形成刷新死循环。我推荐用JavaScript的sessionStorage来控制script typetext/javascript if (!sessionStorage.getItem(goods_%goods.getGid()%_refreshed)) { sessionStorage.setItem(goods_%goods.getGid()%_refreshed, true); // 延迟100ms刷新确保当前页面先渲染完全 setTimeout(function() { location.reload(); }, 100); } /script为什么用sessionStorage而不是cookie因为sessionStorage的生命周期是会话级别用户关掉浏览器再打开标签页关闭再打开都会重新计数而cookie会残留很久。商品详情页的浏览量统计逻辑是后端详情Servlet每次请求先UPDATE t_goods SET view_count view_count 1 WHERE gid ?然后前端再通过上述脚本准确地把首次访问转化为自动刷新一次从而让浏览量立即生效不需要用户手动刷新才看到更新。还有个小细节上面的代码里内嵌了Java代码%goods.getGid()%来区分不同商品这种在JSP中混用Scriptlet的方式本身要少用但这个场景如果不做页面拆分的话算是相对合理的例外。更规范的写法是把goodsId放进data属性里用JS读取但这个技巧够用了。4.4 在JSP页面里引入饿了么Element图标饿了么elment图标这个搜索词说明很多人在JSP项目里想用Element UI的图标组件但不知道怎么引。Element UI是Vue生态的组件库按理说和JSP不搭但它的图标库是独立的CSS/字体文件完全可以单独抽出来用。类似地Bootstrap也很好用。具体接入方式分三步到Element UI的CDN地址拿到index.css或者从npm包里把fonts目录复制到项目的webapp/css和webapp/fonts下。在JSP页面的head中引入link relstylesheet href${pageContext.request.contextPath}/css/element-ui-index.css在页面里直接写图标的类名i classel-icon-goods/i !-- 商品图标 -- i classel-icon-user/i !-- 用户图标 -- i classel-icon-shopping-cart-full/i !-- 购物车 --关键坑Element的CSS里font-face的url()是相对路径如果你把CSS放css目录而字体放fonts目录那就废了。必须保持Element原生目录结构css/index.css和fonts/element-icons.woff在同一层级字体引用路径是../fonts/xxx。很多人图标显示成方框就是路径问题。如果你不想为图标引入整套Element CSS有点重几百KB也可以挑几个需要的图标用iconfont或者直接用Font Awesome。JSP作为服务端渲染模板不管引入什么前端资源原则都是一样的——用相对路径配合${pageContext.request.contextPath}不要写死绝对路径这样部署的时候不会因为应用名变化导致资源404。5. 部署、调试与答辩从能跑到能讲5.1 本地部署链路与常见报错应急手册把项目部署起来本质就三步导入数据库脚本、把war包或整个项目目录放进Tomcat的webapps、启动Tomcat。但实际操作中新手会踩几个高频的坑我把对应的解决方案整理成了一张表报错现象原因排查解决方案ClassNotFoundException: com.mysql.jdbc.DriverMySQL驱动jar包没放进WebContent/WEB-INF/lib下载mysql-connector-java-5.1.49.jar放进去Access denied for user rootlocalhost数据库密码不对检查DBUtil.java里的连接串密码不要带特殊字符The server time zone value Öйú is unrecognizedMySQL 8.0时区问题JDBC连接串加serverTimezoneAsia/Shanghai404页面找不到访问路径和Servlet映射不一致或项目未正常发布检查web.xml中的Servlet映射和WebServlet注解Connections could not be acquired连接池初始化失败检查dbcp.properties的driverClass和url是否匹配MySQL版本中文乱码编码不一致统一MySQL连接串characterEncodingutf8JSP页面pageEncodingUTF-8Tomcatserver.xml加URIEncoding这里额外说一个很隐蔽的问题用Eclipse跑JSP项目时如果你的Server Locations选择了Use Tomcat installation项目文件会复制到Tomcat目录如果选Use workspace metadata则在Eclipse内部。两种方式各有优劣但如果你换了一种方式启动之前上传到uploads目录里的图片就会消失——因为文件路径变化了。这引发了一个更实际的建议图片等上传文件最好存到项目部署目录之外的固定磁盘路径应用里通过配置项读取。毕设为了简单不想改太多的话至少你要知道这个坑别到时候换电脑演示图片全裂。5.2 演示数据准备答辩现场救场的秘密武器很多同学项目功能没问题但答辩演示时页面空空如也老师看着一个没有任何数据的首页很难对你的系统产生好印象。我强烈建议在数据库里预置一批真实感强的演示数据20个左右的用户账号用户名进来就要能登录30条以上的商品记录覆盖数码、图书、生活、服饰全部分类价格有高有低商品图片用真实图片不要用纯色占位图去图床上存一批书本、耳机、台灯之类的闲置物品图几条已完成的订单记录、留言记录让个人中心和商品详情页有内容可展示演示数据是能跑和好用的分水岭。老师看到的是一个热闹的社区而不是一张空壳这个印象分比任何代码技巧都值钱。5.3 答辩老师爱问的问题与答题思路最后聊聊答辩。JSP旧物交易平台的答辩老师的问题其实高度集中在几个维度。我梳理了命中率最高的五个问题1为什么选JSP做前端而不是Vue/React答题思路毕设场景下JSP天然支持Java对象在页面中的直接渲染不需要前后端数据联调接口开发效率高。同时JSP由Servlet衍生能直观体现HTTP请求处理链路符合课程设计的知识点覆盖要求。千万别踩Vue比JSP先进这种话——你用半天时间做了复杂度高的SSR框架最终演示效果不一定比JSP好。问题2如果用户量变大这个系统怎么优化答题思路可以从三个层面展开数据库层面加索引、分页查询、读写分离应用层面引入Redis做缓存热点商品和会话共享架构层面做动静分离把图片等静态资源放到独立存储。不需要全部实现回答出优化方向就够。问题3密码MD5加密够安全吗答题思路承认MD5加盐可以解决后端存储的基本安全问题但传输过程中还是明文更稳妥的方案是HTTPS 前端加密传输如RSA公钥加密。现在很多高校毕业设计答辩现场老师就爱在这个基础上深挖。问题4两个买家同时下单同一件商品怎么处理答题思路讲清楚乐观锁和悲观锁两种思路即可。我在前面代码里用的是UPDATE影响行数为0则下单失败的乐观锁方案直接拿那个例子讲逻辑自洽老师挑不出毛病。问题5平台如何避免买卖双方脱离平台进行私下交易答题思路最简单实用的方案是商品详情页展示联系方式的按钮由后端控制只有登录用户下单后才能看到卖家的手机号/微信号。也就是说核心交易信息藏在下单成功这个动作之后买家要先在平台下单才能对接卖家。这套机制虽然无法绝对杜绝私下交易但从产品设计层面极大地提高了平台存在的必要性——这也是我在多鱼里实际执行的方案。答辩的底层逻辑永远是让你的代码和设计自圆其说。哪怕方案不是最优只要你能讲清楚为什么做这个选择、这个选择解决了什么问题、有哪些不足之处老师就会给高分。怕的就是一句我也不知道当时为什么这么写。最后再分享一点我做多鱼毕业设计时的个人体会这个项目最磨人的不是写代码而是调试订单状态和商品状态不同步的边界情况。建议你们在编码前先静下心把状态流转图画完整把自己当成买家走一遍流程再把自己当成卖家走一遍流程把每个阶段数据库应该长什么样搞清楚再动手。项目做完之后你不但会交差还会发现JSP这套传统但透明的技术栈已经帮你把Java Web的底子打得比很多直接上手Spring Boot的同学更扎实。
返回列表