
简介面向Java Web初学者的宠物管理系统源码包基于JSPServletMySQL实现涵盖宠物分类查询、添加、编辑、删除等完整增删改查功能适合用来理解传统Java Web分层结构与基础CRUD流程。包内共41个文件核心包括7个Java源码、4个JSP页面、7个class编译文件及4个依赖Jar包同时附带SQL初始化脚本、配置说明文档、功能演示视频和多张运行截图便于对照学习与本地部署。压缩包整体6.37MB内容组织清楚源码、数据库、文档和视频分区放置即使零基础也能按文档步骤完成环境配置并跑通项目。已有1580人学习下载尤其适合课程设计、毕业设计入门参考或自学练手。1. 宠物管理系统源码一个能跑通全流程的 Servlet JSP 练手项目做 Java Web 入门的人最头疼的事就是视频看了一堆真要自己搭一个能增删改查的项目半天连环境都起不来。这套 javajspservletmysql 的宠物管理系统源码走的是最经典的 JSP Servlet JDBC 三层结构没有 Spring、没有 MyBatis所有请求路径、参数获取、数据库连接都是最原始的手写方式。反而因为原始你一眼就能看明白一次 HTTP 请求是怎么从浏览器走到 Servlet再走到 MySQL 的。这套系统功能很纯粹按分类查宠物、添加宠物、编辑宠物、删除宠物四个操作凑齐了就是一个完整的 CRUD 闭环。原版只有查询和添加没有编辑和删除后来在源码基础上做了一次升级补全现在交付的版本是完整的增删改查模块。它特别适合两类人一类是刚学完 Servlet 和 JSP 语法、想找个完整项目对照的在校生另一类是准备 Java 面试、想快速过一遍传统 Web 开发流程的求职者。接下来我把项目结构、核心代码、部署步骤和踩坑记录一条条拆给你看。2. 项目结构与数据表设计先读 SQL再做增删改查2.1 拿到压缩包先看什么压缩包解开之后目录结构是这样的petmgr # 项目根目录可直接导入 Eclipse / IDEA │ db_petmgr.sql # 数据库初始化脚本MySQL 直接执行 │ 详细配置.docx # 环境配置和部署说明含 JDK / Tomcat 版本说明 │ 宠物管理系统.pdf # 系统功能说明文档 │ 006...mp4 # 演示视频JSP 页面操作流程我拿到任何一套源码第一步永远是先开 SQL 脚本而不是先开代码。因为数据表能直接反映这个系统的业务边界——有几张表、字段怎么设计的、主键怎么生成的看完这些你再回去读代码思路会顺很多。这套系统的 SQL 脚本就一张宠物信息表典型的单表 CRUD 结构没有外键、没有关联查询对新手的友好度拉满。2.2 宠物表字段设计与类型选择打开db_petmgr.sql核心建表语句大致是这样CREATE TABLE pet ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL COMMENT 宠物名称, category VARCHAR(20) NOT NULL COMMENT 分类猫/狗/兔等, age INT DEFAULT 0 COMMENT 年龄月, gender VARCHAR(4) DEFAULT 公 COMMENT 性别, health VARCHAR(100) DEFAULT 健康 COMMENT 健康状况描述, detail TEXT COMMENT 详细描述 ) ENGINEInnoDB DEFAULT CHARSETutf8;字段设计逻辑很直白id用自增主键避免手动生成主键的麻烦category单独拎出来做成 VARCHAR 而不是用数字字典是因为这套系统没有设计分类表直接用字符串存分类名可以让查询 SQL 少一次 JOIN对入门项目来说这样做反而更好理解。age用 INT 存月份而不是年份是因为宠物年龄普遍不满一岁用月份表达更精确。detail用 TEXT 而不是 VARCHAR是给描述字段留足空间防止用户输入超长文本时插入失败。2.3 数据库连接配置放在哪JDBC 连接参数写在一个专门的工具类里常见做法是放在src/com/util/DBUtil.javapackage com.util; import java.sql.*; public class DBUtil { private static final String DRIVER com.mysql.jdbc.Driver; private static final String URL jdbc:mysql://localhost:3306/db_petmgr?useUnicodetruecharacterEncodingutf-8; private static final String USER root; private static final String PASSWORD 123456; static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } }注意这里characterEncodingutf-8必须加否则 JSP 页面提交的中文宠物名存进 MySQL 会直接变问号。DRIVER用的是老驱动com.mysql.jdbc.Driver这个类在 MySQL 5.x 及以下没问题如果你本机装的是 MySQL 8.0要把驱动改成com.mysql.cj.jdbc.Driver并且 URL 里加上serverTimezoneAsia/Shanghai否则驱动加载会直接报错。这是整套源码里最容易被环境坑到的地方。3. 核心代码走读从列表查询到完整增删改查3.1 按分类查询Servlet 接收参数的过程这套系统没用任何框架请求入口全部是 Servlet。宠物列表页的查询逻辑是这样的流程浏览器请求PetListServlet→ Servlet 里获取category参数 → 调用 DAO 层查数据库 → 把结果放进 request → forward 到pet_list.jsp。package com.servlet; import com.dao.PetDao; import com.entity.Pet; import javax.servlet.ServletException; import javax.servlet.http.*; import java.io.IOException; import java.util.List; public class PetListServlet extends HttpServlet { private PetDao petDao new PetDao(); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(utf-8); String category request.getParameter(category); ListPet petList; if (category ! null !全部.equals(category)) { petList petDao.findByCategory(category); request.setAttribute(currentCategory, category); } else { petList petDao.findAll(); request.setAttribute(currentCategory, 全部); } request.setAttribute(petList, petList); request.getRequestDispatcher(pet_list.jsp).forward(request, response); } }代码逻辑分三段看。第一段request.setCharacterEncoding(utf-8)是处理 POST 请求中文乱码的放在 doGet 里不冲突因为 GET 请求的参数在 URL 上主要靠 Tomcat 的 URIEncoding 配置保证。第二段是核心分支从 request 里拿category如果为空或者等于全部就查全表否则走条件查询。第三段是把查询结果塞进 request 作用域forward 到 JSP 页面渲染。request.getRequestDispatcher(...).forward()是服务端跳转地址栏不变JSP 里可以直接用 EL 表达式取到petList这个属性。这里有个细节值得留意category参数在前端 JSP 里是通过超链接传的比如pet_list.jsp?category猫中文参数会被浏览器自动 URL 编码Tomcat 8.0 默认 UTF-8 解码没问题但你的 Tomcat 如果版本很老7.0 以下需要手动改server.xml里的URIEncodingUTF-8。3.2 DAO 层封装PreparedStatement 防注入业务逻辑没写在 Servlet 里而是抽了一个PetDao类这是传统分层里很标准的做法。数据访问层用PreparedStatement而不是Statement参数用?占位符绑定package com.dao; import com.entity.Pet; import com.util.DBUtil; import java.sql.*; import java.util.ArrayList; import java.util.List; public class PetDao { public ListPet findByCategory(String category) { String sql SELECT * FROM pet WHERE category ?; ListPet list new ArrayList(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, category); ResultSet rs ps.executeQuery(); while (rs.next()) { Pet pet new Pet(); pet.setId(rs.getInt(id)); pet.setName(rs.getString(name)); pet.setCategory(rs.getString(category)); pet.setAge(rs.getInt(age)); pet.setGender(rs.getString(gender)); pet.setHealth(rs.getString(health)); pet.setDetail(rs.getString(detail)); list.add(pet); } } catch (SQLException e) { e.printStackTrace(); } return list; } }try-with-resources语法是关键Connection 和 PreparedStatement 用完后自动关闭不会把数据库连接资源耗尽。查出来的每一行记录手动 set 到 Pet 实体里这个过程叫 ORM 映射不过这是手写的。如果你对 MyBatis 里resultTypecom.entity.Pet的自动映射感到困惑看看这段手动 set 的代码就明白了——框架做的其实就是你在这里做的事。3.3 重点看升级部分编辑和删除这两个模块前面说了原版没有编辑和删除功能升级之后补全了。编辑功能是两个 Servlet 配合的PetEditServlet负责回显数据PetUpdateServlet负责接收表单提交更新数据库。删除是PetDeleteServlet按 id 删一条记录。// PetEditServlet - 编辑前先查出原数据回显到表单 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(utf-8); int id Integer.parseInt(request.getParameter(id)); Pet pet new PetDao().findById(id); request.setAttribute(pet, pet); request.getRequestDispatcher(pet_edit.jsp).forward(request, response); } // PetUpdateServlet - 接收表单参数执行 UPDATE protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(utf-8); int id Integer.parseInt(request.getParameter(id)); String name request.getParameter(name); String category request.getParameter(category); int age Integer.parseInt(request.getParameter(age)); String gender request.getParameter(gender); String health request.getParameter(health); String detail request.getParameter(detail); Pet pet new Pet(); pet.setId(id); pet.setName(name); pet.setCategory(category); pet.setAge(age); pet.setGender(gender); pet.setHealth(health); pet.setDetail(detail); new PetDao().update(pet); response.sendRedirect(PetListServlet); }删改这类写操作完成之后的重定向一定要用sendRedirect而不是forward。原因很朴素forward是服务端跳转浏览器地址栏还停在PetUpdateServlet用户这时候按 F5 刷新浏览器会再次提交上一次的 POST 请求于是数据库里多了一条重复的宠物记录。sendRedirect会返回 302 让浏览器主动跳到PetListServlet页面刷新变成普通的 GET 请求再刷新一万次也只是重新查一次列表安全得多。这个细节不知道坑了多少新手项目里两次请求的跳转方式都用对了你写代码的时候也要保持这个习惯。3.4 JSP 页面的表单和列表渲染JSP 页面用 JSTL 标签 EL 表达式渲染数据列表页的核心片段长这样c:forEach items${petList} varpet tr td${pet.id}/td td${pet.name}/td td${pet.category}/td td${pet.age}/td td a hrefPetEditServlet?id${pet.id}编辑/a a hrefPetDeleteServlet?id${pet.id} onclickreturn confirm(确定删除${pet.name}吗)删除/a /td /tr /c:forEachitems${petList}对应 Servlet 里 set 进去的petList属性varpet是循环变量。编辑和删除的链接拼了id参数所以对应 Servlet 里用request.getParameter(id)能拿到值。onclickreturn confirm(...)是前端的最后一道确认屏障防止误点删除按钮直接把数据清掉。升级补全的增删改查都集中在这套模式里Servlet 收参数、调 DAO、跳 JSP结构非常扁平每一环都看得见摸得着。4. 本地部署与运行三步把这个项目跑起来4.1 环境版本怎么搭配部署这套系统环境搭错了会浪费大量时间先说结论你照着配就行组件版本建议JDK8 或 11Tomcat8.5 或 9.0MySQL5.7或 8.0需改驱动IDEEclipse 或 IDEA选 Java EE / Enterprise 模式JDK 8 Tomcat 8.5 MySQL 5.7 是三件套里最稳的组合和源码里配置的驱动、连接参数完全对齐。MySQL 8.0 也能跑但要把DBUtil.java里的驱动类名换成com.mysql.cj.jdbc.Driver同时 URL 上补时区参数这个我在第 2 章已经提示过了。4.2 建库导数据SQL 脚本的执行方式打开 MySQL 命令行或 Navicat先建库再执行脚本mysql -u root -p # 输入密码后进入 mysql 命令行 CREATE DATABASE db_petmgr DEFAULT CHARACTER SET utf8; USE db_petmgr; SOURCE /你的目录/db_petmgr.sql;CREATE DATABASE ... DEFAULT CHARACTER SET utf8这里必须显式指定字符集否则会继承 MySQL 默认的 latin1中文字段值全变乱码。SOURCE是 MySQL 命令行执行外部 SQL 文件的标准方式路径不能有中文否则某些 Windows 版本的 MySQL 会报错。执行完之后用SHOW TABLES;确认 pet 表存在再跑一条SELECT * FROM pet;看有没有初始数据。4.3 导入项目到 IDEA 并配置 TomcatIDEA 里导入这套源码的操作是固定的File - New - Project from Existing Sources 选择 petmgr 目录 选 Import project from external model - Maven 或 Eclipse 这套源码不带 Maven选 Eclipse 导入方式即可导入之后是一个普通的 Java Web 项目需要在 Project Structure 里做两件事把web目录或WebContent标记为 Web 资源目录把lib下的 JDBC 驱动 jar 加进依赖。然后配置 TomcatRun - Edit Configurations - 左上角 - Tomcat Server - Local Application server 选你本地 Tomcat 的安装目录 Deployment 选项卡 - - Artifact - petmgr:war exploded Application context 填 /petmgrwar exploded是开发模式IDEA 直接把编译后的 class 和 JSP 页面映射到 Tomcat改代码热部署不用重新打 war 包。Application context填/petmgr访问路径就是http://localhost:8080/petmgr/。4.4 验证跑通访问入口和功能检查启动 Tomcat 之后浏览器输入http://localhost:8080/petmgr/PetListServlet能看到宠物列表页说明部署成功。随后按四个顺序逐个点一遍列表查询、添加宠物、编辑宠物、删除宠物。添加一条中文名字的宠物再编辑改一下年龄刷新列表确认数据变了删除再刷新确认数据没了。四步走完CRUD 闭环就通了。5. 新手常见问题与排查五个必踩的坑5.1 404 错误项目访问不到现象Tomcat 启动成功浏览器访问http://localhost:8080/petmgr/却报 404。原因八成是 deployment 里的 Application context 和实际访问路径不一致或者 Artifact 没部署上去。解决打开 Run Configuration 里的 Deployment 选项卡确认 Artifact 已添加Application context是/petmgr。改完重启 Tomcat再用http://localhost:8080/petmgr/访问。注意 IDEA 里改配置后有时需要重新 Run不能只点 Reload。5.2 启动时报 ClassNotFoundException: com.mysql.jdbc.Driver现象Tomcat 启动时控制台直接抛ClassNotFoundException或者运行到Class.forName(DRIVER)这段报错。原因MySQL 驱动 jar 没有打包进 WEB-INF/lib或者驱动类名不对。MySQL 8.0 下用com.mysql.jdbc.Driver会报这个错老驱动类名在 8.0 已移除。解决先确认驱动 jar 放到了WEB-INF/lib目录下并在 Project Structure 里加入了依赖。再确认 MySQL 版本8.0 就把DBUtil.java里的驱动类名改成com.mysql.cj.jdbc.Driver。这两个问题单独出现都好查最烦的是两个一起出现排查顺序先看 jar 再看类名。5.3 中文乱码存进数据库全是问号现象JSP 页面表单提交加菲猫数据库里存的是????页面回显示乱码。原因三层乱码叠加——JSP 页面编码、Servlet 接收编码、JDBC 连接编码任何一层不是 UTF-8 都会出问题。解决逐层排查。JSP 页面顶部确认有pageEncodingUTF-8Servlet 里request.setCharacterEncoding(utf-8)必须在getParameter之前执行JDBC URL 必须有characterEncodingutf-8。三层都改对了还乱码检查 MySQL 表字段字符集是不是 UTF-8SHOW CREATE TABLE pet;看字段的 charset如果是 latin1 就把表删了重新执行 SQL 脚本。5.4 删除功能点了没反应现象列表页点删除链接页面没跳转或者跳了但数据还在。原因最常见的是onclickreturn confirm(...)返回了 false。另外看数据库是不是自增主键如果 id 类型不对Integer.parseInt会抛 NumberFormatException。解决浏览器按 F12 开控制台Network 面板刷新再点删除看请求是没发出还是返回了错误。return confirm()返回 false 会阻断链接跳转这是正常的保护机制。请求发出去且返回 500看 Tomcat 控制台日志十有八九是findById返回 null或者id参数没传过来。单独测一个PetDeleteServlet?id1看这个 id 能不能删掉。5.5 数据库连接超时Too many connections现象连续点了几次查询或添加报Too many connections异常。原因代码里有连接没关闭的地方。DBUtil.java里如果只关闭了 ResultSet没有关闭 ConnectionTomcat 运行一段时间后连接池被打满。解决优先检查代码里是不是用了try-with-resources。这套源码里 DAO 层都是标准写法但如果你自己往里面加方法务必确保getConnection()创建的连接在 finally 里关闭。临时补救可以先重启 Tomcat 释放连接治本还是靠规范关闭连接。6. 从练手到实战给这个项目打三个升级补丁项目跑通之后别急着换下一个教程在它基础上加点东西收获更大。我通常建议新手按顺序做三件事。第一件把列表查询加上分页。现在的PetListServlet是一次性查全表数据量超过 100 条页面就明显变卡。做法是给PetDao加一个findByPage(int pageNum, int pageSize)方法SQL 用LIMIT ? OFFSET ?两个参数控制前端 JSP 加上一页/下一页两个链接。这一步做完你就理解了 MySQL 分页和 MyBatis PageHelper 的原理。第二件把删除改成软删除。现在PetDeleteServlet是物理删除DELETE FROM pet WHERE id?数据没了就没了。改成软删除需要加一个status字段默认 1删除时执行UPDATE pet SET status0 WHERE id?查询条件统一过滤status1。这个改动对数据安全意识帮助极大面试被问生产环境怎么删数据你就有话说了。第三件用 Session 做登录拦截。这步改动稍大但很有价值。新建一个LoginServlet接收用户名密码校验通过就session.setAttribute(user, username)在PetListServlet、PetEditServlet等每个 Servlet 的 doGet 最前面加一段判断if (session.getAttribute(user) null) { response.sendRedirect(login.jsp); return; }。不用新建过滤器先手动写一遍你会发现 Servlet 的重复代码有多烦人这时候再回头学 Filter 过滤器理解会深刻很多。这三件事做完这套宠物管理系统就从一个入门 CRUD 变成了带分页、软删除、登录校验的完整 Web 应用。我之前带过一个刚转行的朋友他拿到源码第一周就只做这三件事做完之后自己重新写了一遍写出来就是能放在简历上的项目。最后说一个我的个人习惯每次部署完这套源码我都会强行走一遍这个流程——关掉 Tomcat、清理数据库表数据、重新执行 SQL 脚本、重启 Tomcat、再走一遍增删改查。这套流程看起来机械但能把环境依赖和代码逻辑彻底分开排查问题的时候能帮你快速锁定到底是代码写错了还是环境改挂了。希望这份拆解能帮到你。本文还有配套的精品资源点击获取