ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Java Web育儿助手系统:JSP+MySQL+Tomcat毕设实战项目

Java Web育儿助手系统:JSP+MySQL+Tomcat毕设实战项目 简介本资源是一份面向计算机专业本科生的Java Web毕业设计项目文档聚焦现代育儿场景下的信息化服务需求为初学者提供可运行、易理解的完整系统实现方案。文档详细阐述了基于JSPJavaMySQL技术栈构建的育儿助手系统涵盖用户端育儿知识浏览、资讯获取、论坛互动、智能问答、个人中心与管理端资讯/轮播/用户/知识/论坛/问答等全维度后台管理双模块设计逻辑与功能实现要点。资源为1个3.82MB的Word文档.doc格式内容包含开题背景、系统分析、数据库设计、核心代码说明、界面截图及中英文摘要等典型毕设要素结构规范、排版清晰适合作为课程设计参考、答辩材料模板或二次开发基础。目前已有200人学习下载对掌握JSP动态网页开发、MySQL数据建模及Java后端业务整合具有较强实践指导价值。1. 基于Web育儿助手系统一个能跑通、能部署、能答辩的Java毕业设计实战项目这不是一个“概念演示”或“PPT系统”。它是一套真实可运行、带完整前后端交互、含管理员后台与用户前台、数据库表结构清晰、JSP页面逻辑闭环、连Tomcat启动报错都能定位到具体行号的本科级Java Web毕业设计落地包。我去年帮3个同学调试过这个项目——有人卡在MySQL中文乱码有人死在JSP EL表达式语法错误还有人把web.xml里servlet-mapping路径写成/login.jsp而不是/login导致404刷屏。它解决的不是“有没有”而是“能不能上线”首页轮播图能换、育儿知识能增删、论坛帖子能发、智能问答能查库返回、投诉建议能存进MySQL并被管理员看到。技术栈干净利落JSP非Servlet裸写有MVC雏形、JavaJDBC直连无Spring Boot遮掩适合答辩讲清流程、MySQL 5.7建表含外键、索引、中文字段、B/S架构Chrome/Firefox直输http://localhost:8080/baby/即进首页。适合两类人一是大四赶毕设 deadline 的同学需要一份不踩坑、不翻车、能本地跑通、能导出war包、能应对老师现场提问的实操资源二是刚学完JDBC和JSP想练手的初学者它比“学生选课系统”更贴近生活场景比“图书管理系统”多出论坛、问答、轮播等真实模块代码量适中核心JSP页28个Java类19个SQL脚本1份改起来不晕讲起来有料。2. 技术选型与环境搭建为什么是JSPMySQLTomcat而不是Spring Boot2.1 JSP不是过时技术而是毕业设计的“可控性锚点”很多人看到JSP第一反应是“淘汰了”。但对本科毕设而言JSP恰恰是最可控的技术选择。原因有三调试链路极短JSP修改 → 保存 → 刷新浏览器错误直接打在页面上如org.apache.jasper.JasperException: Unable to compile class for JSP你能立刻看到哪行EL表达式写错、哪个JavaBean没import而Spring Boot改个Controller要重启、看日志、查端口冲突新手容易陷入“改了但没生效”的玄学状态。MVC边界清晰本项目虽未用Struts但已自然分层——JSP负责展示% %取值、c:forEach遍历、JavaBean封装数据User.java,Post.java、Servlet处理请求LoginServlet.java,AddPostServlet.java、DAO操作数据库UserDAO.java。答辩时老师问“怎么实现登录验证”你指着LoginServlet.doPost()里userDAO.findByUsernameAndPassword()这行代码再讲JDBC连接池配置逻辑扎实不空洞。教学资源丰富Eclipse Tomcat MySQL组合B站搜“JSP学生管理系统”有上千个带语音的实操视频遇到ClassNotFoundException: com.mysql.cj.jdbc.Driver你知道该去WEB-INF/lib下放mysql-connector-java-8.0.33.jar而Spring Boot的application.yml配错新手常卡在YAML缩进或spring.datasource.url里时区参数漏写。提示本项目JSP使用JSTL 1.2c:if、c:forEach需在WEB-INF/lib中放入jstl-1.2.jar和standard-1.1.2.jar。若用Tomcat 9注意JSTL版本兼容性——Tomcat 9默认支持JSP 2.3JSTL 1.2完全可用无需升级到JSTL 1.3。2.2 MySQL 5.7选它不是因为“新”而是因为“稳”和“好教”项目摘要里写“MySQL数据库”但没指定版本。实测发现MySQL 5.7.44 是本项目的黄金版本。原因如下字符集开箱即用安装时勾选utf8mb4而非旧版utf8建库语句CREATE DATABASE baby CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;后续所有表自动继承彻底规避“育儿知识”四个字存进数据库变????的血泪问题。权限管理够用不复杂毕设只需一个baby_user账号赋予baby.*库的SELECT,INSERT,UPDATE,DELETE权限即可。命令就一行CREATE USER baby_userlocalhost IDENTIFIED BY baby123; GRANT SELECT,INSERT,UPDATE,DELETE ON baby.* TO baby_userlocalhost; FLUSH PRIVILEGES;不像MySQL 8.0强制caching_sha2_password插件新手配JDBC URL时得加?serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue一长串参数极易出错。工具链成熟Navicat for MySQL 15、MySQL Workbench 8.0、甚至DOS下的mysql -u root -p都能无缝连接。导入SQL脚本时Navicat右键“运行SQL文件”比命令行source baby.sql更直观适合答辩前快速重装数据库。2.3 Tomcat 8.5毕业设计的“安全区”服务器为什么不用Tomcat 10因为Tomcat 10全面转向Jakarta EE 9所有javax.*包名改为jakarta.*如javax.servlet.http.HttpServlet→jakarta.servlet.http.HttpServlet而本项目所有Servlet仍用javax——这是JSP规范在Java EE 8时代的标准写法。Tomcat 8.5.94最新8.5.x版完美兼容支持JSP 2.3、Servlet 3.1、EL 3.0覆盖项目全部语法内存占用低Win10下启动仅占300MB内存老笔记本也能跑conf/server.xml里Connector port8080直接暴露端口无需反向代理本地测试零配置。部署时将项目根目录含WEB-INF文件夹整个拖进webapps/下重命名为baby启动Tomcat后访问http://localhost:8080/baby/index.jsp即进首页。若遇404先检查webapps/baby/WEB-INF/web.xml是否存在再确认welcome-file-list里是否为welcome-fileindex.jsp/welcome-file。2.4 B/S架构不是“为了用而用”而是解决真实部署痛点本项目坚持B/SBrowser/Server而非C/SClient/Server核心动因是降低交付与演示门槛学生交毕设老师不想装客户端答辩现场换电脑只要浏览器就能打开管理员后台/admin/路径无需额外登录态维护全靠Sessionrequest.getSession().setAttribute(admin, admin)关浏览器即退出安全又省事所有静态资源CSS/JS/图片放在webapps/baby/static/下路径硬编码为/baby/static/css/style.css避免相对路径../css/style.css在不同层级JSP中失效。注意B/S意味着所有业务逻辑在服务端。例如“智能问答”模块用户输入关键词JSP提交到SearchServletServlet调KnowledgeDAO.searchByKeyword(keyword)查MySQL再把结果List传回JSP用c:forEach展示——没有前端JavaScript发AJAX没有Vue响应式纯服务端渲染。这正是答辩时老师想听的“数据从哪来怎么查怎么传怎么显”3. 核心功能实现从注册登录到智能问答每一步都附可运行代码3.1 用户注册与登录Session JDBC 密码MD5三步闭环注册流程不是简单存表而是包含数据校验、密码加密、唯一性约束三重保障。关键代码在RegisterServlet.java// RegisterServlet.java protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username request.getParameter(username).trim(); String password request.getParameter(password); String email request.getParameter(email).trim(); // 1. 前端校验JSP中已有onsubmitreturn validateForm()此处二次校验 if (username.length() 3 || username.length() 16) { request.setAttribute(error, 用户名长度3-16位); request.getRequestDispatcher(register.jsp).forward(request, response); return; } if (!email.matches(^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\\.[a-zA-Z]{2,}$)) { request.setAttribute(error, 邮箱格式不正确); request.getRequestDispatcher(register.jsp).forward(request, response); return; } // 2. 密码MD5加密使用commons-codec-1.15.jar String encryptedPassword DigestUtils.md5Hex(password); // 3. 调用DAO检查用户名是否已存在 UserDAO userDAO new UserDAO(); if (userDAO.findByUsername(username) ! null) { request.setAttribute(error, 用户名已被注册); request.getRequestDispatcher(register.jsp).forward(request, response); return; } // 4. 创建User对象并插入 User user new User(); user.setUsername(username); user.setPassword(encryptedPassword); user.setEmail(email); user.setRegTime(new Date()); userDAO.insert(user); // 执行INSERT INTO user VALUES(...) request.setAttribute(msg, 注册成功请登录); request.getRequestDispatcher(login.jsp).forward(request, response); }逻辑说明与参数说明DigestUtils.md5Hex(password)使用Apache Commons Codec库比手写MessageDigest简洁且commons-codec-1.15.jar已放入WEB-INF/libuserDAO.findByUsername(username)DAO层执行SELECT * FROM user WHERE username ?查到记录即返回User对象否则返回nullrequest.getRequestDispatcher(xxx.jsp).forward()服务端跳转URL不变request域中属性如error、msg可被目标JSP获取关键避坑点username.trim()防止用户输空格注册email.matches(...)正则确保邮箱基础格式数据库user.username字段设为UNIQUE索引双重防重。登录逻辑在LoginServlet.java核心是比对MD5密码// LoginServlet.java User user userDAO.findByUsernameAndPassword(username, DigestUtils.md5Hex(password)); if (user ! null) { // 登录成功存入Session HttpSession session request.getSession(); session.setAttribute(user, user); // 后续所有页面可通过${sessionScope.user.username}取值 response.sendRedirect(index.jsp); // 重定向避免F5刷新重复提交 } else { request.setAttribute(error, 用户名或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); }提示response.sendRedirect()是重定向URL变为/baby/index.jsprequest.getRequestDispatcher().forward()是转发URL保持/baby/login。登录成功必须用重定向否则用户刷新login.jsp会再次提交表单。3.2 育儿知识管理CRUD全链路含分页与分类管理员后台的“育儿知识管理”是典型CRUD模块但增加了按分类筛选、按发布时间倒序、分页显示三个实用功能。KnowledgeListServlet.java负责列表页// KnowledgeListServlet.java protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int page 1; int pageSize 10; String currentPage request.getParameter(page); if (currentPage ! null !currentPage.isEmpty()) { page Integer.parseInt(currentPage); } String category request.getParameter(category); // 分类筛选如新生儿 KnowledgeDAO knowledgeDAO new KnowledgeDAO(); // 1. 查询总记录数用于分页计算 int totalCount knowledgeDAO.getTotalCount(category); // 2. 查询当前页数据 ListKnowledge knowledgeList knowledgeDAO.findByPage(category, (page-1)*pageSize, pageSize); // 3. 计算总页数 int totalPage (int) Math.ceil((double) totalCount / pageSize); // 4. 将数据存入request域 request.setAttribute(knowledgeList, knowledgeList); request.setAttribute(page, page); request.setAttribute(totalPage, totalPage); request.setAttribute(totalCount, totalCount); request.setAttribute(category, category); request.getRequestDispatcher(/admin/knowledge_list.jsp).forward(request, response); }DAO层关键SQLKnowledgeDAO.java// 查询总数带分类条件 public int getTotalCount(String category) { String sql SELECT COUNT(*) FROM knowledge WHERE 11; if (category ! null !category.isEmpty()) { sql AND category ?; } try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { if (category ! null !category.isEmpty()) { ps.setString(1, category); } ResultSet rs ps.executeQuery(); if (rs.next()) { return rs.getInt(1); } } catch (SQLException e) { e.printStackTrace(); } return 0; } // 分页查询MySQL写法 public ListKnowledge findByPage(String category, int offset, int limit) { String sql SELECT * FROM knowledge WHERE 11 ORDER BY create_time DESC LIMIT ?, ?; if (category ! null !category.isEmpty()) { sql SELECT * FROM knowledge WHERE category ? ORDER BY create_time DESC LIMIT ?, ?; } // ... 执行查询封装为ListKnowledge }JSP分页HTMLknowledge_list.jsp!-- 分页导航 -- div classpagination c:if test${page 1} a hrefknowledge_list?page${page-1}${empty param.category ? : categoryparam.category}laquo; 上一页/a /c:if c:forEach begin1 end${totalPage} vari c:choose c:when test${i page} span classcurrent${i}/span /c:when c:otherwise a hrefknowledge_list?page${i}${empty param.category ? : categoryparam.category}${i}/a /c:otherwise /c:choose /c:forEach c:if test${page totalPage} a hrefknowledge_list?page${page1}${empty param.category ? : categoryparam.category}下一页 raquo;/a /c:if /div参数说明offset (page-1)*pageSizeMySQL分页起点第1页从0开始第2页从10开始LIMIT ?, ?预编译占位符防SQL注入${empty param.category ? : categoryparam.category}JSTL三元运算保留分类筛选参数点击页码不丢失筛选条件classcurrentCSS高亮当前页提升管理体验。3.3 智能问答模块不是AI而是关键词模糊匹配的轻量级实现标题叫“智能问答”实际是基于MySQL全文索引的LIKE模糊搜索符合本科毕设定位——不吹嘘大模型但功能真实可用。SearchServlet.java核心逻辑// SearchServlet.java String keyword request.getParameter(keyword).trim(); if (keyword.isEmpty()) { request.setAttribute(error, 请输入搜索关键词); request.getRequestDispatcher(search.jsp).forward(request, response); return; } // 使用MySQL全文索引需提前在knowledge表title,content字段建FULLTEXT索引 // ALTER TABLE knowledge ADD FULLTEXT(title, content); String sql SELECT * FROM knowledge WHERE MATCH(title, content) AGAINST(? IN NATURAL LANGUAGE MODE) ORDER BY MATCH(title, content) AGAINST(?) DESC; // 若未建全文索引则降级为LIKE // String sql SELECT * FROM knowledge WHERE title LIKE ? OR content LIKE ? ORDER BY create_time DESC; ListKnowledge results new ArrayList(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, keyword); ps.setString(2, keyword); ResultSet rs ps.executeQuery(); while (rs.next()) { Knowledge k new Knowledge(); k.setId(rs.getInt(id)); k.setTitle(rs.getString(title)); k.setContent(rs.getString(content).substring(0, Math.min(200, rs.getString(content).length())) ...); k.setCategory(rs.getString(category)); results.add(k); } } catch (SQLException e) { // 降级处理若全文索引报错改用LIKE sql SELECT * FROM knowledge WHERE title LIKE ? OR content LIKE ? ORDER BY create_time DESC; // ... 重新执行 } request.setAttribute(results, results); request.setAttribute(keyword, keyword); request.getRequestDispatcher(search_result.jsp).forward(request, response);建全文索引SQL执行一次即可ALTER TABLE knowledge ADD FULLTEXT(title, content); -- 验证是否生效SHOW INDEX FROM knowledge;优势与边界MATCH...AGAINST比LIKE %keyword%快10倍以上尤其数据量超千条时IN NATURAL LANGUAGE MODE支持相关性排序搜索“发烧”时“宝宝发烧怎么办”排在“儿童发烧物理降温”前面不依赖外部API纯数据库能力答辩时可演示EXPLAIN SELECT ...证明性能若老师问“为什么不是真正AI”可答“本模块聚焦信息检索效率全文索引是MySQL原生高性能方案避免引入Python或调用第三方API带来的部署复杂度符合B/S架构轻量级原则。”3.4 论坛发帖与回复一对多关系的JSP实现论坛模块体现数据库设计功底。post表主贴与reply表回复是典型一对多外键reply.post_id指向post.id。发帖JSPadd_post.jsp提交到AddPostServlet// AddPostServlet.java String title request.getParameter(title); String content request.getParameter(content); int userId ((User) request.getSession().getAttribute(user)).getId(); Post post new Post(); post.setTitle(title); post.setContent(content); post.setUserId(userId); post.setCreateTime(new Date()); PostDAO postDAO new PostDAO(); int postId postDAO.insert(post); // 返回自增ID // 发帖成功后重定向到该贴详情页 response.sendRedirect(post_detail.jsp?id postId);post_detail.jsp同时加载主贴和所有回复!-- 主贴 -- div classpost-detail h2${post.title}/h2 p classpost-meta作者${post.userName} | 发布时间${post.createTime}/p div classpost-content${post.content}/div /div !-- 回复列表 -- div classreplies h3共 ${fn:length(replies)} 条回复/h3 c:forEach items${replies} varreply div classreply-item pstrong${reply.userName}/strong${reply.content}/p p classreply-time${reply.createTime}/p /div /c:forEach /div !-- 回复表单 -- form actionAddReplyServlet methodpost input typehidden namepostId value${param.id} textarea namecontent placeholder写下你的回复... required/textarea button typesubmit提交回复/button /formDAO层关联查询PostDAO.java// 查询主贴及所有回复一次SQL避免N1 public Post findWithReplies(int postId) { String sql SELECT p.*, u.username as userName, r.id as reply_id, r.content as reply_content, r.create_time as reply_time, ru.username as reply_user_name FROM post p LEFT JOIN user u ON p.user_id u.id LEFT JOIN reply r ON p.id r.post_id LEFT JOIN user ru ON r.user_id ru.id WHERE p.id ? ORDER BY r.create_time ASC; // ... 执行手动组装Post对象及ListReply }注意LEFT JOIN确保无回复的帖子也能显示ORDER BY r.create_time ASC让回复按时间正序排列最早回复在最前JSP中${fn:length(replies)}需在页面顶部声明% taglib prefixfn urihttp://java.sun.com/jsp/jstl/functions %。4. 避坑指南那些让答辩前夜崩溃的12个真实问题与解法4.1 中文乱码从数据库到JSP五层防线全解析现象MySQL里存的是“新生儿护理”网页显示“æ–°ç”或表单提交“张三”数据库存成“å¼ ä¸‰”。原因乱码是字符集传递链断裂涉及5个环节MySQL服务器默认字符集character_set_server数据库/表字符集CREATE DATABASE ... CHARACTER SET utf8mb4JDBC连接URL参数?characterEncodingutf8mb4Tomcatserver.xmlConnector的URIEncodingUTF-8JSP页面编码声明% page contentTypetext/html;charsetUTF-8 %解决步骤1MySQL命令行执行SHOW VARIABLES LIKE character_set_%;确保character_set_serverutf8mb4步骤2建库时明确指定CREATE DATABASE baby CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;步骤3DBUtil.java中JDBC URL写全private static final String URL jdbc:mysql://localhost:3306/baby?useUnicodetruecharacterEncodingutf8mb4serverTimezoneAsia/Shanghai;步骤4conf/server.xml中Connector标签加属性Connector port8080 protocolHTTP/1.1 URIEncodingUTF-8 ... /步骤5每个JSP顶部第一行必须是% page languagejava contentTypetext/html; charsetUTF-8 pageEncodingUTF-8%缺一不可。曾有同学只改了JSP忘了改server.xml导致GET请求URL参数仍乱码。4.2 JSP EL表达式不解析不是语法错是web.xml版本惹的祸现象JSP里写% user.username %能显示但c:out value${user.username}/或${user.username}直接原样输出字符串。原因EL表达式默认在JSP 2.0启用但若web.xml头声明为Servlet 2.3旧版EL会被禁用。解决检查webapps/baby/WEB-INF/web.xml顶部声明!-- ✅ 正确Servlet 3.0EL默认开启 -- 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若看到version2.3或http://java.sun.com/dtd/web-app_2_3.dtd立即替换为上方3.1版本声明。Tomcat 8.5完全兼容。4.3 Tomcat启动失败端口被占、JAR冲突、JDK版本三杀现象双击startup.bat无反应或命令行报Address already in use: JVM_Bind、java.lang.UnsupportedClassVersionError。排查三步法端口冲突netstat -ano | findstr :8080Windows或lsof -i :8080Mac/Linux找到PID后taskkill /PID PID /FJAR冲突WEB-INF/lib下若有多个mysql-connector-java-*.jar如5.1和8.0混存删掉旧版只留mysql-connector-java-8.0.33.jarJDK版本错配本项目编译为Java 8javac -source 1.8 -target 1.8若系统装了JDK 17Tomcat会报UnsupportedClassVersionError。解决方案下载JDK 8u202长期支持版设置JAVA_HOME指向JDK 8echo %JAVA_HOME%Windows或echo $JAVA_HOMEMac/Linux确认重启命令行再启Tomcat。4.4 管理员登录404路径大小写与web.xml映射的隐形杀手现象访问http://localhost:8080/baby/admin/提示404但/baby/index.jsp正常。原因文件路径大小写错误webapps/baby/admin/文件夹名写成AdminWindows不敏感Linux敏感web.xml中Servlet映射路径错误url-pattern/admin/login/url-pattern写成url-pattern/Admin/Login/url-patternJSP中链接写死a href/admin/index.jsp应为a href${pageContext.request.contextPath}/admin/index.jsp。解决统一用小写命名所有文件夹和JSPweb.xml中url-pattern全部小写所有JSP内链接用${pageContext.request.contextPath}动态获取上下文路径避免硬编码/baby。4.5 数据库连接失败驱动、URL、权限的铁三角验证现象java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver或Communications link failure。验证清单项目正确值检查方式驱动JARmysql-connector-java-8.0.33.jar确认在WEB-INF/lib/下且无其他版本JDBC URLjdbc:mysql://localhost:3306/baby?useUnicodetruecharacterEncodingutf8mb4serverTimezoneAsia/Shanghai复制到Navicat测试能否连MySQL账号权限baby_user对baby库有SELECT,INSERT,UPDATE,DELETESHOW GRANTS FOR baby_userlocalhost;MySQL服务状态正在运行services.msc中检查“MySQL80”服务是否启动血泪经验曾有同学MySQL服务名为“MySql57”JDBC URL却写localhost:3306实际端口是3307。务必用netstat -ano | findstr :330确认MySQL监听端口。5. 进阶技巧让项目从“能跑”升级为“值得讲”的3个硬核操作5.1 用Log4j2替代System.out.println让调试痕迹变成答辩加分项毕业设计答辩时老师常问“登录失败时你怎么知道是密码错还是用户不存在” 如果回答“我看控制台打印”显得粗糙。换成Log4j2就能说“我配置了日志级别ERROR日志记录异常堆栈WARN日志标记业务异常INFO日志追踪关键流程所有日志按日期滚动归档。”操作步骤下载log4j-api-2.20.0.jar和log4j-core-2.20.0.jar放入WEB-INF/lib/在src/下新建log4j2.xml?xml version1.0 encodingUTF-8? Configuration statusWARN Appenders RollingFile nameFileOut fileNamelogs/baby.log filePatternlogs/baby-%d{yyyy-MM-dd}-%i.log.gz PatternLayout pattern%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n/ Policies TimeBasedTriggeringPolicy / SizeBasedTriggeringPolicy size10 MB/ /Policies DefaultRolloverStrategy max30/ /RollingFile /Appenders Loggers Root levelinfo AppenderRef refFileOut/ /Root /Loggers /Configuration在LoginServlet.java中添加日志private static final Logger logger LogManager.getLogger(LoginServlet.class); // 登录失败时 logger.warn(登录失败用户名[{}]不存在或密码错误, username); // 登录成功时 logger.info(用户[{}]登录成功IP{}, username, request.getRemoteAddr());效果项目根目录生成logs/baby.log内容如14:22:31.882 [http-nio-8080-exec-2] INFO c.b.s.LoginServlet - 用户[zhangsan]登录成功IP127.0.0.1答辩时打开日志文件老师一眼看到“INFO”“WARN”分级立刻感知工程规范性。5.2 为首页轮播图增加JSON接口暴露RESTful能力应对“你会前端吗”灵魂拷问管理员后台可上传轮播图但前台JSP是静态写死img srcstatic/img/banner1.jpg。升级为动态新建BannerServlet.javadoGet()返回JSONprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BannerDAO bannerDAO new BannerDAO(); ListBanner banners bannerDAO.findAll(); // 查询status1的轮播图 response.setContentType(application/json;charsetUTF-8); PrintWriter out response.getWriter(); out.print(new Gson().toJson(banners)); // 用Gson转JSON out.flush(); }index.jsp中用JavaScript调用script fetch(${pageContext.request.contextPath}/banner) .then(response response.json()) .then(data { const carousel document.getElementById(carousel); data.forEach(banner { const item div classcarousel-itemimg src${banner.imageUrl} alt${banner.title}/div; carousel.innerHTML item; }); }); /script价值证明你理解前后端分离思想即使没用Vue也用fetch调接口展示JSON数据交换能力为未来学Ajax打基础接口URL/banner符合RESTful风格比getBannerList.jsp更专业。5.3 用Druid连接池替换DBUtil从“能连”到“高并发”的认知跃迁DBUtil.getConnection()每次创建新连接高并发时会耗尽MySQL连接数。换成Druid能监控连接池状态、自动回收泄漏连接、防止SQL注入。操作WEB-INF/lib/加入druid-1.2.16.jarsrc/druid.propertiesdriverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/baby?useUnicodetruecharacterEncodingutf8mb4 usernamebaby_user passwordbaby123 initialSize5 maxActive20 minIdle5 maxWait60000 timeBetweenEvictionRunsMillis60000 minEvictableIdleTimeMillis300000 validationQuerySELECT 1 testWhileIdletrue testOnBorrowfalse testOnReturnfalse poolPreparedStatementstrue maxPoolPreparedStatementPerConnectionSize20 filtersstat,wallDBUtil.java重构为单例Druidpublic class DBUtil { private static DruidDataSource dataSource; static { Properties props new Properties(); props.load(DBUtil.class.getClassLoader().getResourceAsStream(druid.properties)); dataSource (DruidDataSource) DruidDataSourceFactory.createDataSource(props); } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } }答辩话术“我用了Druid连接池它能自动管理数据库连接比如设置maxActive20保证最多20个并发查询超出的请求排队等待避免MySQL因连接数爆满而拒绝服务。还开启了wall防火墙过滤器能拦截SELECT * FROM user WHERE 11 OR 11本文还有配套的精品资源点击获取
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表