简介这是一份基于jspservletmysql开发的简单宠物管理系统源码面向Java Web初学者适合用来练习JSP页面、Servlet控制层与MySQL数据库之间的增删改查操作。系统支持宠物分类查询、添加、编辑和删除功能简洁同时涵盖了数据库表设计、JDBC连接和页面数据回显等典型学习点。压缩包共41个文件包含7个Java源文件、4个JSP页面、4个依赖jar包、SQL数据库脚本以及png效果图、docx配置说明、pdf文档和mp4操作演示视频总大小6.37MB各类型文件分工明确便于对照学习。目前已有1580人学习参考热度较好。资源在原版本基础上新增了编辑与删除功能形成完整的增删改查模块并附带数据库初始化脚本、环境配置文档和运行录像读者可以按文档配置数据源、导入SQL并部署到Tomcat快速跑通项目理解jspservletmysql的整合流程也可作为课程设计或毕业设计前的练手模板。1. JSPServletMySQL 宠物管理系统课程设计源码到底能给你什么JSPServletMySQL 这三件套至今还是 Java Web 课程设计里的常客很多课程设计案例源码都绕不开它。这份宠物管理系统源码就是典型数据库脚本、petmgr 工程、配置文档、演示视频一次给全纯 Servlet 处理请求、JSP 渲染页面、JDBC 连 MySQL没有框架干扰。适合刚学完 Java Web 基础、想拿一份能跑通全流程的代码来入门的人。它把完整请求链路压缩到很小代码量浏览器发请求Servlet 接收处理DAO 层访问数据库结果回填到 JSP。按分类查询、添加、编辑、删除都在原版只有查询和添加后来补全编辑和删除才成为完整增删改查模块。想快速交课程设计或看懂传统 javaweb 骨架的这份很合适但不懂 JDBC 和 Tomcat 原理的话照视频配完照样踩坑。2. 压缩包结构与请求链路从 db_petmgr.sql 看到 Servlet 的完整流转2.1 压缩包内部结构哪些文件负责什么拿到压缩包第一件事不是急着导入 IDE而是先把包里每个文件认一遍不然很容易在“配置文档”和“代码”之间来回折腾还找不到东西。解压后大致是这个布局006_javajspservletmysql简答宠物管理系统/ ├── 功能描述.txt ├── 图片/1.png、2.png、3.png ├── 代码/petmgr/ ├── 配置/详细配置.docx ├── 数据/db_petmgr.sql ├── 文档/宠物管理系统.pdf └── 视频/006_...(演示视频).mp4db_petmgr.sql 是数据库初始化脚本建库、建表、插样例数据全在里面详细配置.docx 是环境搭建和部署的图文教程适合第一次跑 Java Web 项目的人照着点宠物管理系统.pdf 是项目说明文档交作业或答辩时可以直接引用演示视频和几张图片是运行效果的佐证。petmgr 是真正的 Web 工程文件夹src 目录放 Java 源码WebRoot有的是 web 目录放 JSP 和静态资源。如果你打开代码发现类名、目录名和后面写的略有出入不用纠结这是不同版本的命名差异逻辑对应关系是一致的。功能描述.txt 里也写了这个包经历过一次升级原版只有查询和添加后来补了编辑和删除所以你在代码里能同时看到“增删改查”四套处理逻辑而不只是某个残缺的半成品。在宠物管理系统这类课设项目里工程结构基本遵守同一个套路。src 下面一般拆成几个包bean 放数据模型类dao 放数据库访问层servlet 放请求处理工具类如 DBUtil 专门管理数据库连接。WebRoot 下放 JSP 页面和 WEB-INF/web.xmlweb.xml 是整个 Web 应用的入口描述文件。把这个两层结构记牢后面阅读代码会顺很多自己动手改功能时也知道该去哪一层的哪个文件动刀。2.2 数据库设计db_petmgr.sql 核心表结构这个系统功能简单数据库也没有复杂设计核心就是一张宠物信息表 pet所有业务都围绕它展开。下面这段 SQL 是这类项目的典型写法和脚本里实际字段命名可能有细微差别但结构基本一致CREATE DATABASE IF NOT EXISTS db_petmgr DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE db_petmgr; CREATE TABLE IF NOT EXISTS pet ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 宠物ID, name VARCHAR(50) NOT NULL COMMENT 宠物名称, category VARCHAR(20) NOT NULL COMMENT 分类如猫/狗/鸟, age VARCHAR(10) DEFAULT NULL COMMENT 年龄用字符串方便展示, sex VARCHAR(10) DEFAULT NULL COMMENT 公/母, description VARCHAR(500) DEFAULT NULL COMMENT 描述 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT宠物信息表;有两个设计细节值得你注意。第一category 直接存字符串没有单独拆分类表。小项目这么选是合理的查询不用 JOIN页面下拉框写死几个选项就行代价是以后想维护分类层级的联动关系会比较麻烦。第二age 字段用 VARCHAR 而不是 INT因为用户可能会填“3个月”或“2岁半”字符串在展示层最省事。这是课设项目里最常见的取舍我个人是认可这种务实做法的毕竟系统目标是跑通增删改查不是做一套完整的数据规范。脚本导入后可以用这条命令快速确认表结构就位mysql -uroot -p -e USE db_petmgr; SHOW TABLES; DESC pet;看到 pet 表和 id、name、category 这些字段说明数据库初始化完成可以进入部署环节了。如果表不存在先别急着改代码回头看 SQL 导入过程有没有报错大概率是没选对库或者脚本没执行完。2.3 一次完整请求的流转web.xml、Servlet、DAO 是怎么串起来的这个系统没有用 Spring MVC 之类的框架请求从页面到数据库完全靠 web.xml 的映射和 Servlet 内部分发逻辑驱动。我从访问列表页这个场景说起。浏览器输入 http://localhost:8080/petmgr/Tomcat 根据 welcome-file 找到 index.jspindex.jsp 一般会跳转到 listPet.jsp。listPet.jsp 上有个查询按钮或分类下拉框提交到类似 pet 的 URL。这个 pet 不是文件名而是 web.xml 里声明的 Servlet 映射?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_4_0.xsd version4.0 display-namepetmgr/display-name servlet servlet-namePetServlet/servlet-name servlet-classcom.petmgr.servlet.PetServlet/servlet-class /servlet servlet-mapping servlet-namePetServlet/servlet-name url-pattern/pet/url-pattern /servlet-mapping welcome-file-list welcome-fileindex.jsp/welcome-file /welcome-file-list /web-app这段配置把 /pet 这个 URL 交给 com.petmgr.servlet.PetServlet 处理。注意 schema 版本web-app_4_0.xsd 对应 Tomcat 9如果本地是 Tomcat 8.5要把 schema 里的 4.0 改成 3.1否则启动时解析会报错。PetServlet 收到请求后先读一个 action 参数用 if/else 或 switch 分发到具体方法。这是传统 Servlet 项目最常见的写法也是这个系统用一个 Servlet 完成列表、添加、编辑、删除的原因protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); String action request.getParameter(action); if (list.equals(action)) { listPet(request, response); // 查全部或按条件查 } else if (toEdit.equals(action)) { showEditPage(request, response); // 跳转编辑页并回显 } else if (delete.equals(action)) { deletePet(request, response); // 删除记录 } else { listPet(request, response); } }action 参数的值由 JSP 页面的表单或超链接决定。列表页查询按钮提交 actionlist编辑链接带 actiontoEditid1。request.setCharacterEncoding(UTF-8) 必须放在所有 getParameter 之前否则读到的中文参数已经乱码这是整个系统里最容易踩的坑后面避坑章节专门展开。Servlet 拿到参数后把业务委托给 DAO 层。PetDAO 用 JDBC 执行 SQL把 ResultSet 逐行封装成 Pet 对象再返回 List。Servlet 把 List 放进 request 域使用 request.getRequestDispatcher(listPet.jsp).forward(...) 转发到 JSP页面再用 EL 或 JSTL 遍历 List 渲染表格。到这里“页面 → Servlet → DAO → 数据库 → 页面”的闭环就完成了。理解这条链路比背十个增删改查代码片段都管用因为整个项目所有功能都是在这条链路上增加分支而已。3. 部署配置JDK、Tomcat、MySQL 三件套的版本搭配与连接参数3.1 版本搭配为什么推荐 JDK 8 Tomcat 9 MySQL 8先给一个我验证过能稳定跑起来的组合组件推荐版本注意事项JDK1.88u202 及以上大多数教学环境默认版本Tomcat8.5.x 或 9.0.x对应 Servlet 3.1 / 4.0 schemaMySQL5.7 或 8.0.x8.0 需注意驱动类名和时区参数mysql-connector-java5.1.49 或 8.0.x版本不同驱动类名不同这套组合推荐的理由很简单网上大量 Java Web 课程设计源码都以 JDK 8 为基准编译Tomcat 8.5 和 9.0 在 Servlet 层面的行为差异对这个小项目没有实际影响。JDK 11 以上也能跑但如果你用老版本 IDE反而容易在编译级别上卡住。JDK 环境变量配置这部分详细配置.docx 里应该有截图如果还卡在 java -version先不要往下走否则部署阶段报的错会让你分不清是环境问题还是代码问题。MySQL 版本是这个组合里最需要小心的一环。如果本地 MySQL 是 8.0而源码自带的驱动 jar 是 5.1.x连接时大概率会报 caching_sha2_password 相关错误因为 MySQL 8 默认的认证插件和 5.x 不兼容。解决方式有两种把 mysql-connector-java 升级到 8.0.x并修改 DBUtil 里的驱动类名为 com.mysql.cj.jdbc.Driver或者在 MySQL 里把 root 用户的认证插件改回 mysql_native_password。注意如果你打算用 MySQL 8.0优先选第一种方案改驱动不动数据库账号以后换环境也更省事。连接 URL 在 MySQL 8 下建议写全这几个参数jdbc:mysql://localhost:3306/db_petmgr?useSSLfalseallowPublicKeyRetrievaltruecharacterEncodingutf8mb4serverTimezoneAsia/ShanghaiuseSSLfalse 是为了避免 SSL 握手报错serverTimezone 解决 8.0 的时区差异characterEncodingutf8mb4 保证中文写入正常。这串参数几乎能覆盖 MySQL 8 下的大部分连接异常。3.2 导入数据库命令行、Navicat 两条路径数据库脚本导入是最容易出乱码的环节这里给两种方式。命令行方式最简单把终端切到 db_petmgr.sql 所在目录执行mysql -uroot -p db_petmgr.sql输入密码回车看到没有任何报错脚本就执行完了。Navicat 方式是打开连接后右键数据库选择“运行 SQL 文件”选中 db_petmgr.sql编码选择 utf8mb4执行完刷新库列表。导入完成后执行一次检查mysql -uroot -p -e USE db_petmgr; SHOW TABLES; DESC pet;如果看到 pet 表和 id、name、category 等字段说明数据初始化成功。这里有两个高频坑。第一不要在 Navicat 的查询编辑器里整段复制 SQL 执行脚本里如果有 CREATE DATABASE 语句查询编辑器可能执行不完整最后库建出来了表数据是空的。第二MySQL 8 命令行导入如果报 public key retrieval is not allowed不是密码错误而是认证插件导致的检查一下连接串是否带了 allowPublicKeyRetrievaltrue。3.3 部署进 TomcatIDEA 与 Eclipse 的操作差异把 petmgr 导入 IDE 后配置 Tomcat。Eclipse 用户在 Servers 视图新建 Tomcat 实例把项目 Add 进去IDEA 用户在 Run Configuration 里选择 Tomcat Server-Local配置 Application context 为 /petmgr。启动前先确认三件事。第一web.xml 的 schema 版本和 Tomcat 版本匹配前面说过 4.0 对应 Tomcat 9。第二mysql 驱动 jar 已经放进 WEB-INF/lib不是只存在于 IDE 的外部库列表里否则部署后 jar 进不了 artifact运行时报 ClassNotFoundException 是必然的。第三如果 Tomcat 8080 端口被占用改 conf/server.xml 里的 Connector 配置Connector port8081 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 /改完端口重启 Tomcat浏览器访问 http://localhost:8081/petmgr/。看到列表页或登录页说明部署成功。如果 404先检查访问路径里的上下文路径是不是 /petmgr这个值要和 IDE 里配置的 Application context 一致跟文件夹叫什么名字没关系。我在答疑时发现不少人把工程文件夹重命名为 petmgr2但 IDE 里 Application context 仍写 /petmgr那应该访问的还是 /petmgr而不是 /petmgr2。4. 增删改查实现分类查询、添加表单、编辑回显与删除确认的关键代码4.1 列表和分类查询PreparedStatement 动态拼条件列表是系统的默认页面。PetDAO 里提供一个同时支持按名称模糊查询和按分类精确查询的方法这样无论是直接进列表还是选择分类后再查询都走同一个方法public ListPet findByNameAndCategory(String name, String category) { ListPet list new ArrayList(); String sql SELECT id, name, category, age, sex, description FROM pet WHERE 11; if (name ! null !name.trim().isEmpty()) { sql AND name LIKE ?; } if (category ! null !category.trim().isEmpty()) { sql AND category ?; } try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { int index 1; if (name ! null !name.trim().isEmpty()) { ps.setString(index, % name %); } if (category ! null !category.trim().isEmpty()) { ps.setString(index, category); } try (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.getString(age)); pet.setSex(rs.getString(sex)); pet.setDescription(rs.getString(description)); list.add(pet); } } } catch (SQLException e) { e.printStackTrace(); } return list; }代码逻辑不复杂重点在两处。WHERE 11 是动态拼接条件的常用写法后面接 AND 不需要判断当前是不是第一个条件省去一层 if 嵌套用 PreparedStatement 而不是字符串拼 SQL避免了引号转义麻烦也天然挡住了 SQL 注入。这是 JavaWeb DAO 层最经典的写法面试时也常被问到。设置参数时 index 从 1 开始递增顺序必须和 SQL 里 ? 的出现顺序一致否则运行时会报参数索引错误。分类下拉框的数据来源可以写死几个 option也可以用 SELECT DISTINCT category FROM pet 从数据库动态加载。我更推荐后者新增分类后不用改 JSP 就能自动出现。但要注意动态查询时如果数据库里没有任何数据下拉框会是空的所以种子数据别删光。4.2 添加宠物doPost 编码处理与 PRG 跳转添加页面 addPet.jsp 的表单字段和 pet 表字段一一对应提交方式必须用 post避免 URL 过长和参数裸露form actionpet methodpost input typehidden nameaction valueadd / 名称input typetext namename / 分类 select namecategory option value猫猫/option option value狗狗/option option value鸟鸟/option /select 年龄input typetext nameage / 性别 select namesex option value公公/option option value母母/option /select 描述textarea namedescription/textarea button typesubmit添加/button /formform 的 action 写的是 pet 而不是 /petmgr/pet这里依赖相对路径解析如果当前页面 URL 是 http://localhost:8080/petmgr/addPet.jsp表单会提交到 http://localhost:8080/petmgr/petTomcat 按 web.xml 找到 PetServlet。如果你在 JSP 里加了 标签提交地址以 base 为准两种方式混用时最容易出 404。Servlet 的 doPost 处理新增protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); String action request.getParameter(action); if (add.equals(action)) { String name request.getParameter(name); String category request.getParameter(category); String age request.getParameter(age); String sex request.getParameter(sex); String description request.getParameter(description); Pet pet new Pet(); pet.setName(name); pet.setCategory(category); pet.setAge(age); pet.setSex(sex); pet.setDescription(description); int rows new PetDAO().addPet(pet); if (rows 0) { response.sendRedirect(pet?actionlist); } else { request.setAttribute(msg, 添加失败); request.getRequestDispatcher(addPet.jsp).forward(request, response); } } }doPost 开头第一行必须是 request.setCharacterEncoding(UTF-8)而且要放在任何 getParameter 之前。这一步漏了表单提交的中文到 Servlet 时已经是乱码后面数据库配置得再标准也救不回来。另一个细节是新增成功后用 sendRedirect 而不是 forward这叫 PRG 模式Post/Redirect/Get目的是让浏览器地址栏变成 get 请求的列表页用户按 F5 刷新不会重复提交表单。很多课设代码这里用 forward结果刷新一次多一条数据答辩时容易被老师挑出来。4.3 编辑回显和删除id 参数传递与 UPDATE/DELETE 语句编辑功能比新增多一个步骤先回显再提交。列表页每一行生成两个操作链接常见写法a hrefpet?actiontoEditid${pet.id}编辑/a a hrefpet?actiondeleteid${pet.id} onclickreturn confirm(确定删除这条记录吗);删除/a这里的 ${pet.id} 是 EL 表达式它取的是 request 域中 pet 对象的 id 属性。EL 解析的是 JavaBean 的 getter 方法所以 Pet 类里必须有 getId() 方法属性名拼错一个字拿到的就是 null后续转 Integer 直接抛 NumberFormatException。编辑回显的 Servlet 方法private void showEditPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id Integer.parseInt(request.getParameter(id)); Pet pet new PetDAO().findById(id); request.setAttribute(pet, pet); request.getRequestDispatcher(editPet.jsp).forward(request, response); }editPet.jsp 里除了表单字段还有两个隐藏域一个存 id用来定位更新哪条记录一个存 actionupdate让 doPost 的 else if 分支识别这是更新操作。更新逻辑最终落到一条 UPDATE 语句UPDATE pet SET name?, category?, age?, sex?, description? WHERE id?删除操作更简单一条 DELETE FROM pet WHERE id? 就能删干净。但这里我要多说一句列表页里的删除链接是 GET 请求这是课设项目的常规偷懒写法对生产环境有隐患。搜索引擎预取、浏览器收藏夹都可能把 GET 请求当普通访问一旦带上 id 就会误删数据。想做得严谨一点可以把删除改成表单 POST 提交或者至少保留前端的 confirm 拦截。这是源码可以升级的方向之一下一章我会给完整的建议。5. ServletJSP 项目避坑清单连接失败、中文乱码、404 的现场还原5.1 ClassNotFoundException: com.mysql.jdbc.Driver现象第一次访问列表页Tomcat 控制台抛 java.lang.ClassNotFoundException: com.mysql.jdbc.Driver页面 500错误堆栈定位到 Class.forName(...) 这一行。原因驱动 jar 没有被打进 WEB-INF/lib。很多人把 jar 拖到 IDE 的 External Libraries 或 Tomcat 的 lib 目录下以为这样就能用。实际上 Web 应用运行时每个应用的类加载器以 WEB-INF/lib 和 WEB-INF/classes 为主外部库的配置不一定生效。另外 MySQL 8.0 用户如果用了旧驱动驱动类名本身也对不上。解决把 mysql-connector-java 的 jar 拷到 petmgr 工程的 WEB-INF/lib 下在 IDE 里 clean 并重新部署确认部署后的 artifact 里包含这个 jar。如果 MySQL 是 8.0把驱动类改成 com.mysql.cj.jdbc.Driver。改完重启 Tomcat 再访问这个异常就消失了。这条解决路径我走过不下五次每次都是 jar 位置或版本的问题和业务代码无关。5.2 数据库连接失败Access denied 或 Public Key Retrieval is not allowed现象页面报 SQLException提示 Access denied for user rootlocalhostusing password: YES或者提示 Public Key Retrieval is not allowed。原因前者是账号密码不匹配后者是 MySQL 8 默认 caching_sha2_password 认证插件要求客户端在首次连接时获取公钥旧驱动或连接串没带 allowPublicKeyRetrievaltrue 时就会报这个错。不少人在这一步反复确认密码结果不是密码问题是认证方式不匹配。解决先用 Navicat 或命令行确认账号能正常登录排除密码错误。然后在 JDBC 的 URL 上加参数jdbc:mysql://localhost:3306/db_petmgr?useSSLfalseallowPublicKeyRetrievaltruecharacterEncodingutf8mb4serverTimezoneAsia/Shanghai如果还报 SSL 或时区错误说明驱动版本太旧直接换 8.0.x 的 mysql-connector-java。DBUtil 里的连接参数最好统一放到常量里改一处全局生效不用到处找。5.3 中文乱码添加宠物后中文名变成“???”现象新增宠物成功回到列表页中文名称和分类显示为问号英文正常。直接查数据库里的记录也是问号。原因三层出现编码断层。Servlet 的请求体没设置 UTF-8或者设置放在了 getParameter 之后读到就是乱码JDBC 连接 URL 没带 characterEncoding驱动侧又转换一次数据库或表本身是 latin1插入时再转一次就彻底变问号。最常见的还是前两者叠加。解决按三步统一编码。第一Servlet 里 request.setCharacterEncoding(UTF-8) 写在方法第一行第二JDBC 连接 URL 加 characterEncodingutf8mb4第三确认数据库和表的 charset 是 utf8mb4导入 SQL 时选择 utf8mb4 编码。改完后删掉刚才的脏数据重新插一遍。已经变成问号的记录不要指望靠查数据看编码恢复直接删除重来最快。5.4 访问项目出现 404Tomcat 控制台却显示部署成功现象Tomcat 启动正常日志里出现 petmgr 的部署信息但浏览器访问 http://localhost:8080/petmgr/ 返回 404。原因这类 404 大概率不是代码问题而是上下文路径或映射不一致。常见有三种情况IDE 配置的 Application context 不是 /petmgrweb.xml 里 welcome-file 写错文件名比如写 index.html 而工程里只有 index.jspJSP 里 form 的 action 和 web.xml 的 url-pattern 对不上。这不是什么玄学就是路径没对齐。解决先看访问地址是否带了正确的项目上下文路径再检查 web.xml 的 welcome-file 是否指向真实存在的文件。如果是页面内链接 404回到第 2 章的链路图把 URL 逐段拆开http://localhost:8080/上下文路径/Servlet映射?参数一段一段核对。最后看 IDE 部署输出确认实际部署的上下文路径和浏览器输入一致。5.5 页面能显示但 CSS、图片全部失效现象列表页数据正常渲染但页面没有样式、图片红叉整体布局错乱。原因JSP 里 css 和图片用了相对路径比如 hrefcss/style.css。当浏览器地址是 /petmgr/pet?actionlist 时相对路径会基于 /petmgr/pet 解析最终去找 /petmgr/pet/css/style.css自然不存在。这是 Servlet 映射路径和 JSP 静态资源混用时的典型问题数据没错纯粹是浏览器解析基准变了。解决在 JSP 页面顶部加一行 base 标签让所有相对路径都基于项目根目录% String basePath request.getScheme() :// request.getServerName() : request.getServerPort() request.getContextPath() /; % base href%basePath%加了这一行后直接写 hrefcss/style.css 也会被解析成 /petmgr/css/style.css不会再跟着 Servlet 路径到处乱跑。这个修复几乎零成本但很多课设代码里压根没写页面数据全对就是丑得没法看。6. 进阶升级登录、分页、校验和参数过滤让课设更完整到这里系统的部署和核心增删改查已经盘清楚。如果你打算把这个包作为课程设计或者想让它更完整一些下面四个改动优先级最高每个半小时内能完成但价值很直观。先加登录。数据库新建一张 user 表字段 id、username、password插入一条测试账号建 login.jsp 做登录表单Servlet 里查库比对成功后用 session.setAttribute(loginUser, username) 存登录态listPet.jsp 和 addPet.jsp 顶部统一检查 session为空就重定向回 login.jsp。这是答辩时最常被问“整个系统状态怎么控制”的地方一套下来能讲三五分钟。再加分页。列表页超过十几条数据后浏览体验很差。PetDAO 里加一个带 LIMIT 的查询方法String sql SELECT id, name, category, age, sex, description FROM pet LIMIT ?, ?;Servlet 里从 request 拿 pageNo 和 pageSize 两个参数默认 pageNo1、pageSize10查总记录数后算出总页数JSP 上渲染“上一页/下一页”两个链接。分页是 Java Web 面试高频题强烈建议手写一遍不要直接复制别人的。然后是前端校验。addPet.jsp 的 form 加 onsubmit 事件名称为空时直接弹提示不发请求form actionpet methodpost onsubmitreturn checkForm(); script function checkForm() { var name document.querySelector(input[namename]).value.trim(); if (name ) { alert(请输入宠物名称); return false; } return true; } /script但记住前端校验只负责体验后端 Servlet 里同样要判断 name 非空否则绕过页面直接 POST 请求照样插入空数据。前后端双重校验才是完整做法这也是面试官喜欢追问的点。最后是参数过滤。第 4 章提到 LIKE 查询时如果用户输入了 % 或 _ 会被当成通配符造成意外匹配。在把关键字拼进 SQL 参数前做一次转义keyword keyword.replace(%, \\%).replace(_, \\_);这样用户输入“100%”时查询的是字面的百分号而不是匹配任意字符。我拿到任何一份新源码的习惯是先把 web.xml 和数据库脚本读一遍确认入口 URL 和表结构之后才启动项目。这份宠物管理系统我也照样过了一遍驱动不打包、中文乱码、相对路径 404几个典型的坑全踩过才确认源码本身没有大问题。从那以后每次部署老的 Servlet 项目我都会把“驱动是否进 WEB-INF/lib、编码是否设置、上下文路径是否一致”这三项强制过一遍再也没有在环境问题上反复翻车。你照着这篇笔记跑一遍大概率也会遇到其中一两个问题回第 5 章对号入座就行。希望帮到你。本文还有配套的精品资源点击获取