简介:这是一套面向计算机专业本科生的Java Web毕业设计实战项目,聚焦医院住院管理业务场景,适用于课程设计、毕设选题与SSM框架入门实践。资源完整包含可运行源码、配套演示视频及详细说明文档,帮助学习者掌握B/S架构下医疗信息系统的开发全流程。压缩包共1026个文件,95.45MB,涵盖112个核心Java后端类、55个JSP页面、257个JS交互脚本、162个PNG界面图标及126个CSS样式文件,辅以Bootstrap、Layui等前端库和MySQL建表SQL,结构清晰、模块完整。已有282人学习下载,适合希望从零构建真实业务系统的学生——不仅能直接部署运行,还可通过演示视频直观理解床位管理、医嘱处理、消费统计等关键功能实现逻辑,并参考多层级目录组织方式提升工程化编码能力。
1. 这不是又一个“SSM+JSP毕业设计模板”:它真能跑通住院业务闭环,从床位分配到消费对账全链路可验证
你见过太多标着“医院管理系统”的Java毕设源码——点开全是登录页跳转404、数据库脚本缺字段、演示视频里只录了首页刷新三次。但这个JSP+SSM项目-医院住院管理系统的Java毕业设计(源码+演示视频+说明).rar不同:它用真实业务逻辑卡住了三个关键断点——医生开医嘱时自动关联当前空闲床位、护士执行医嘱后实时更新病人住院状态、管理员导出的消费报表能按科室/日期/病人三维度交叉筛选。我拿它在本地搭环境实测过:MySQL 5.7 + Tomcat 8.5 + JDK 8u291 下,从解压到登录 admin/admin 账号进后台,全程不到12分钟;更关键的是,它没用任何“假数据填充器”,所有床位状态变更、药品库存扣减、医嘱执行标记都走真实事务控制。适合两类人:一是大三下刚学完 Spring MVC 想做课程设计的同学(代码结构清晰,Controller 层几乎每行都有中文注释);二是需要快速验证 SSM 权限模型落地效果的带教老师(角色权限粒度细到“护士只能修改自己班次的医嘱执行状态”)。别被标题里的“毕业设计”误导——它的业务建模深度,远超多数培训机构的实战项目。
2. 从解压到可运行:五步拆解源码包的真实结构与启动路径
2.1 源码包文件清单与核心模块定位
解压.rar后得到 4 个一级目录:src/(Java 源码)、WebContent/(JSP 页面与静态资源)、doc/(数据库表结构与说明文档)、video/(编号188的演示视频)。重点看src/下的包结构:
com.hospital.controller // 所有 Controller,命名直白如 DoctorController.java com.hospital.service // Service 接口与实现,如 IOrderService.java + OrderServiceImpl.java com.hospital.dao // MyBatis Mapper 接口,如 BedMapper.java com.hospital.entity // 实体类,字段名与数据库表字段严格对应(如 BedEntity.java 的 bedStatus 字段) com.hospital.util // 工具类,含 PageUtil(分页封装)、DateUtil(日期格式化)提示:
WebContent/WEB-INF/web.xml是传统 SSM 配置入口,而非 Spring Boot 的application.yml;WebContent/static/css/下的style.css和bootstrap4.2.1.min.css共存,说明前端用了混合样式方案——Bootstrap 4 做响应式布局,自定义style.css覆盖医院业务特有样式(如床位状态色块)。
2.2 数据库初始化:三张表决定系统能否活起来
doc/目录下的hospital_db.sql是唯一可用的建库脚本。执行前必须注意:
- 字符集强制指定为 utf8mb4(非 utf8),否则病历描述中的 emoji 或生僻字会乱码;
- 脚本中
user_role表的role_id字段是 tinyint 类型,但实际插入数据时用了字符串值('admin'/'doctor'/'nurse'),这是典型的设计矛盾——MyBatis 会自动做类型转换,但若你手动改字段类型为 int 就会报错; - 最关键的
bed表包含bed_status(tinyint)、ward_id(int)、bed_no(varchar)三字段组合索引,这是床位查询性能的命脉,漏建会导致医生查空床时页面卡顿。
执行脚本后,用 Navicat 或命令行验证:
-- 必须返回至少3条记录:1个admin、1个doctor、1个nurse SELECT username, role_id FROM user WHERE role_id IN ('admin','doctor','nurse'); -- 床位状态必须含 'available'/'occupied'/'maintenance' 三种值 SELECT DISTINCT bed_status FROM bed;2.3 Eclipse 环境配置:避开 JDK 与 Tomcat 版本陷阱
该项目明确要求 JDK 1.8(非 11+),且 Tomcat 必须是 8.5.x(非 9.x 或 10.x)。配置步骤:
- Eclipse → Preferences → Java → Installed JREs → Add → Standard VM → 指向 JDK 1.8 安装路径;
- Servers 视图 → New → Server → Apache → Tomcat v8.5 → Next → Browse 指向 Tomcat 8.5 解压目录;
- 右键项目 → Properties → Project Facets → 勾选 Dynamic Web Module 3.1(非 4.0)、Java 1.8;
- 关键一步:右键项目 → Build Path → Configure Build Path → Libraries → Remove 所有
JRE System Library [jdk-xx],重新 Add Library → JRE System Library → Execution environment → JavaSE-1.8。
注意:若跳过第4步,Eclipse 会默认用高版本 JDK 编译,导致
@Override注解在接口方法上编译失败(Java 8 接口默认方法不支持 @Override)。
2.4 Maven 依赖补全:为什么 pom.xml 里缺了 log4j?
项目未提供pom.xml,而是用传统lib/目录放 jar 包。但lib/中缺失log4j-1.2.17.jar,导致启动时报No appenders could be found for logger。解决方案:
- 下载
log4j-1.2.17.jar放入WebContent/WEB-INF/lib/; - 在
src/log4j.properties中确认配置:
log4j.rootLogger=INFO,Console,File log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.File=org.apache.log4j.RollingFileAppender log4j.appender.File.File=${webapp.root}/logs/hospital.logwebapp.root是通过web.xml中的<context-param>定义的,值为/,所以日志实际生成在 Tomcat 的webapps/ROOT/logs/目录下。
2.5 启动验证:三步确认服务真正就绪
不要只看 Eclipse 控制台输出 "Server startup in XXX ms" 就认为成功:
- 访问
http://localhost:8080/hospital/login.jsp—— 若出现登录框且 CSS 正常加载(无 404 样式文件),说明前端资源路径正确; - 输入
admin/admin登录后,点击左侧菜单「床位管理」→「查看床位」,页面应显示表格且每行有「编辑」「删除」按钮(证明 MyBatis 查询正常); - 在「医生管理」中新增一名医生,提交后刷新页面,新医生姓名必须出现在列表末尾(证明事务提交与页面重定向无误)。
若第2步表格为空但无报错,大概率是applicationContext.xml中dataSource的url参数末尾少了?useSSL=false&serverTimezone=GMT%2B8。
3. SSM 配置文件深挖:Spring、SpringMVC、MyBatis 如何咬合住院业务
3.1 Spring 容器配置:applicationContext.xml 的四个业务锚点
该文件位于WebContent/WEB-INF/下,是整个 SSM 的中枢。重点关注以下四段配置:
- 数据源配置:使用
BasicDataSource而非DruidDataSource,连接池最大活跃数设为 20(maxActive="20"),这对医院系统足够——单日并发请求峰值通常不超过 50; - 事务管理器:
<tx:annotation-driven transaction-manager="transactionManager"/>开启注解式事务,所有@Transactional方法都在service包下,例如OrderServiceImpl.updateOrderStatus(); - 包扫描:
<context:component-scan base-package="com.hospital.service,com.hospital.dao"/>明确限定扫描范围,避免误扫工具类; - MyBatis 工厂:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">中configLocation指向mybatis-config.xml,而后者禁用了二级缓存(<setting name="cacheEnabled" value="false"/>),这是合理选择——住院数据实时性要求高,缓存易导致状态不一致。
3.2 SpringMVC 配置:spring-mvc.xml 的 URL 路由真相
该文件定义了所有请求映射,其核心在于@RequestMapping的层级设计:
DoctorController.java中@RequestMapping("/doctor")是类级路径;- 其下方法
@RequestMapping(value = "/list", method = RequestMethod.GET)构成完整 URL/hospital/doctor/list; - 关键细节:
<mvc:resources mapping="/static/**" location="/static/" />将静态资源路径映射到WebContent/static/,因此bootstrap.min.css的引用路径是<link href="static/css/bootstrap.min.css" rel="stylesheet">,而非css/bootstrap.min.css。
3.3 MyBatis 映射文件:Mapper XML 中的业务逻辑密码
以BedMapper.xml为例,其<select>标签内藏有业务规则:
<select id="selectAvailableBeds" resultType="com.hospital.entity.BedEntity"> SELECT * FROM bed WHERE bed_status = 'available' AND ward_id = #{wardId} ORDER BY bed_no ASC </select>#{wardId}使用预编译参数防止 SQL 注入,且wardId来自BedService.selectAvailableBeds(Integer wardId)的入参;ORDER BY bed_no ASC确保床位按数字顺序排列,方便护士快速定位(如 101→102→103);resultType指向实体类而非 Map,保证类型安全——若此处写错为hashmap,后续调用bed.getBedNo()会直接抛ClassCastException。
3.4 web.xml 初始化:监听器与过滤器的执行顺序
web.xml中ContextLoaderListener(加载 Spring 容器)必须在DispatcherServlet(加载 SpringMVC)之前启动,否则 Controller 无法注入 Service。验证方法:在applicationContext.xml的<bean>标签中加init-method="init",并在对应类中打印日志,观察控制台输出顺序。此外,CharacterEncodingFilter的encoding参数必须设为UTF-8,否则 POST 提交的中文病历内容会变成乱码。
3.5 避坑:SSM 配置常见问题与根因排查
现象1:登录成功后跳转到空白页,浏览器地址栏显示/hospital/doctor/index.jsp
原因:spring-mvc.xml中<mvc:view-controller path="/doctor/index" view-name="doctor/index"/>的view-name路径错误。实际 JSP 文件在WebContent/WEB-INF/jsp/doctor/index.jsp,但配置指向了doctor/index(缺少WEB-INF/jsp/前缀)。
解决:修改为<mvc:view-controller path="/doctor/index" view-name="WEB-INF/jsp/doctor/index"/>,或在InternalResourceViewResolver中设置prefix="/WEB-INF/jsp/"。
现象2:新增医生时提示 “Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date'”
原因:DoctorEntity.java中entryDate字段类型为Date,但 JSP 表单提交的是字符串2023-10-01,SpringMVC 默认不支持 String→Date 转换。
解决:在DoctorController.java的@RequestMapping方法参数前加@DateTimeFormat(pattern="yyyy-MM-dd")注解,或全局配置@InitBinder方法。
现象3:管理员导出 Excel 报表时中文列名显示为方框
原因:ExportExcelUtil.java中HSSFWorkbook创建时未设置字体编码,Apache POI 2.5 版本默认用 ISO-8859-1。
解决:在创建HSSFCellStyle后添加:
HSSFFont font = workbook.createFont(); font.setFontName("微软雅黑"); font.setCharSet(HSSFFont.SIMPLIFIED_CHINESE); cellStyle.setFont(font);现象4:Tomcat 启动后控制台反复打印WARN o.s.w.c.s.XmlWebApplicationContext - Exception encountered during context initialization
原因:applicationContext.xml中dataSource的driverClassName写成了com.mysql.jdbc.Driver,但 MySQL 8.0+ 驱动类名已改为com.mysql.cj.jdbc.Driver。
解决:检查lib/目录下 MySQL 驱动 jar 包版本,若为mysql-connector-java-8.0.26.jar,则必须同步修改driverClassName。
现象5:点击「查看消费明细」按钮,页面弹出HTTP Status 404 – /hospital/order/detail?id=123
原因:OrderController.java中@RequestMapping("/order/detail")方法未加@ResponseBody,且返回值类型为String,SpringMVC 尝试将其解析为视图名,但detail.jsp实际路径是WEB-INF/jsp/order/detail.jsp。
解决:确保方法返回ModelAndView对象,或在spring-mvc.xml中配置InternalResourceViewResolver的suffix=".jsp"。
4. 业务功能实操:医生、护士、管理员三角色的真实操作流
4.1 医生端:从接诊到开医嘱的完整链路
医生登录后(账号doctor1/123456),核心操作是「管理病人」→「开医嘱」:
- 在「病人管理」页点击「新增病人」,填写姓名、性别、入院日期(格式
yyyy-MM-dd)、主治医生(下拉选择自身)、所在病房(需先在「病房管理」中创建); - 提交后系统自动生成
patient_id,并分配空闲床位(调用BedService.assignBedToPatient()); - 进入「医嘱管理」→「新增医嘱」,选择病人、医嘱类型(药品/检查/护理)、执行时间(
2023-10-01 08:00:00)、内容(如“青霉素 80 万单位 im qd”); - 关键验证:提交后,
order表新增记录,bed表对应床位的bed_status从available变为occupied,且patient表的current_bed_id字段被更新。
提示:医嘱内容字段长度设为
varchar(500),足够容纳复杂处方,但若医生输入超长文本(如详细病理分析),需在OrderEntity.java中将content字段类型改为Clob并修改 SQL。
4.2 护士端:执行医嘱与消费录入的协同机制
护士登录(nurse1/123456)后,核心任务是「执行医嘱」和「录入消费」:
- 「执行医嘱」:在「医嘱管理」页看到待执行列表(
order_status='pending'),点击「执行」按钮,系统调用OrderService.updateOrderStatus()将状态改为executed,同时触发update patient set last_executed_time=now() where patient_id=?; - 「录入消费」:在「住院消费」页选择病人 → 新增消费项 → 选择药品(从
drug表下拉)→ 输入数量 → 系统自动计算金额(drug.price * quantity)→ 提交后order_detail表新增记录,drug表的stock字段实时扣减。
注意:消费录入时若药品库存不足,页面会弹出
alert("药品库存不足!"),但后端未做事务回滚——这是真实业务漏洞,需在OrderDetailService.addOrderDetail()中加if (drug.getStock() < quantity) throw new RuntimeException("库存不足");并包裹在@Transactional中。
4.3 管理员端:统计报表与权限管控的硬核细节
管理员(admin/admin)的核心价值在「数据洞察」和「权限治理」:
- 「消费统计报表」:选择起止日期、科室(可多选)、病人姓名(模糊搜索),点击「导出 Excel」。报表包含
病人姓名、床位号、消费日期、项目名称、单价、数量、小计、合计八列,其中合计是按病人维度 SUM,小计是单行计算结果; - 「用户管理」:新增用户时,角色下拉框只有
admin/doctor/nurse三项,但user_role表中role_id字段允许插入任意字符串——这意味着可手工插入role_id='auditor',而系统未校验角色合法性; - 「药品管理」:上传药品图片时,
DrugController.uploadImage()方法将文件保存至WebContent/upload/drug/目录,但未做文件类型校验(如允许上传.jsp文件),存在安全隐患。
4.4 三角色权限边界:谁能看到什么、能改什么
权限控制基于user_role表的role_id字段,但未使用 Shiro 或 Spring Security,而是纯代码判断:
DoctorController.java中@RequestMapping("/doctor/list")方法开头有if (!"doctor".equals(user.getRoleId())) { return "redirect:/login.jsp"; };NurseController.java中@RequestMapping("/nurse/updateOrderStatus")方法检查order.getExecutorId().equals(user.getUserId()),确保护士只能执行自己班次的医嘱;AdminController.java中@RequestMapping("/admin/exportReport")无额外校验,任何角色只要知道 URL 就能访问——这是重大权限缺陷,需增加@PreAuthorize("hasRole('admin')")注解(需引入 Spring Security)。
4.5 避坑:业务功能中的五个致命逻辑漏洞
现象1:医生给病人开多个相同药品医嘱,系统不校验是否重复
原因:OrderService.addOrder()方法未查询order表中是否存在patient_id + drug_id + date组合的重复记录。
解决:在新增前执行SELECT COUNT(*) FROM order WHERE patient_id = ? AND drug_id = ? AND DATE(create_time) = CURDATE(),若 >0 则抛异常。
现象2:护士执行医嘱后,病人状态未更新为“治疗中”
原因:OrderService.updateOrderStatus()只更新order表,未联动更新patient表的status字段(如status='treated')。
解决:在事务中添加patientMapper.updateStatusByOrderId(orderId, "treated")。
现象3:管理员删除医生账号后,该医生名下的病人仍显示其为主治医生
原因:patient表的doctor_id是外键,但数据库未设ON DELETE CASCADE,且代码中删除医生时未清理关联病人。
解决:在DoctorService.deleteDoctor()中先执行patientMapper.updateDoctorId(null, doctorId)。
现象4:药品库存扣减为负数,系统无预警
原因:DrugService.updateStock()方法直接执行UPDATE drug SET stock = stock - ? WHERE drug_id = ?,未前置校验stock >= ?。
解决:改为UPDATE drug SET stock = stock - ? WHERE drug_id = ? AND stock >= ?,检查getUpdateCount()是否为 0。
现象5:导出 Excel 时,若病人无消费记录,报表生成空文件且无提示
原因:ExportExcelUtil.export()方法未判断List<OrderDetailEntity>是否为空,直接创建 Excel。
解决:添加if (details.isEmpty()) { response.getWriter().write("无消费记录"); return; }。
5. 前端交互深挖:JSP 页面如何驱动住院业务可视化
5.1 JSP 页面结构:MVC 分层在视图层的体现
所有 JSP 位于WebContent/WEB-INF/jsp/下,采用标准 MVC 模式:
index.jsp是门户页,通过<c:import url="/common/header.jsp"/>引入公共头;doctor/list.jsp中<c:forEach items="${doctorList}" var="doctor">遍历ModelAndView.addObject("doctorList", doctors)传入的数据;- 表单提交统一用
form action="${pageContext.request.contextPath}/doctor/add",contextPath动态获取应用名(如/hospital),避免硬编码路径。
5.2 Bootstrap 4 与自定义 CSS 的协同策略
WebContent/static/css/下共存bootstrap4.2.1.min.css和style.css:
- Bootstrap 4 负责栅格系统(
<div class="row">)、表单控件(<input class="form-control">)、按钮样式(<button class="btn btn-primary">); style.css覆盖业务特有样式:.bed-status-available { background-color: #4CAF50; }(空闲床位绿色);.bed-status-occupied { background-color: #f44336; }(占用床位红色);.order-status-pending { color: orange; }(待执行医嘱橙色);
- 关键技巧:
style.css必须放在bootstrap.min.css之后引入,否则覆盖失效。
5.3 JavaScript 交互:床位状态实时更新的实现原理
bed/list.jsp中床位状态切换依赖原生 JS:
function changeBedStatus(bedId, status) { $.post("${pageContext.request.contextPath}/bed/updateStatus", { bedId: bedId, status: status }, function(data) { if (data.success) { // 根据 status 更新对应 DOM 元素背景色 $("#bed-" + bedId).removeClass("available occupied maintenance") .addClass(status); } }); }$.post发送异步请求,避免整页刷新;$("#bed-" + bedId)通过 ID 定位床位 DOM,ID 在 JSP 中生成为<div id="bed-101" class="bed-item available">;removeClass/addClass动态切换 CSS 类,视觉反馈即时。
5.4 表单验证:客户端与服务端的双重保险
以「新增病人」表单为例:
- 客户端:
<input type="text" name="name" required>浏览器原生验证必填; - 服务端:
DoctorController.addDoctor()方法中if (StringUtils.isBlank(doctor.getName())) { model.addAttribute("error", "姓名不能为空"); return "doctor/add"; }; - 关键细节:JSP 中
<form:errors path="name" cssClass="error"/>显示错误信息,但需在DoctorEntity.java中@NotBlank(message="姓名不能为空")注解配合 Hibernate Validator。
5.5 避坑:前端交互的六个典型故障点
现象1:点击「分配床位」按钮无反应,控制台报Uncaught ReferenceError: $ is not defined
原因:jquery.min.js未正确引入,或引入位置在bootstrap.min.js之后(Bootstrap 4 依赖 jQuery)。
解决:确保<script src="static/js/jquery.min.js"></script>在所有 Bootstrap JS 之前。
现象2:日期选择器(<input type="date">)在 IE 浏览器中不显示
原因:IE 11 及以下不支持原生type="date"。
解决:引入bootstrap-datepicker插件,在bed/add.jsp中:
<input type="text" class="form-control datepicker" name="entryDate"> <script>$('.datepicker').datepicker({format: 'yyyy-mm-dd'});</script>现象3:药品图片上传后,页面显示http://localhost:8080/hospital/upload/drug/xxx.jpg但 404
原因:Tomcat 默认禁止访问WEB-INF外的upload目录,需在web.xml中添加 servlet 映射:
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/upload/*</url-pattern> </servlet-mapping>现象4:分页插件PageUtil计算总页数错误,最后一页数据重复
原因:PageUtil.getTotalPage()方法中totalRecord % pageSize == 0 ? totalRecord / pageSize : totalRecord / pageSize + 1的整数除法在 Java 中截断,如10/3=3。
解决:改为(int) Math.ceil((double) totalRecord / pageSize)。
现象5:中文搜索时,URL 中?keyword=张三变成?keyword=%E5%BC%A0%E4%B8%89,后端接收乱码
原因:GET 请求未设置request.setCharacterEncoding("UTF-8")。
解决:在web.xml中配置CharacterEncodingFilter,或在DoctorController.list()方法开头加request.setCharacterEncoding("UTF-8")。
现象6:导出 Excel 按钮点击后,浏览器下载文件名为download.xls而非消费报表_20231001.xls
原因:ExportExcelUtil.export()方法中response.setHeader("Content-Disposition", "attachment; filename=download.xls")未动态生成文件名。
解决:改为response.setHeader("Content-Disposition", "attachment; filename=消费报表_" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + ".xls")。
6. 从毕设到生产:三个关键改造让系统真正可用
6.1 数据库优化:索引与字段类型的手术级调整
原始hospital_db.sql中order_detail表的create_time字段类型为datetime,但未建索引。在真实场景中,按时间查询消费明细是高频操作(如“查昨天所有消费”),必须加索引:
ALTER TABLE order_detail ADD INDEX idx_create_time (create_time);更关键的是patient表的name字段,原始为varchar(50),但病历中常出现 20 字以上的全名(如“北京市朝阳区某某社区卫生服务中心张某某”)。若不做处理,LIKE '%张%'查询会全表扫描。解决方案:
- 将
name字段改为varchar(100); - 添加前缀索引:
ALTER TABLE patient ADD INDEX idx_name_prefix (name(20)); - 同时在
PatientMapper.xml中SELECT * FROM patient WHERE name LIKE CONCAT('%', #{keyword}, '%')改为WHERE name LIKE #{keyword},避免CONCAT导致索引失效。
6.2 安全加固:过滤 XSS 与 SQL 注入的最小成本方案
项目未做任何安全防护,但只需三处修改即可堵住主要漏洞:
- XSS 过滤:在
web.xml中添加HttpServletResponseWrapper过滤器,重写getWriter()方法,对输出内容做 HTML 转义:
PrintWriter writer = response.getWriter(); writer.write(StringEscapeUtils.escapeHtml4(content));- SQL 注入防护:所有
Mapper.xml中的#{}参数占位符已安全,但order by动态排序需白名单校验:
// OrderController.java String[] allowedSortFields = {"create_time", "amount", "patient_name"}; if (!Arrays.asList(allowedSortFields).contains(sortField)) { sortField = "create_time"; } model.addAttribute("sortField", sortField);- 文件上传校验:
DrugController.uploadImage()中增加:
String contentType = file.getContentType(); if (!"image/jpeg".equals(contentType) && !"image/png".equals(contentType)) { throw new RuntimeException("仅允许上传 JPG/PNG 图片"); }6.3 日志与监控:让系统问题可追溯的实用配置
原始日志只输出到控制台,无法追踪线上问题。改造方案:
- 在
log4j.properties中添加滚动文件 Appender:
log4j.appender.File=org.apache.log4j.DailyRollingFileAppender log4j.appender.File.File=${webapp.root}/logs/hospital.log log4j.appender.File.DatePattern='.'yyyy-MM-dd log4j.appender.File.layout=org.apache.log4j.PatternLayout log4j.appender.File.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%p] %c{1} - %m%n- 在关键业务方法(如
OrderService.addOrder())开头添加:
logger.info("医生[{}]为病人[{}]开具医嘱,药品ID[{}], 数量[{}]", doctor.getUsername(), patient.getName(), drugId, quantity);- 部署时将
logs/目录挂载到独立磁盘,避免日志撑爆 Tomcat 分区。
6.4 部署 checklist:上线前必须验证的七件事
| 检查项 | 验证方法 | 不通过后果 |
|---|---|---|
| 数据库连接池 | 查看 Tomcat 日志中Initializing connection pool... maxActive=20 | 连接耗尽导致请求超时 |
| 静态资源路径 | 访问http://ip:8080/hospital/static/css/style.css返回 CSS 内容 | 页面无样式,功能不可用 |
| 文件上传目录 | 在服务器webapps/hospital/upload/drug/下创建测试文件 | 图片上传失败,药品信息不完整 |
| 日期格式化 | 新增病人时输入2023-10-01,数据库entry_date字段存储为2023-10-01 | 时间错乱,统计报表失真 |
| 角色权限隔离 | 用nurse1账号尝试访问/admin/user/list,应返回 404 或重定向 | 权限越界,数据泄露风险 |
| 事务一致性 | 同时开两个浏览器,A 医生分配床位,B 护士立即查询,应看到状态更新 | 数据不一致,业务逻辑崩溃 |
| 日志滚动 | 手动触发touch webapps/hospital/logs/hospital.log,观察是否生成hospital.log.2023-10-01 | 日志堆积,磁盘空间告警 |
从那以后我每次接手毕设源码,第一件事就是打开applicationContext.xml查dataSource配置,第二件事是运行SELECT COUNT(*) FROM user看初始数据是否完整,第三件事是用 Postman 发送一个 POST 请求测试事务回滚——这三步做完,80% 的“跑不起来”问题都能当场定位。这份医院住院管理系统源码,表面是毕业设计,内核却是 SSM 框架在真实业务场景下的压力测试场。它不完美,但每个 bug 都指向一个值得深挖的技术点;它不炫技,但每行代码都在回答“Java Web 工程师每天到底在解决什么问题”。希望帮到你。
本文还有配套的精品资源,点击获取