JavaWeb图书管理系统部署与二次开发:从环境配置到核心代码解析
发布时间:2026/10/1 11:27:07 锦皓数字建站

简介这是一份基于JavaWeb的图书管理系统完整项目涵盖前端页面、后端服务与数据库脚本面向计算机专业毕业设计学生、课程设计和期末大作业需求者也适合需要JavaWeb实战练习的初中级学习者。压缩包共352个文件约64.72MB包含37个Java源码与91个Class文件、14个HTML页面、13个CSS样式、12个JS脚本另有41个XLS数据文件与5个SQL建库脚本以及JSP、XML、属性配置等结构清晰便于导入开发工具直接运行调试。项目为经导师指导并认可的98分毕业设计作品完整提供前端交互、后端业务逻辑和数据库设计所有代码经过严格调试确保可正常运行。已有240人学习下载既适合在毕业设计中作为参考模板也可作为课程设计或期末大作业的功能完善实例帮助学习者快速掌握JavaWeb项目开发流程。1. 拿到 javaweb 图书管理系统“前端后端源码数据库”压缩包后先解决这三件事很多读者手里其实都躺着一个名字相近的压缩包“基于javaweb的图书管理系统前端后端源码数据库优质项目.zip”解压后里面有 src、web、SQL 文件。常见场景是课程设计要用或者想拿一个完整案例学一下前端和后端怎么配合。拿到手的第一反应往往是把代码往 IDEA 里一拖然后直接点运行结果要么 404要么数据库报错最后得出“这个项目有问题”的结论。其实这类成熟的 javaweb 图书管理系统源码结构大同小异问题几乎都出在三件事上环境版本不匹配、数据库脚本没导入、Tomcat 的部署配置不对。把这三件事理顺了项目基本就能跑。这个项目属于典型的 JavaWeb 单体应用前端是 JSP/HTML/CSS/JavaScript后端是 Servlet Service DAO数据库是 MySQL正好覆盖了学习 JavaWeb 的完整链路适合课程设计、毕业设计也适合想学会 IDEA 里启动 JavaWeb 完整项目的人对照着练。接下来按顺序拆解这个项目从结构到启动把每一步的参数和坑都说清楚。2. 先读懂 javaweb 图书管理系统的分层前端、后端、数据库到底在干什么2.1 为什么这类项目坚持用 Servlet/JSP而不是 Spring Boot拿到这类项目很多人第一句话是“这都 2025 年了怎么还在用 Servlet/jsp”。原因很直接教学顺序和课程设计的要求。Spring Boot 的确省事但对初学者来说它是个黑匣子——一个注解上去请求就从入口走到了数据库中间发生了什么很难看清。而 javaweb 的图书管理系统最常见的做法是把请求链路完整露出来浏览器发起请求 → web.xml 或 WebServlet 把 URL 映射到某个 Servlet → Servlet 调用 Service 层方法 → Service 调 DAO → DAO 通过 JDBC 访问 MySQL 数据库 → 结果一层层返回 → Servlet 把数据塞进 request 或 session → forward 到 views 下的 JSP 页面 → JSP 渲染成 HTML 返回浏览器。这种分层不是多余的它的价值在于每一层都能独立测试DAO 可以单独联数据库Service 可以只测业务逻辑Servlet 只关注参数接收和返回。二次开发时如果想给项目加“图书预约”功能你只需要按这个链路加一张表、一个 DAO 方法、一个 Service 方法、一个 Servlet 和一个 JSP改动的边界非常清晰。在技术选型上我一般推荐按项目的原始技术栈来跑而不是拿到手先换成 Spring Boot。原因很简单换框架不是一行配置能解决的事涉及的依赖、包结构、事务管理全都会变跑不起来时你很难判断是自己改坏了还是原来就坏了。正确做法是先按原样跑通再考虑拆分改造。2.2 前端文件不是装饰JSP 目录、请求路径和静态资源要这样看这个项目里前端部分通常放在 web 目录或者 WebRoot 目录下里面至少有 index.jsp、login.jsp 一类的页面还有 css、js、images 文件夹。打开项目后我建议先看 web/WEB-INF 目录。这个目录有个特殊之处放在 WEB-INF 里面的 JSP 文件不能被浏览器直接访问只能通过 Servlet forward 进入。这样做的好处是强制走后端逻辑防止有人不登录就访问图书管理后台页面。前端和后端的配合方式简单说就是表单提交和超链接带着参数访问 Servlet例如form action${pageContext.request.contextPath}/login methodpost input typetext nameusername placeholder用户名 input typepassword namepassword placeholder密码 button typesubmit登录/button /form${pageContext.request.contextPath}是 JSP 里动态获取项目根路径的写法它解决的是不同机器上项目名可能不同的路径问题。如果这里写死/book_manage/login换到你的电脑上部署名变了表单就会 404。参数username、password会被 Servlet 通过request.getParameter(username)拿到我在下面第 4 章的登录代码里会展开讲。静态资源CSS、JS、图片一般放在 web 根目录下用link relstylesheet href${pageContext.request.contextPath}/css/login.css这种形式引入。很多新手翻车在这个细节上直接把 CSS 文件放进了 WEB-INF结果浏览器拿不到样式页面看起来像“裸奔”。记住一个判断标准能被浏览器地址栏直接访问的文件放在 WEB-INF 外面需要权限控制的视图页面放 WEB-INF 里面。2.3 数据库脚本是命根子表关系、导入顺序和连接参数这个项目的数据库一般是一个名为 book 或 library 的库核心表通常有这三张表名作用关键字段user用户/管理员账号id、username、password、rolebook图书信息id、book_name、author、publisher、stateborrow借书记录id、book_id、user_id、borrow_date、return_date其中 borrow 表通过 book_id 和 user_id 关联另外两张表这是典型的“一对多”关系设计一本书可以被多次借阅一个用户可以借多本书。导入数据库时不要只盯着 SQL 文件里建表和插入语句还要注意 SQL 文件的执行顺序。有的项目把建库语句写在注释里需要用命令行手动建库有的直接在 SQL 文件开头写了CREATE DATABASE IF NOT EXISTS但你用 IDEA 的数据库面板执行时可能会因为字符集不识别而报错。最稳妥的导入方式是命令行动手。在 MySQL 的 bin 目录下执行mysql -uroot -p123456 -e CREATE DATABASE IF NOT EXISTS book DEFAULT CHARSET utf8mb4; mysql -uroot -p123456 book /解压路径/sql/book.sqlmysql命令后面的-uroot是用户名-p123456是密码中间不空格这是 MySQL 的固定写法book指定要导入的库名表示把 book.sql 文件的内容作为输入喂给 mysql 命令。导入完成后用mysql -uroot -p123456 -e USE book; SHOW TABLES;看表是否齐全。连接参数通常集中在一个配置文件里比如db.properties或jdbc.properties下面是最常见的三种数据库版本需要改的参数jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/book?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai jdbc.usernameroot jdbc.password123456如果是 MySQL 8 以上的驱动driver 要改成com.mysql.cj.jdbc.DriverURL 里的serverTimezone是 MySQL 8.0 的强制要求不带这个参数连 MySQL 8 会直接报时区错误。useUnicodetrue和characterEncodingutf8是处理中文乱码的两个关键参数缺一个都会导致插入书名时出现问号。3. 在 IDEA 里把这个 javaweb 图书管理系统跑起来环境选型、导入步骤、数据库连接与启动验证3.1 环境版本怎么选JDK、Tomcat、MySQL 的搭配在拿到这类“javaweb 项目完整案例 mysql”源码时第一步不是打开 IDEA 写代码而是确认机器上的环境。我一般推荐这样一个组合组件推荐版本原因JDK1.8即 Java 8很多老项目编译级别是 1.8JDK 17 编译老代码会包访问错误Tomcat8.5 或 9.0支持 Servlet 3.1/4.0兼容绝大多数课程设计项目MySQL5.7 或 8.05.7 最稳8.0 需要改驱动和时区参数IDEA2021 以上均可社区版也够用这组搭配是“最不踩坑”的。JDK 11 或 17 上跑老 Servlet 项目不是绝对不行但你会遇到 javax.servlet 包名变化、JSP 编译失败等问题对新手来说排查成本太高。Tomcat 10 也别用因为 Tomcat 10 把 javax.servlet 替换成了 jakarta.servlet这类老项目里的 import 全部会标红。提示换发 Tomcat 版本前先看项目里 web.xml 的 xmlns 声明Servlet 2.5 和 4.0 的写法差别很大强行兼容会报各种你以为的“玄学”错误。3.2 导入源码与 IDEA 里 JavaWeb 项目配置的 6 个检查点在 IDEA 里启动前端和后端最核心的是一个概念你运行的并不只是某个 java 文件而是一个“Web 应用”。IDEA 需要把你的 JSP、Servlet、依赖 jar 包组装成一个 Web Application再扔给 Tomcat 运行。下面这 6 个检查点是每次换项目都必看的第一确认导入方式。用 IDEA 的File - New - Project from Existing Sources选中解压目录如果项目里有 pom.xml选 Maven如果只有 .classpath/.project 是 Eclipse 风格选 Eclipse 导入后马上关掉自动下载改用 Add Framework Support 手动补 Web 能力。第二确认源码目录标记。右键 src 目录Mark Directory as - Sources Root右键 web 或 WebRoot 目录如果没被识别为 Web Resource Root 则手动标记。这一步错了IDEA 会把 JSP 当普通文件Tomcat 部署后访问不到页面。第三打开File - Project Structure - Facets选中项目点加号添加Web项。这是 IDEA 识别“这是一个 JavaWeb 项目”的关键一步。Web Facet 配置界面里要把 Web Resource Directory 指向 web 或 WebRootWeb Resource Prefix 留空即可。第四在同一个Project Structure面板里进Artifacts点加号选Web Application: Exploded。这一步的作用是告诉 Tomcat 部署时要打包哪些文件。如果 Artifacts 列表为空后面 Run 配置里根本没有可用的 Deployment 项这种情况启动后会直接报“没有部署目标”或启动完 404。第五添加依赖 jar 包。右键项目选Open Module Settings进Libraries把项目里带的 lib 目录或解压后的 jar 包加入如果项目是 Maven 管理等 Maven 同步完即可。老式 Web 项目的 lib 包通常放在 web/WEB-INF/lib 下必须让 IDEA 把它们识别为 Library否则编译时会报 ClassNotFoundException。第六配置 Tomcat。打开Run - Edit Configurations - 加号 - Tomcat Server - Local在Deployment页签点加号选Artifact把前面建的那个 Artifact 挂上去。Application context 一般填/book或/取决于项目原本部署名。这里有个血泪经验Application context 填什么浏览器访问地址就是什么要和代码里的根路径配置保持一致。3.3 修改数据库配置并把项目启动起来环境配置好之后改数据库连接参数。用 IDEA 打开src下的db.properties或jdbc.properties确认 2.3 节里四个参数和本地 MySQL 的实际账号密码一致。注意 UTF-8 编码如果 IDEA 打开文件乱码去Settings - File Encodings里把全局和项目编码都设为 UTF-8再顺手把右下角默认编码也改了。数据库验证用一个小工具类跑通比直接把项目丢给 Tomcat 更快import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class TestDb { public static void main(String[] args) throws Exception { Class.forName(com.mysql.jdbc.Driver); String url jdbc:mysql://localhost:3306/book?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai; Connection conn DriverManager.getConnection(url, root, 123456); Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(SELECT COUNT(*) FROM book); rs.next(); System.out.println(book 表的记录数 rs.getInt(1)); conn.close(); } }Class.forName这行是在加载驱动JDBC 3.0 之前必需。DriverManager.getConnection三个参数分别是 URL、用户名、密码。Statement适合执行单条 SQL这里只用来验证连接项目正式代码里应该用预处理PreparedStatement防 SQL 注入。控制台打印出记录数说明数据库没问题。接着启动 Tomcat点运行。看到控制台出现“Tomcat started on port(s): 8080”后浏览器访问http://localhost:8080/项目名/一般会跳到登录页。用项目 SQL 文件里预设的用户名密码登录正常能进管理页面。验证的标准动作是新增一本图书然后去列表页看是否出现。列表能出现、重启 Tomcat 后数据还在说明前后端和数据库三个环节全部打通了。4. 读核心代码登录、借还书、分页查询这三段逻辑的价值4.1 登录与会话拦截Servlet 的职责边界打开源码先读登录相关代码它决定了这个系统“谁在用”。Servlet 的核心职责是解析 HTTP 参数、调用业务层、把结果送到页面。下面是简化后的常见写法WebServlet(/login) public class LoginServlet extends HttpServlet { Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username req.getParameter(username); String password req.getParameter(password); UserService service new UserService(); User user service.checkLogin(username, password); if (user ! null) { HttpSession session req.getSession(); session.setAttribute(loginUser, user); resp.sendRedirect(req.getContextPath() /book/list); } else { req.setAttribute(errMsg, 用户名或密码错误); req.getRequestDispatcher(/login.jsp).forward(req, resp); } } }WebServlet(/login)是 Servlet 3.0 之后注解式映射省掉了 web.xml 里的servlet配置。req.setAttribute存的是请求范围内的参数转发到 JSP 后可以用${errMsg}取出resp.sendRedirect是重定向走到这行说明登录成功地址栏变化为图书列表页。这里最容易混的是“转发”和“重定向”的区别登录失败用 forward保持地址栏在 login 上并可携带 request 里的错误信息登录成功用 sendRedirect否则刷新页面会重复提交表单。业务判定被放在UserService.checkLogin()里Service 内部再调用 DAO 查数据库。这个链条看着绕但好处是以后把密码做 MD5 加密只改 Service 一处不用动 JSP 和数据库表。拦截逻辑常见的是配一个 Filter 或直接在每个 JSP 页面顶部做 session 判断。Filter 方式更干净WebFilter(/*) public class LoginFilter implements Filter { Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpSession session request.getSession(false); String uri request.getRequestURI(); boolean isLoginPage uri.endsWith(login.jsp) || uri.endsWith(/login); if (session null || session.getAttribute(loginUser) null) { if (isLoginPage) { chain.doFilter(req, resp); } else { ((HttpServletResponse) resp).sendRedirect(request.getContextPath() /login.jsp); } } else { chain.doFilter(req, resp); } } }request.getSession(false)表示不主动给匿名访问者创建 Session拿不到说明未登录。白名单写死在isLoginPage里登录页和登录接口放行其余地址要求已登录。这段代码新手常踩的坑是把静态资源 CSS、JS 也拦截了导致登录页样式全丢判断里需要加上/css/、/js/放行。4.2 借书还书事务边界到底画在哪图书管理系统的核心业务是借书和还书。借书在数据库层面要做两件事把 book 表的 state 字段从 0 改成 1再往 borrow 表插一条记录。这两步必须在一个事务里完成——如果只把书改成了“已借出”而借阅记录没插上书就凭空消失了。常见实现public void borrowBook(int bookId, int userId) { String sqlUpdate UPDATE book SET state 1 WHERE id ? AND state 0; String sqlInsert INSERT INTO borrow(book_id, user_id, borrow_date) VALUES(?, ?, NOW()); try (Connection conn DataSourceUtils.getConnection()) { conn.setAutoCommit(false); try (PreparedStatement ps1 conn.prepareStatement(sqlUpdate); PreparedStatement ps2 conn.prepareStatement(sqlInsert)) { ps1.setInt(1, bookId); ps1.setInt(2, userId); if (ps1.executeUpdate() ! 1) { throw new SQLException(图书不存在或已被借出); } ps2.setInt(1, bookId); ps2.setInt(2, userId); ps2.executeUpdate(); conn.commit(); } catch (SQLException e) { conn.rollback(); throw new RuntimeException(借书失败已回滚, e); } finally { conn.setAutoCommit(true); } } catch (SQLException e) { throw new RuntimeException(e); } }setAutoCommit(false)是事务开启JDBC 默认每条 SQL 自动提交必须关掉才能让两条 SQL 同生共死。UPDATE ... WHERE id? AND state0是典型的乐观锁防并发下两个管理员同时借同一本书——只有 state 还是 0可借时更新才成功executeUpdate()返回值不是 1 就直接抛异常回滚。try-with-resources保证 PreparedStatement 和 Connection 一定会关闭。这段代码看懂后还书就反过来写UPDATE 把 state 改回 0UPDATE borrow 表把 return_date 写成 NOW()逻辑对称。4.3 分页查询LIMIT 两个参数和总数查询图书列表页不写分页随着录书数据增多页面越来越慢而且一次性把几百条记录塞进 JSP数据库和浏览器都不舒服。分页常见用 MySQL 的 LIMIT 语法int pageSize 10; int page Integer.parseInt(request.getParameter(page)); int offset (page - 1) * pageSize; ListBook list bookDao.findPage(offset, pageSize); int totalCount bookDao.countAll(); int totalPages (int) Math.ceil(totalCount * 1.0 / pageSize);DAO 里的查询SELECT * FROM book ORDER BY id DESC LIMIT ?, ?;第一个?是 offset偏移量第二个?是 pageSize每页条数。第一页 offset0第二页 offset10第 N 页 offset(N-1)*pageSize。总数查询单独执行一条SELECT COUNT(*) FROM book可以在 JSP 里用两个数算总页数也可以直接 SQL 算出来SELECT CEIL(COUNT(*)/10) FROM book。这里注意LIMIT ?, ?不能用字符串拼接必须用 PreparedStatement 的 setInt 绑定参数否则就是 SQL 注入点。分页查询结果放进 request 后在 JSP 里用c:forEach循环表格行再在底部输出上一页/下一页链接这就是完整的分页闭环。如果你的 MySQL 版本是 5.5 以后的LIMIT 两个参数都支持无需考虑旧的LIMIT offset, count兼容性问题。5. javaweb 图书管理系统跑不起来了这里有 5 条高频踩坑记录5.1 404Tomcat 能启动访问不了页面现象IDEA 控制台显示 Tomcat started但浏览器访问http://localhost:8080/book/报 404。原因最常见的是 Artifact 没挂到 Deployment 上或者 Application context 路径填的和访问路径不一致。另一个高发原因是 JSP 页面明明在 web 目录却因为 Web Facet 没配置IDEA 没有把 jsp 拷贝进 Tomcat 的 app 目录。解决打开Run - Edit Configurations - Tomcat Server - Deployment确认有 Artifact 且 Application context 是/book到项目的 target或 out目录看看有没有把 jsp、WEB-INF 都生成出来。没有就回第 3.2 节重新检查 Facets 和 Artifacts 两项。5.2 Access denied for user rootlocalhost现象项目日志里报 java.sql.SQLException: Access denied for user rootlocalhost (using password: YES)。原因数据库连接配置里的密码和本地 MySQL 的 root 密码不一致。很多课程设计项目的压缩包里默认写了 123456你本机可能不是这个密码甚至连 root 账号都因为安装时选择过密码校验策略而带上了特殊字符。解决用本地能用的密码改掉db.properties里的jdbc.password。如果忘记 root 密码本身临时改 MySQL 的 root 密码后再回填。这里注意有些授权脚本会创建单独账号比如CREATE USER booklocalhost IDENTIFIED BY book123;那就把配置改成这个专门账号别用 root 硬扛。5.3 插入的书名全是问号现象页面上输入中文书名提交后列表里显示????????英文正常。原因数据库表字符集是拉丁的或者 JDBC URL 里没有带characterEncodingutf8。前者是建库时的历史问题后者是配置文件问题。解决命令行执行ALTER DATABASE book CHARACTER SET utf8mb4;再去把表也改一遍ALTER TABLE book CONVERT TO CHARACTER SET utf8mb4;。配置里补上useUnicodetruecharacterEncodingutf8。改完重启 Tomcat重插一条测试数据。这个问题最大的迷惑性是直接在 Navicat 里能看到中文但通过 Java 程序插入就是问号原因就是 JDBC 连接层没声明编码。5.4 换机到别人电脑运行就报 404现象同一个项目在自己电脑上跑得好好的发给同学在他的 IDEA 里就起不来报 JSP 编译错误或找不到页面。原因项目里的 web.xml 或代码中写死了绝对路径比如http://localhost:8080/book/...里的book是原作者的部署名换一台机器项目名变了路径就断了。解决全代码搜索contextPath或写死的项目名尽量把路径改成${pageContext.request.contextPath}动态获取。Tomcat 的 Application context 在另一台机器也别随意改保持/book或按项目原来部署名来。这是 JavaWeb 项目维护里最经典的一个“玄学”问题其实只是部署名约定不一致。5.5 驱动版本不匹配导致的 Connection 报错现象日志出现ClassNotFoundException: com.mysql.jdbc.Driver或Communications link failure。原因驱动包放错位置。lib 里的 jar 包没被 IDEA 加入 Artifact编译能过因为代码区引用了但运行时 lib 没打进去。另一个可能是驱动的 class 路径不一致——MySQL 5 驱动包和 MySQL 8 驱动包的类名不一样。解决先在Project Structure - Libraries里确认驱动 jar 存在再检查 WEB-INF/lib 或 Artifact 输出目录里有没有 jar。最后看驱动类名com.mysql.jdbc.Driver是旧版com.mysql.cj.jdbc.Driver是 8.x如果报错信息和驱动类名对不上把 db.properties 里 driver 换成对应的。6. 跑通之后怎么改从换数据库到拆前后端这个 javaweb 项目还能再进阶6.1 换数据库从 MySQL 切到达梦或 PostgreSQL 有哪些改动很多人问“能否把这个项目的数据库换成国产库或别的库”答案是可以但有两处必改第一JDBC 驱动 jar 换成目标数据库的驱动包第二db.properties 里的jdbc.driver和jdbc.url改写。比如换成达梦数据库驱动类通常是dm.jdbc.driver.DmDriverURL 是jdbc:dm://localhost:5236/book分页 SQL 里的LIMIT ?,?可能就不能用了需要改成对应数据库的写法。这个步骤最大的价值是让你意识到项目里 SQL 写得太特化换库就疼。早年我没注意这点把LIMIT和NOW()这种 MySQL 专用语法当标准用后来换个数据库改了一整晚血泪教训。我的建议是如果只是练手先不急着换库留着 MySQL 把借阅功能跑透等你想做稍正式的课设答辩再把数据库层改成通用 DAOSQL 抽到 mapper 里扩散面才会小。6.2 加功能在现有 JavaWeb 分层结构中加“图书预约”掌握了结构以后可以给自己布置一个小任务加一个“图书预约”模块。流程是用户点击预约按钮生成一条预约记录管理员审批后转为可以借阅。加表是第一步CREATE TABLE reserve ( id INT PRIMARY KEY AUTO_INCREMENT, book_id INT NOT NULL, user_id INT NOT NULL, status TINYINT DEFAULT 0 COMMENT 0待处理 1已通过 2已取消, create_time DATETIME, FOREIGN KEY (book_id) REFERENCES book(id), FOREIGN KEY (user_id) REFERENCES user(id) );然后照着 4.1 和 4.2 的节奏写 ReserveDao 的 insert 和 update 方法、ReserveService 的业务判断、ReserveServlet 接收参数、reserve.jsp 做展示。这个练习能验证你有没有真正掌握“分层”这个核心思想。如果你能在手写代码的情况下说出“新功能从数据表到页面的完整调用链”这套源码就算吃透了。6.3 拆前后端保留 Servlet 后端把 JSP 替换成 HTML fetch如果学到这里还不过瘾可以试着把前端拆出去JSP 留着只做登录列表页全换成静态 HTML用fetch调用后端接口。后端 Servlet 统一改成返回 JSON设置响应头和 JSON 输出resp.setContentType(application/json;charsetutf-8); ObjectMapper mapper new ObjectMapper(); mapper.writeValue(resp.getWriter(), resultMap);前端这样拿数据fetch(/book/listJson) .then(res res.json()) .then(data { if (data.code 200) { renderTable(data.rows); } });这个改造过程不用引 Vue 或 React 这种大框架也能感受到前后端分离的接口约定是什么。注意跨域问题如果前端静态文件用 8080 端口后端也跑 8080 就没跨域如果前端用file://打开或单独起一个 3000 端口Servlet 侧要加 CORS 响应头否则浏览器的 preflight 请求会把你卡在半路。这套源码消化到这个程度你再遇到别的 javaweb 项目基本都能十分钟理顺先看数据库脚本再看配置文件最后一个一个查 Servlet 映射。我自己的习惯就是先导数据库后读连接配置顺序对了什么项目都能在两小时内跑出来。希望这些参数、坑和改法能帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。