ARTICLE DETAIL

资讯详情

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

基于JSP的JavaWeb购物网站系统设计与毕业答辩实战解析

基于JSP的JavaWeb购物网站系统设计与毕业答辩实战解析 作为一名带过不少毕业生做JavaWeb课题的老兵我几乎每年都会看到有人选“基于JSP购物网站系统的设计与实现”这个题目。它确实是个经典到不能再经典的毕业设计选题为什么因为JSP购物网站恰好覆盖了JavaWeb课程里最重要的几个知识点JSP页面渲染、Servlet处理请求、Session保持登录状态、JDBC操作数据库再加上一个不算复杂的购物车和订单流程难度刚好卡在“能体现工作量”和“不容易翻车”之间。这篇文章我就把整个项目的设计思路、数据库结构、核心代码、环境搭建和常见坑位全部拆开揉碎讲一遍特别针对那些手里已经拿到一份源码但还不知道怎么讲清楚、怎么改明白、怎么保证答辩能过关的同学。先说清楚这篇博文能帮你解决什么。如果你正准备做毕业设计或者已经选了这个题目但脑子里还是一团浆糊那么按着这篇文章的节奏走一遍你就能搞清楚这个系统到底分了哪些模块、每个模块为什么要这么设计、核心功能的代码应该怎么写、以及从零部署一套环境需要做哪些事。如果你是那种“源码在手但全是问题”的状态——导入IDE报错、页面中文乱码、数据库连不上、不知道代码从哪里看起那么第五部分可以当一份速查手册来用。即便你只是想在原有代码基础上加点功能让工作量更饱满我也给了具体的位置和改法建议。一句话这篇文章不是给你讲理论是给你讲怎么把JSP购物网站这个题目坐实、做全、做漂亮。1. 项目全貌与设计思路拆解1.1 这个题目到底在做什么从表面看你要做的就是一个网上商城用户能注册、登录、浏览商品、把商品加进购物车、提交订单管理员能在后台维护商品信息、处理订单。但站在毕业设计的角度这套系统其实是在模拟一个标准JavaWeb应用从数据到展示再到业务控制的完整闭环。换句话说评委和指导老师想看到的不是你会不会“购物”而是你能不能讲清楚一条数据从MySQL表里被读出来经过Java代码处理塞进JSP页面最后渲染成用户在浏览器里看到的那张商品卡片。很多同学一上来就急着写代码或者急着跑通一份下载的源码却忽略了题目里“设计与实现”四个字的分量。“设计”意味着你要有系统架构、数据库设计、功能模块划分“实现”意味着代码能跑、功能闭环、页面能看。如果你在答辩PPT里放一张架构图再放一张ER图然后把关键代码讲明白老师的印象分会比那些只放截图的高出一大截。记住这个题目的核心是在展示你对JavaWeb分层思想的理解而不是展示你商城界面有多花哨。1.2 技术选型为什么是JSP这条老路现在JavaWeb开发早就被SpringBoot、Vue前后端分离占据了大半江山为什么毕业设计还大量保留“基于JSP”这种题目因为你必须理解一个底层事实JSP Servlet JavaBean JDBC这套组合是JavaWeb最原生的血脉。SpringBoot再好也是在这套东西上面封装了一层又一层。用JSP做电商题目好处有三点第一JSP页面里可以直接写Java代码和HTML标签天然契合“页面”和“数据”的混合场景你不需要额外搭建前后端分离项目对毕设来说省掉大量工程化配置。第二MVC结构非常清晰。JSP充当ViewServlet充当ControllerJavaBean / DAO充当Model。老师一看你的目录结构就知道你懂MVC这比什么都管用。第三部署简单。打成一个war包扔进Tomcat就能跑不用像SpringBoot那样折腾内嵌容器、打包配置、环境变量。当然你也别把JSP理解成“老古董就学不到东西”。恰恰相反当你亲手写一个Servlet去接收表单数据、再调DAO插入数据库的时候你对HTTP请求、Cookie、Session、中文编码这些基础问题的理解会比用框架时深得多。答辩时老师问“JSP和Servlet是什么关系”“Session存在哪里”你都能接得住因为你是一行行代码写过来的。1.3 功能模块怎么划分才满足答辩要求我给这个题目定下的模块划分方案在往届同学身上反复验证过既不会太多导致做不完也不会太少显得单薄。整个系统分两个角色普通用户和管理员。用户端的核心功能按使用路径串起来注册与登录用户注册后自动登录登录状态通过Session维持。商品浏览首页展示商品列表支持按商品名称搜索列表做分页。商品详情点击商品进入详情页显示图片、价格、库存、描述。购物车管理用户可以把商品加入购物车修改数量删除商品清空购物车。订单提交从购物车结算生成订单同时扣减商品库存。个人中心查看自己提交的订单列表查看订单状态确认收货。管理端的功能按表格罗列更清晰功能点说明管理员登录独立于用户表的登录入口通常放在/admin/login.jsp商品管理添加、编辑、上下架商品修改商品信息和图片订单管理查看所有订单修改订单状态待发货、已发货、已完成、已取消用户管理查看注册用户列表可禁用用户数据统计可选模块简单统计商品数量、订单总量、销售额你可能注意到我没有提“收藏夹”“评论功能”“优惠券”这些花活。原因很简单毕业设计的核心是验证基础业务逻辑的完整性而不是功能的无限堆叠。你先把上面这些主线功能做扎实保证每个功能都能讲出“输入→处理→输出”的完整链路如果还有富余时间再考虑加一两个亮点功能比如用ECharts画个销量统计图。切记宁要一条完整跑通的主链路不要五个半死不活的功能。2. 数据库设计与核心表结构2.1 六张表搞定用户、商品、购物车和订单购物网站的数据模型不复杂但表与表之间的关联关系必须捋清楚。我最常用也最推荐的表结构是六张表用户表、商品表、购物车表、订单表、订单项表、管理员表。用户表t_user用户id、用户名、密码、昵称、联系方式、注册时间、状态。密码必须密文存储至少用MD5加盐这是容易被老师指出的安全漏洞。商品表t_product商品id、商品名称、商品描述、价格、库存、图片路径、分类、上架时间、状态。购物车表t_cart_item购物车项id、用户id、商品id、数量、加入时间。需要注意这里存的本质是“用户和商品的多对多关系”所以购物车项是中间表。订单表t_order订单id、订单编号、用户id、总金额、下单时间、收货地址、联系电话、订单状态。订单项表t_order_item订单项id、订单id、商品id、商品名称快照、商品价格快照、购买数量、小计金额。为什么要存“快照”而不是直接关联商品表因为商品价格、名称都可能修改但订单一旦生成你的交易记录里的商品名称和价格必须保持当时的样子这是非常关键的设计细节。管理员表t_admin管理员id、用户名、密码、创建时间。一般就一条数据admin/admin123。下面这个建表脚本是SQL的完整参考字段类型和命名都经过验证直接照着用就行CREATE TABLE t_user ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL, password varchar(64) NOT NULL, nickname varchar(50) DEFAULT NULL, phone varchar(20) DEFAULT NULL, create_time datetime DEFAULT NULL, status int(11) DEFAULT 1 COMMENT 1正常 0禁用, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE t_product ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, description text, price decimal(10,2) NOT NULL, stock int(11) NOT NULL DEFAULT 0, image varchar(255) DEFAULT NULL, category varchar(50) DEFAULT NULL, status int(11) DEFAULT 1 COMMENT 1上架 0下架, create_time datetime DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE t_cart_item ( id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL, product_id int(11) NOT NULL, quantity int(11) NOT NULL DEFAULT 1, create_time datetime DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE t_order ( id int(11) NOT NULL AUTO_INCREMENT, order_no varchar(32) NOT NULL, user_id int(11) NOT NULL, total_amount decimal(10,2) NOT NULL, create_time datetime DEFAULT NULL, receiver_name varchar(50) DEFAULT NULL, receiver_phone varchar(20) DEFAULT NULL, receiver_address varchar(255) DEFAULT NULL, status int(11) DEFAULT 0 COMMENT 0待付款 1待发货 2已发货 3已完成 4已取消, PRIMARY KEY (id), UNIQUE KEY uniq_order_no (order_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE t_order_item ( id int(11) NOT NULL AUTO_INCREMENT, order_id int(11) NOT NULL, product_id int(11) DEFAULT NULL, product_name varchar(100) NOT NULL, product_price decimal(10,2) NOT NULL, quantity int(11) NOT NULL, sub_total decimal(10,2) NOT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE t_admin ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL, password varchar(64) NOT NULL, create_time datetime DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;2.2 购物车为什么不建议建表这里有个非常经典的设计分歧购物车到底要不要落库很多同学的直觉是把购物车里的每一项单独存一张表也就是我上面给出的t_cart_item。这样做的好处是用户关掉浏览器再打开购物车数据还在。但如果你用纯Session存购物车那么用户没登录也能加购物车代码实现更简单可是关掉浏览器数据就没了。我的建议是如果你做的是“用户必须登录才能买”的系统就建购物车表如果你只是在演示“加入购物车”这个动作可以用Session。但毕业设计我还是建议落库。原因很简单答辩时老师一定会问“购物车数据存在哪里怎么保证用户下次登录还能看到”你回答“Session里”虽然不能说错但会显得设计不够严谨。落库之后你还可以顺带讲出“把购物车看成未生成订单的临时中间状态”这种有设计感的话。需要注意的是购物车表里不应该出现商品名称、价格这种冗余字段。想象一下商品改价后购物车里的价格如果还是旧的用户结算时会觉得莫名其妙。所以购物车表只存商品id和数量价格在展示时实时去商品表查询这样才是最规范的。2.3 订单状态字段的前置设计订单状态是整套系统里最容易混淆的地方。我见过不少源码用String类型存状态比如“未处理”“已发货”这在展示层确实直白但给后续业务判断带来麻烦。更好的做法是用int类型数字代表状态统一用注释说明例如0代表待付款、1代表待发货、2代表已发货、3代表已完成、4代表已取消。为什么一定要在开发前就把状态机定下来因为这个字段会牵扯到至少四个地方用户下单时的默认状态、管理员后台修改状态的下拉选项、用户个人中心显示的状态文字、以及订单列表的筛选条件。如果你用一个散落的字符串到时候前端判断、后端判断、SQL查询条件就要写好几套不统一的值。用数字枚举所有地方一以贯之改动也只需要改一个常量类或者前端JSP里的三目判断。订单编号字段同样是个加分项。别直接用自增id当订单号别人一眼就看出你订单总量有多少设计上也显得业余。正确做法是在Java代码里生成一个唯一字符串例如“yyyyMMddHHmmss”加随机数再加一个自增id做唯一索引兜底。答辩时你可以主动讲一句“订单号我这里用了时间戳加随机数避免订单信息泄露和重复”。这个细节很能体现你的工程思维。3. 从零搭建环境和创建项目3.1 JDK Tomcat MySQL IDEA的环境配对做老牌JSP项目环境版本必须克制用太高版本反而容易踩坑。我推荐一套稳了无数次的组合JDK 8虽然JDK 11、17都出来了但Tomcat 8/9最匹配、最没脾气的还是JDK 8。如果你们的毕设要求必须用高版本Tomcat 10对应JDK 11以上但要注意Tomcat 10里javax.servlet被改成了jakarta.servlet很多老代码直接迁移会报包不存在非常坑不建议美式自找麻烦。Tomcat 8.5稳定中庸也能跑JDK8下载解压版直接配进IDEA。MySQL 5.7或MySQL 8.0我用5.7比8.0多因为驱动jar更方便5.7的默认时区和编码问题更少。不过8.0配8.0的驱动也完全OK主要记得在连接串里加上useSSLfalseserverTimezoneAsia/Shanghai。IDEA社区版或专业版社区版就够用不需要专业版的Spring Initializer我们要新建的是普通JavaWeb项目。数据库驱动mysql-connector-java 5.1.49对应MySQL5.7。如果MySQL8.0用8.0.33的驱动。以上这些工具在安装时都有默认步骤没什么难点真正容易出错的是后面我们在IDEA里新建Web项目的姿势。3.2 用IDEA创建传统JSP项目的正确姿势很多同学在IDEA里新建项目时如果找不到Java Enterprise或者Web Application选项就开始怀疑自己装了一个假IDEA。实际上社区版IDEA对JavaWeb项目支持比较弱但依然可以创建。我这里给一个通用性最强的创建流程完全不需要JavaEE插件新建一个普通的Java项目模板选“Java”或“Empty Project”。在项目根目录下右键添加“Web”适配IDEA会自动生成web目录和web/WEB-INF/web.xml。注意有的版本是手动创建一个web目录然后在Project Structure里把web目录标记成Web资源目录。在Project StructureCtrlAltShiftS里打开Modules选中你的模块点击上面的“”或直接看到Web选项把Web资源目录指向web并在Deployment Descriptors里设置web/WEB-INF/web.xml。在Dependencies里添加Tomcat的servlet-api.jar或者后面直接在Artifacts里配置Lib目录。其实最省事的方法是不要用IDEA自动生成Web项目那一套而是手动维护这个结构ShoppingSystem/ ├── src/ │ └── com/shop/ │ ├── bean/ // 实体类 │ ├── dao/ // 数据访问类 │ ├── servlet/ // 控制器 │ └── filter/ // 过滤器 ├── web/ │ ├── WEB-INF/ │ │ └── web.xml │ ├── css/ │ ├── js/ │ ├── images/ │ ├── admin/ // 后台页面 │ ├── user/ // 用户相关页面 │ └── index.jsp这样一个目录结构无论你用Eclipse还是IDEA无论把项目拷到哪台电脑都能被任何IDE正确识别。因为JavaWeb项目的本质就是“源码目录 web目录 web.xml”IDE只是帮助我们编译和部署而已。这也是我建议每个打算改源码的同学都要亲自动手重建一次目录的原因你能真正理解项目的骨骼。3.3 web.xml和项目目录结构说明传统JSP项目里web.xml是所有Servlet、过滤器、监听器的注册中心也是整个Web应用的总配置文件。这个文件不要随便删也不要依赖注解一梭子写到底。虽然Servlet 3.0之后可以用WebServlet注解免配置但毕业设计里我还是建议保留web.xml的方式因为老师打着看到代码里的servlet映射会认可你掌握了规范。一个典型web.xml长这样?xml version1.0 encodingUTF-8? web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd version3.1 display-nameShoppingSystem/display-name welcome-file-list welcome-fileindex.jsp/welcome-file /welcome-file-list !-- 编码过滤器 -- filter filter-nameEncodingFilter/filter-name filter-classcom.shop.filter.EncodingFilter/filter-class /filter filter-mapping filter-nameEncodingFilter/filter-name url-pattern/*/url-pattern /filter-mapping !-- 登录拦截器 -- filter filter-nameLoginFilter/filter-name filter-classcom.shop.filter.LoginFilter/filter-class /filter filter-mapping filter-nameLoginFilter/filter-name url-pattern/user/*/url-pattern /filter-mapping !-- 商品列表Servlet -- servlet servlet-nameProductListServlet/servlet-name servlet-classcom.shop.servlet.ProductListServlet/servlet-class /servlet servlet-mapping servlet-nameProductListServlet/servlet-name url-pattern/product/list/url-pattern /servlet-mapping !-- 其他Servlet类似 -- /web-app注意到那个EncodingFilter了吗我把它当成全套系统的“第一道安全线”。所有请求先进这个过滤器统一设置请求和响应的编码为UTF-8这样你的页面和数据库通信才不会出现中文乱码。关于乱码问题后面我会专门列出来讲。4. 核心功能实现与关键代码解读4.1 用户注册登录与Session管理用户登录是所有购物流程的前提也是整套系统最简单又最容易埋雷的地方。这里我直接给出一套最稳妥的做法用Servlet接收表单参数调DAO查询用户名和密码再把用户对象塞进Session。先看DAO层的一个典型查询方法public User login(String username, String password) { String sql SELECT * FROM t_user WHERE username ? AND password ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, username); ps.setString(2, password); ResultSet rs ps.executeQuery(); if (rs.next()) { User user new User(); user.setId(rs.getInt(id)); user.setUsername(rs.getString(username)); user.setNickname(rs.getString(nickname)); return user; } } catch (Exception e) { e.printStackTrace(); } return null; }这里必须注意三点坑用PreparedStatement而不是拼接SQL字符串。拼接字符串最大的问题是SQL注入比如用户名传 or 11就能绕过密码登录。你把这个点主动讲出来答辩瞬间加分。密码不能明文比对。至少在注册时做一次MD5加密登录比较的是加密后的密文。当然现在更推荐加盐和BCrypt但对毕设来说MD5盐已经比明文强一个档次。登录成功后一定要用session.setAttribute(user, user)保存用户对象而不仅仅是保存用户名。后面购物车、个人中心都要从Session里拿这个用户id没有它整个业务流程都断了。再补充一下登录Servlet的写法要点。request.getParameter(username)拿参数别用getAttribute。判断用户是否存在如果为null就跳回登录页并提示账号或密码错误如果非空就跳转到首页同时注意resp.sendRedirect()和req.getRequestDispatcher().forward()的区别。登录成功后必须用sendRedirect否则用户刷新页面会重复提交表单如果只是转发地址栏还是login的地址刷新就二次登录又是一个答辩经典提问。对于Session失效问题比如用户20分钟没操作被踢下线一般我们不太会专门去调超时时间用Tomcat默认30分钟就行。拦截器代码里判断Session中的user对象是否为null为null就重定向到登录页。这个逻辑写成Filter非常统一访客想直接访问/user/cart.jsp这类地址会被拦下来整个系统的权限边界就立住了。4.2 商品列表分页查询的实现很多同学拿到源码后发现商品列表不分页几十条商品全排在一页这是非常业余的表现。分页的实现逻辑其实很简单但你必须掌握计算总页数和限制查询偏移量的两个关键点。SQL层面就一句话SELECT * FROM t_product WHERE status 1 ORDER BY id DESC LIMIT ?, ?;第一个问号是偏移量offset (currentPage - 1) * pageSize第二个问号是每页条数pageSize。同时还要再查一次总记录数totalCount然后用totalPage (totalCount pageSize - 1) / pageSize算出总页数。这个向上取整的公式在MySQL里没有内置函数Java代码里这么写最方便。Servlet层大概是这样int page 1; int pageSize 8; String pageStr request.getParameter(page); if (pageStr ! null !pageStr.isEmpty()) { page Integer.parseInt(pageStr); } int totalCount productDao.getCount(); int totalPage (int) Math.ceil((double) totalCount / pageSize); if (page 1) page 1; if (page totalPage) page totalPage; ListProduct list productDao.getListByPage(page, pageSize); request.setAttribute(list, list); request.setAttribute(totalPage, totalPage); request.setAttribute(currentPage, page); request.getRequestDispatcher(/product_list.jsp).forward(request, response);JSP页面上分页导航的写法给一个可复用的片段div classpage-nav c:if test${currentPage 1} a hrefc:url value/product/list?page${currentPage-1}/上一页/a /c:if span第 ${currentPage} / ${totalPage} 页/span c:if test${currentPage totalPage} a hrefc:url value/product/list?page${currentPage1}/下一页/a /c:if /div页码显示时一定要注意边界条件当前页是第一页时上一页链接不能显示当前页是最后一页时下一页链接不能显示。否则点击到没数据的页面列表空白会被老师挑刺。此外搜索功能如果加了关键词分页的URL里要带上keyword参数否则第二页的搜索条件就丢了。这是个超高频bug。4.3 购物车与下单流程的实现思路购物车是整套系统的核心难点也是答辩时老师最爱追问的地方。我不会直接贴一大段重复代码而是把实现思路和关键判断逻辑讲清楚你完全可以根据自己的源码去对照。购物车落库之后它的操作就变成了对t_cart_item表的增删改查。最关键的是“加入购物车”的动作用户点击“加入购物车”时Servlet先判断这个用户当前的购物车里是否已经存在该商品。如果不存在就insert一条新记录数量为1如果已经存在就update数量加1。千万别傻傻地每次insert一条新记录那样同一个商品会出现好几条数量还不会合并。伪代码大概是这样CartItem item cartDao.findByUserIdAndProductId(userId, productId); if (item null) { cartDao.add(userId, productId, 1); } else { cartDao.updateQuantity(item.getId(), item.getQuantity() 1); }购物车展示页的逻辑也很清晰先查当前用户的所有购物车项拿到商品id列表再批量查商品信息组装成“购物车行”对象每一行显示商品图片、名称、单价、数量、小计。最后页面上用一个EL表达式累加计算总金额。最后一步是结算考试重点又来了。下单流程我建议这样设计用户在购物车页面点击“去结算”跳到一个填写收货人姓名、电话、地址的确认订单页。这个页面要把购物车里已有的商品列表展示出来用户可以核对金额。提交订单时Servlet在一个方法里做的事情有几件生成订单编号orderNo计算总金额totalAmount往t_order表插入一条主记录状态设为1待发货或者0待付款看你自己的设计遍历购物车列表往t_order_item表插入对应的订单项同时把商品名和价格作为快照存进去删除该用户的购物车数据更新对应商品的库存stock stock - 购买数量如果库存不够要报错回滚。这一个动作涉及多张表的写入一定要考虑事务问题。JDBC里事务的操作模板是Connection conn DBUtil.getConnection(); try { conn.setAutoCommit(false); // 多个更新操作 orderDao.insert(order); orderItemDao.batchInsert(items); cartDao.clearByUserId(userId); productDao.decreaseStock(productId, quantity); conn.commit(); } catch (Exception e) { conn.rollback(); throw new RuntimeException(下单失败请重试); } finally { conn.setAutoCommit(true); conn.close(); }只要有一处失败全部回滚这是保证业务正确性的底线。如果答辩老师问你“怎么保证购物的数据一致性”你直接把这段代码放出来他基本没什么可挑的了。很多网上流传的源码根本没有事务你要么把它补上要么至少知道这个漏洞以便答辩时回答“这个问题我考虑过”。4.4 后台管理管理员端的四个必备页面后台管理是体现系统完整性的重头戏。至少要有四个页面管理员登录页、商品管理页、订单管理页、用户管理页。这里我只挑两个最容易被忽视的细节讲商品管理页的“编辑商品”功能最大的坑在于图片上传。如果你不想引入复杂的文件上传组件可以把商品图片设计成一个URL地址在表单里用一个文本框让管理员填图片链接。这样工作量少很多但有个明显缺点——如果填的是网络图片没网就显示不了。稳妥一点的做法是上传到项目下的upload目录然后在数据库里保存相对路径。上传时JSP的form表单要设置enctypemultipart/form-dataServlet里用Part对象解析文件。订单管理页的核心是对订单状态的操作。管理员点“发货”实际上就是更新t_order表的status。这里记住前端不要直接传status数字并盲更新一定要做合法性校验比如只允许从“待发货”改成“已发货”不能把“已完成”直接改成“待付款”。状态流转的合法性判断可以放在Servlet的代码开头这又是一个能讲出设计深度的细节。用户管理页相对简单无非是CRUD加禁用启用。但要注意用户被禁用后这个用户如果在系统里还保持着登录态下次请求时必须判断用户状态是否为0。这通常可以在LoginFilter里多查一次数据库或者每次从Session读用户时联动校验状态。多数毕设源码不会做这一步如果你做出来就是一个亮点。5. 常见问题排查与源码使用避坑5.1 中文乱码的三种场景和统一解决JSP项目中文乱码是提问率最高的问题没有之一。乱码无非发生在三个位置页面显示乱码问题在JSP文件编码。解决办法是JSP页面顶部写上% page languagejava contentTypetext/html; charsetUTF-8 pageEncodingUTF-8%同时保证IDE里文件编码是UTF-8。如果还是乱码把项目设置里File Encodings的Global Encoding、Project Encoding、Default encoding for properties files全部改成UTF-8。表单提交到数据库后乱码问题在请求编码。GET请求参数乱码在Tomcat 8及以上默认已经处理主要问题是POST请求。最简单的统一方案就是前面说的EncodingFilter过滤器在doFilter里强转request.setCharacterEncoding(UTF-8); response.setCharacterEncoding(UTF-8); chain.doFilter(request, response);数据库表里中文乱码问题在数据库连接串和表字符集。连接串中一定要加characterEncodingutf8表的CHARSET用utf8mb4。如果已经存进去的乱码一般只能清掉重来没有后悔药。5.2 数据库连接失败的常见根源数据库连接报错是第二个大坑。最常见的五种情况驱动类没导入。错误信息通常是ClassNotFoundException: com.mysql.jdbc.Driver这是因为项目没把mysql-connector-java.jar放进WEB-INF/lib里。在Artifacts的输出目录里检查有没有lib文件夹没有就补。连接URL写错。5.7用jdbc:mysql://localhost:3306/shop?useSSLfalsecharacterEncodingutf88.0还要额外加serverTimezoneAsia/Shanghai。账号密码错误。注意MySQL安装时设置的root密码别把默认的123456当成了密码。数据库服务没启动。Windows服务里检查MySQL是否在运行或者命令行输入net start mysql。防火墙拦截。本地跑基本不会遇到但用局域网让别人访问时要检查3306端口是否放行。我给所有用源码的同学一个自查顺序先确认MySQL服务启动再确认数据库名和账号密码对得上再确认驱动版本匹配最后确认URL里的库名拼写。大部分数据库连接问题都是前三项。5.3 源码导入后跑不起来的十大原因每年都能收到大量留言学长我导入源码后Tomcat能启动但页面空白/404/500。这里我按出现频率排一下你可以当对照表来用。症状可能原因解决办法404但Tomcat正常项目没部署到Tomcat或者访问路径不对检查Artifacts是否勾选部署访问项目根路径/或/index.jsp500页面报错缺少jar包、连接不上数据库、表不存在看控制台完整堆栈逐条解决能打开登录页但登录报错数据库用户名密码不对或表结构不匹配核对DBUtil里的配置和数据库里的表页面样式全丢JSP引用的css路径不对用绝对路径${pageContext.request.contextPath}/css/style.css图片不显示图片路径存的是相对路径页面访问不到图片地址前拼项目名或用虚拟路径映射upload目录表单功能点不了JS文件没加载或路径404F12看Console修复js引用路径项目里没有web.xml版本较新的IDEA默认可能不生成手动创建web/WEB-INF/web.xml并注册端口被占用8080被其他程序占用修改Tomcat的Server port或关闭占用程序中文乱码编码问题见上文统一UTF-8并加过滤器Session永远登录不上Cookie被禁用或未设置JSESSIONID检查浏览器是否禁Cookie或Session配置是否正确5.4 答辩时容易被问到的几个点答辩准备最怕没有方向。JSP购物网站这个题目老师的提问高度集中在五个地方JSP和Servlet的关系是什么JSP最后也会被编译成Servlet但JSP更侧重页面展示Servlet更侧重业务逻辑Servlet对响应输出控制更强。为什么使用JSP而不是纯ServletJSP天然适合写HTMLServlet如果拼HTML字符串会非常繁琐维护性差。MVC思想就是把页面和逻辑解耦。购物车为什么要用数据库因为它需要持久化用户可能下次再来登录购物车还要保留。如果用Session服务器重启或用户浏览器关闭就丢了。库存超卖怎么处理订单事务里先判断库存用UPDATE语句stock stock - ? WHERE id ? AND stock ?受影响行数为0说明库存不足。这是一个很讲细节的回答。项目有哪些可以优化的地方不要乱答。你可以说密码改为BCrypt加密、增加Redis缓存购物车、用连接池替换原生JDBC。点到为止让老师知道你有一定的工程视野。我个人的建议是答辩前把你源码里每个Servlet对应的url-pattern、每个表的主键外键关系、每个功能页面的跳转逻辑都梳理一遍画在纸上。哪怕有些代码不是你写的你也要能看着代码讲清楚它做了什么。这是对自己负责。最后再分享一个我实测过的小技巧不论你手里的源码是从哪获得的拿到之后第一步不要急着跑先把整个项目的目录结构、每个Web目录下的JSP都按“用户端、管理员端、公共组件”分类看一眼在注释里写上自己的理解。这个过程能让你花半天时间彻底解读一套代码比瞎猜错误乱调强一百倍。等你把项目讲顺了、改出自己的一两个小功能点这个毕业设计就算彻底稳了。
返回列表