☰
JavaWeb学生成绩管理系统:源码导入、环境配置与避坑指南
2026/10/1 10:36:50 网站建设 项目流程

简介:基于JavaWeb的学生成绩管理系统项目源码,定位为计算机专业期末大作业与课程设计的高分模板,经导师指导并认可,评审分达98分,适合需要项目实战练习的初、中级学习者。压缩包共337个文件、3.32MB,主要包含84个Java源文件、84个Class编译文件、36个JSP页面、61个JS脚本、28个CSS样式以及SQL数据库脚本,完整覆盖后端业务逻辑、前端交互和数据库初始化,目录结构清晰,便于按模块拆解学习。目前已有5296人学习下载,参考口碑良好。通过该系统可系统掌握Servlet/JSP开发、MVC分层思想、学生成绩增删改查与统计报表等核心技能,同时附带数据库初始化脚本与配置说明,是期末冲刺和实战练手的直接素材。

1. JavaWeb 学生成绩管理系统到底是个什么项目:给拿到源码却跑不起来的人先拆清楚

如果你是做 JavaWeb 课程设计或毕业设计的学生,大概率下载过这种资源包:一个学生成绩管理系统项目源码,附带一份 .sql 数据库文件。压缩包解开后,src 目录堆了几十个 .java 文件,web 目录下全是 JSP 页面,README 里只有一句含糊的“用 IDEA 打开即可运行”。这个项目能不能跑起来,直接决定你是拿高分还是面临二辩。它本质是一个标准三层架构 JavaWeb 应用:JSP 做界面,Servlet 处理请求,MySQL 存数据,登录后按管理员、教师、学生三种角色展示不同功能。本文不评价项目好坏,只讲一件事:拿到这类源码包后,怎么把环境配好、把数据库导进去、把 Tomcat 跑通,再把成绩统计和权限控制改成能在答辩里讲清楚的东西。适合正在为课程设计发愁,或想拿现成 JavaWeb 项目练手的人。

2. 拿到源码先读结构:20 分钟搞清技术栈和运行方式

很多人的第一个动作是直接启动 Tomcat,然后被一堆报错打懵。正确顺序是先花 20 分钟读目录,搞清楚这个项目是不是 Maven 工程、Servlet 版本是多少、数据库连接配置写在哪。这些信息都写在文件里,不需要源码级阅读能力。

2.1 三种常见项目形态:JSP+Servlet、SSM、Spring Boot 的判断方法

网上流传的学生成绩管理系统源码主要有三种形态,判断错了后面全白做。第一种是经典 JSP+Servlet+JDBC,目录里会有 WebContent 或 web 文件夹,里面是 WEB-INF/web.xml,lib 目录下堆着一排 jar 包。第二种是 SSM(Spring+SpringMVC+MyBatis),根目录有 pom.xml,配置文件散落在 src/main/resources 下,web.xml 只做监听器配置。第三种是 Spring Boot 单应用,结构更简单,一个 Application.java 就能启动,但严格说已经不算“javaweb 传统项目”了。

判断方法不靠猜,看两个文件。根目录下有没有 pom.xml,有就是 Maven 工程,没有就是传统 Web 项目。再看 web.xml 的 schemaLocation,写的是 2.5 还是 3.1,这个版本号直接对应 Tomcat 版本要求——Servlet 2.5 用 Tomcat 6/7 就行,Servlet 3.1 至少要 Tomcat 8.5。你拿到的如果是老项目配新 Tomcat,通常会报“ClassNotFoundException: javax.servlet.http.HttpServlet”或者诡异的 404,问题不在代码,在版本错配。

传统 JSP+Servlet 项目的典型结构长这样:

project-root/ ├── src/ │ ├── com/xxx/dao/ # JDBC 数据访问层 │ ├── com/xxx/servlet/ # 控制器层 │ ├── com/xxx/model/ # 实体类 │ └── com/xxx/util/ # DBUtil 等工具类 ├── web/ 或 WebContent/ │ ├── WEB-INF/ │ │ ├── web.xml │ │ └── lib/ # 手动导入的 jar 包 │ ├── login.jsp │ ├── student/ │ │ ├── studentList.jsp │ │ └── scoreManage.jsp │ └── css/js/ ├── db.sql # 数据库脚本 └── README.txt

这段结构里最值得关注的是 DAO 层,它是这个项目的“数据咽喉”。所有成绩查询、学生增删改查最终都汇聚到这里的 JDBC 代码上,后面看数据库连接配置也是找这个包下的 DBUtil 或 JdbcUtil 类。

2.2 从 web.xml 看访问路径和 Servlet 映射规则

web.xml 是整个项目的地图。很多项目登录后跳转失败,不是代码写错,而是 servlet-mapping 里的 url-pattern 和 JSP 里 form 的 action 对不上。看的时候注意两点:一是 servlet 注册名和映射路径,常见的登录映射是 /login 或 /LoginServlet;二是 welcome-file 把首页指定成了哪个文件,正常情况是 login.jsp 或 index.jsp。

<servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>com.example.servlet.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list>

这里有个很隐蔽的坑:如果 url-pattern 是 /login,而 JSP 的 form 写的是 action="LoginServlet",启动后点登录按钮必然 404。所以拿到项目第一件事不是在 IDEA 里跑,而是把 login.jsp 里的 form action 和 web.xml 的 servlet-mapping 对照一遍。我一般会用 grep 直接搜整个 web 目录,看哪个 JSP 里写了 form 提交地址,再和 web.xml 比对,不匹配的先记下来。

2.3 数据库连接配置在哪:db.properties、jdbc.properties 或 DBUtil 硬编码

数据库连接配置是第二个必看文件。老项目喜欢把它写在 src 下的 db.properties 或 jdbc.properties 里,内容就是 driver、url、username、password 四行;更老的项目直接硬编码在 DBUtil.java 的静态代码块里。打开这个文件,立刻能判断你要不要把 MySQL 版本或密码。

jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/student?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai jdbc.username=root jdbc.password=123456

注意看 driver 这一行。如果是 com.mysql.jdbc.Driver,这是 MySQL 5.x 时代的驱动包;如果是 com.mysql.cj.jdbc.Driver,这是 MySQL 8.x 的驱动。用 MySQL 8 连老项目的旧驱动虽然有时也能跑,但时区和 SSL 相关的报错会让人怀疑人生。URL 里的 characterEncoding=utf8 和 serverTimezone=Asia/Shanghai 这两项,是治中文乱码和日期报错的关键参数,后面避坑章节还会展开。

3. 用 IDEA 运行 javaweb 项目:从导入源码到看到登录页的完整配置

环境配置占了这类项目 70% 的失败率。这不是代码问题,而是 IDEA 对 Java Web 项目的部署方式跟 Eclipse 不一样,很多人拿着 Eclipse 的思维在 IDEA 里折腾,自然翻车。这一章的每一节都是一条可复现的路径。

3.1 三种导入方式:Maven 工程、传统 Web 工程、Eclipse 工程

先看根目录有没有 pom.xml。有的话直接用 IDEA 的 Open 打开,选择信任项目后,等 Maven 把依赖拉完。这里要特别提醒国内网络环境,Maven 中央仓库经常拉取超时,settings.xml 里建议配置镜像,常见做法是阿里云镜像。

<mirror> <id>aliyunmaven</id> <mirrorOf>central</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/central</url> </mirror>

配置完镜像后,再执行一次 mvn clean compile,控制台 BUILD SUCCESS 才算依赖就绪。如果连阿里云镜像都慢,还可以在 pom.xml 里指定仓库地址,但这种情况较少。

没有 pom.xml 的老项目走另一条路:File → Project Structure → Facets,点加号添加 Web 模块,指定 web 资源目录和 web.xml 路径;再到 Artifacts 添加 Web Application Exploded,把项目打成 war 包结构。这两步做完,Tomcat 配置才能识别到部署内容,否则启动后在浏览器只会看到 Tomcat 默认首页,你的项目根本不在部署列表里。

Eclipse 项目(有 .project 和 .classpath 文件)最省事,IDEA 直接 Open 就能识别,但要注意 Project Structure 里的 SDK 和语言级别,Eclipse 用 JDK 8 写的代码,到 IDEA 里如果默认语言级别是 17,可能直接编译报错。

3.2 数据库导入:用 Navicat 或命令行跑通 db.sql

数据库这块,我建议优先用命令行导入而不是图形工具,因为 .sql 文件里可能包含存储过程、触发器或特殊字符,图形工具导入报错时日志不直观。先建库再导数据,顺序不能反。

mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS student DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" mysql -u root -p student < db.sql

导入成功后别急着关命令行,先查一下核心表有没有数据。很多“高分项目”的 db.sql 只建了表结构,没写 INSERT 语句。如果 student 表和 score 表是空的,登录进去看到白茫茫一片,很容易误判成程序故障,实际只是没有初始数据。命令行查数据用下面这句:

USE student; SHOW TABLES; SELECT COUNT(*) FROM student; SELECT COUNT(*) FROM score;

如果表名和项目代码里 DAO 层写的不一致,比如代码里查询的是student_info但表叫tb_student,导入后一登录就报 SQL grammar 错误。这种事在网上下载的资源包里挺常见,拿到 .sql 先扫一遍 CREATE TABLE 的表名,和 DAO 层 SQL 对一下,能省一晚上的排查时间。

3.3 Tomcat 配置与启动:从 404 到登录页的排查顺序

IDEA 里配 Tomcat 时,Run/Debug Configurations 里选 Tomcat Server → Local,在 Deployment 标签页把 Artifact 加进去,Application context 填项目访问路径,比如 /student。建议 URL 填http://localhost:8080/student/,启动后 IDEA 会自动打开浏览器。

这里最容易出现的问题有三个:端口被占用、Artifact 没部署、项目路径带空格。端口占用时 Console 会直接提示 Port 8080 was already in use,换 8081 或者在任务管理器里杀掉占用进程都行。Artifact 没部署的表现是浏览器能打开 Tomcat 默认页面,但 URL 换成 /student 就 404,回到 Deployment 看有没有把项目加进去。路径带空格的问题通常在 Windows 上,项目所在目录的完整路径里不能有空格,否则 JSP 编译会出一堆莫名其妙的错。

正常跑通后,用初始账号登录。大多数这种项目会在 db.sql 的 admin 表里写死一个管理员账号,比如 admin/admin123。实在不知道账号密码,就查 user 表或 admin 表:

SELECT * FROM admin; SELECT * FROM user;

看到明文密码就说明登录逻辑是明文比对,看到 MD5 密文也别慌,网上随便找个 MD5 在线工具把 admin123 加密后比对一下就知道初始密码了。这一步是很多“高分项目”使用者卡住的第一道坎,项目能登录了,后续功能验证才谈得上。

4. 成绩模块核心逻辑:表设计、增删改查和统计 SQL 的落地写法

学生成绩管理系统的核心是成绩模块,无论是课设答辩还是二次开发,这块讲不清楚基本就凉了。这个模块本质就是一张 score 表挂在 student 表和 course 表上,所有功能都围绕“给谁、哪门课、多少分”这三个要素展开。

4.1 五张核心表的结构设计:从建表 SQL 看懂权限和业务边界

常见设计至少五张表:student(学生)、teacher(教师)、course(课程)、score(成绩)、admin(管理员)。有的资源包会把 admin 和 teacher 合并成 user 表,加一个 role 字段区分,这种设计更灵活但要小心权限判断逻辑。

CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, sno VARCHAR(20) NOT NULL UNIQUE COMMENT '学号', sname VARCHAR(50) NOT NULL COMMENT '姓名', gender VARCHAR(10) DEFAULT '男', class_name VARCHAR(50) COMMENT '班级', created_at DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE course ( id INT PRIMARY KEY AUTO_INCREMENT, cno VARCHAR(20) NOT NULL UNIQUE COMMENT '课程号', cname VARCHAR(50) NOT NULL COMMENT '课程名', credit DECIMAL(3,1) DEFAULT 2.0 COMMENT '学分' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE score ( id INT PRIMARY KEY AUTO_INCREMENT, sno VARCHAR(20) NOT NULL COMMENT '学号', cno VARCHAR(20) NOT NULL COMMENT '课程号', score DECIMAL(5,2) NOT NULL COMMENT '成绩', exam_time VARCHAR(20) COMMENT '考试时间,如2024-01', UNIQUE KEY uk_sno_cno (sno, cno) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

注意 score 表里设置了联合唯一约束 uk_sno_cno,这一个约束就解决了“同一学生同一门课只能有一条成绩记录”的重复录入问题。很多老项目的表设计里没有这个约束,导致成绩数据里出现一条学生同一门课两条分数,统计平均分时一算一个不吱声。字段选择上也值得注意:sno 和 cno 用字符串而不是直接用 student 表的自增 id,是为了让 score 表不依赖 student 表的内部主键,学号作为业务主键更稳定,学生转班、修改记录时成绩不至于错乱。

4.2 成绩录入、修改、删除的 SQL 写法:先查后写还是直接覆盖

成绩录入是教师角色的高频操作。经典写法是“先查这条成绩是否存在,存在则更新,不存在则插入”,用代码判断逻辑清晰,但访问量一大就容易出现并发问题——两个请求同时查都不存在,然后各插一条,唯一约束直接报错。更稳妥的做法是直接用 MySQL 的 INSERT ... ON DUPLICATE KEY UPDATE,把判断交给数据库。

INSERT INTO score (sno, cno, score, exam_time) VALUES ('2024001', 'CS101', 88.5, '2024-01') ON DUPLICATE KEY UPDATE score = VALUES(score), exam_time = VALUES(exam_time);

这条 SQL 的意思是:如果 (sno, cno) 在 uk_sno_cno 上撞了唯一约束,就把这条记录的 score 和 exam_time 更新为当前值;没撞就正常插入。用 VALUES() 函数引用待插入值,比再调一次 SELECT 再 UPDATE 的方式少一次数据库往返,逻辑也更原子化。成绩删除相对简单,但要注意是物理删除还是逻辑删除,课设项目一般直接 DELETE 就行,讲究点的会在 score 表加一个 is_deleted 字段做软删除,避免误删重要成绩。

4.3 统计查询的三种 SQL:平均分、排名、及格率

成绩管理系统的“管理”二字,最终落在统计报表上。最常见的三个需求:某门课的平均分、某个班级学生的成绩排名、某门课的及格率。这三个 SQL 写法覆盖了大部分课设答辩会问到的点。

-- 按课程统计平均分和考试人数 SELECT c.cname, COUNT(s.id) AS exam_count, AVG(s.score) AS avg_score, MAX(s.score) AS max_score, MIN(s.score) AS min_score FROM score s JOIN course c ON s.cno = c.cno GROUP BY c.cname;

这个查询用 JOIN 把 score 和 course 两张表关联起来,COUNT 统计考试人数,AVG 算平均分。GROUP BY 一定要和 SELECT 里的非聚合字段一致,也就是 c.cname,否则在 MySQL 的 ONLY_FULL_GROUP_BY 模式会直接报错。成绩排名用窗口函数,MySQL 8.0 及以上版本才支持:

SELECT sno, score, RANK() OVER (PARTITION BY class_name ORDER BY score DESC) AS rank_in_class FROM score JOIN student ON score.sno = student.sno WHERE cno = 'CS101';

窗口函数的逻辑是:先按班级分区(PARTITION BY class_name),再在各自分区内按成绩降序排号。RANK() 的规则是分数相同并列同 rank,比如两个 90 分都排第 1,下一个是第 3。如果你想要并列后跳过编号,用 DENSE_RANK();不想并列,用 ROW_NUMBER()。及格率一般这么算:

SELECT cno, SUM(CASE WHEN score >= 60 THEN 1 ELSE 0 END) AS pass_count, COUNT(*) AS total_count, ROUND(SUM(CASE WHEN score >= 60 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) AS pass_rate FROM score WHERE cno = 'CS101' GROUP BY cno;

用 CASE WHEN 把成绩映射成 1 或 0,SUM 出来的就是及格人数。及格率要乘 100.0 而不是 100,因为如果 *100 是整数乘除法,结果会丢精度变成整数。ROUND 保留两位小数。这三段 SQL 跑通并理解后,答辩时被问“你的统计是怎么实现的”就能讲得很有底气了。

5. 避坑:学生成绩管理系统跑不起来的 6 个常见问题

这一章全是血泪经验。我见过太多人把时间浪费在环境问题上,最后以为是自己代码写得不行。以下按出现频率排序,每条都按“现象 → 原因 → 解决”给完整路径。

5.1 乱码问题:页面中文显示问号,数据库存的中文变问号

  • 现象:登录页正常,但登录后显示的学生姓名全是??,或者数据库里存进去的就是??。
  • 原因:三层乱码,三层互不相关。第一层是 JSP 页面本身不是 UTF-8 编码;第二层是 IDEA 的文件编码设置不对;第三层是 MySQL 连接 URL 缺 characterEncoding 参数,或者数据表默认字符集是 latin1。
  • 解决:先改 IDEA 全局编码,File → Settings → Editor → File Encodings,全部设成 UTF-8,Properties Files 的 Transparent native-to-ascii conversion 勾上。然后检查 JSP 第一行有没有pageEncoding="UTF-8"。最后确认 MySQL 表字符集,如果库已经建了但字符集不对,ALTER TABLE score CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci。三处都对齐,重启 Tomcat 再试。

5.2 MySQL 8 时区报错:启动后一查数据库就抛 SQL 异常

  • 现象:Tomcat 能启动,页面也能打开,但一点登录或查询就报The server time zone value '中国标准时间' is unrecognized或者Cannot create PoolableConnectionFactory。
  • 原因:MySQL 8.x 的驱动要求 serverTimezone 必须显式指定,而 db.properties 里要么没写,要么写的是过时的 GMT。
  • 解决:连接 URL 加上serverTimezone=Asia/Shanghai,JDBC 驱动换成com.mysql.cj.jdbc.Driver。如果你用的是 C3P0 连接池,配置文件里同样改 connection URL。改完一定重启 Tomcat,连接池在第一次连接时会缓存配置,光改文件不重启是玄学吗?不是,是连接池生命周期问题。

5.3 Tomcat 启动成功但访问项目 404

  • 现象:IDEA Console 显示 Tomcat Started,浏览器自动打开却看到 404,或者停留在 Tomcat 默认欢迎页。
  • 原因:没把 Artifact 加到 Deployment 里,或者 Application context 路径和 URL 访问路径不一致。IDEA 的 Tomcat 配置里 Deployment 空的,项目根本没有部署进去。
  • 解决:Run → Edit Configurations → Deployment 标签页,点加号选 Artifact,选带 exploded 的那个。Application context 填 /student,然后浏览器访问http://localhost:8080/student/。如果这样还 404,检查 web.xml 的 welcome-file 是不是指向了一个不存在的 JSP。

5.4 端口占用导致 Tomcat 起不来

  • 现象:启动 Tomcat 时 Console 直接报Port 8080 was already in use,IDEA 提示端口冲突。
  • 原因:之前运行过别的服务没关,或者被其他程序占用。Windows 上最常见的是本机装了别的 Web 服务。
  • 解决:换端口最省事,Run → Edit Configurations → Tomcat Server → HTTP port 改成 8081。要么找到占用进程杀掉:Windows 命令行执行netstat -ano | findstr :8080,最后一列是 PID,再用taskkill /F /PID 该PID。注意改端口后访问 URL 也要跟着变。

5.5 数据库连接 Access denied 或 Communications link failure

  • 现象:启动项目后登录提交,页面报 500 错误,Console 最底层 Caused by 是Access denied for user 'root'@'localhost'或Communications link failure。
  • 原因:第一类是用户名密码不对或 MySQL 服务没启动;第二类是 MySQL 的默认端口 3306 被占用或驱动连接的超时时间太短,还有可能是 db.properties 里的 IP 写成了别的机器。
  • 解决:先在命令行用mysql -u root -p测试账号密码能不能登录。能登录但项目报错,看 db.properties 里的密码是不是被改了。Communications link failure 检查 MySQL 服务是否启动,Windows 下用services.msc找到 MySQL 服务,启动类型设成自动。

5.6 score 表重复数据导致统计结果异常

  • 现象:按课程统计平均分,发现一个学生同一门课出现了两条成绩,算出来的平均分虚高,答辩时被老师一问就露馅。
  • 原因:score 表缺少 (sno, cno) 联合唯一约束,并且录入逻辑是先 SELECT 再 INSERT,并发或重复点击时插入了多条。
  • 解决:建表时加上 UNIQUE KEY uk_sno_cno (sno, cno),已经坏了的数据先清理再补约束。清理重复记录用这条 SQL,保留最小 id 的那条:DELETE s1 FROM score s1 JOIN score s2 ON s1.sno = s2.sno AND s1.cno = s2.cno AND s1.id > s2.id;然后录入逻辑改成 ON DUPLICATE KEY UPDATE 写法。表结构不乱,统计才会准。

6. 做二次开发和拿高分:角色权限拦截与成绩导出两个改进点

如果项目已经能跑通,你想让它从“能运行”变成“敢答辩”,建议从两个方向动手:权限控制和成绩导出。这两个点讲起来不复杂,但体现了对系统的整体理解,属于投入产出比很高的改进。

6.1 用 Filter 做基于角色的权限拦截

老项目常见的硬伤是谁都能直接访问 URL 绕过登录,比如在地址栏敲/student/studentList.jsp就能看到所有学生信息。加一个权限过滤器,没有登录的一律踢回登录页,这比在代码里到处判断 session 要干净得多。

@WebFilter("/*") public class AuthFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; HttpSession session = request.getSession(false); String path = request.getRequestURI().substring(request.getContextPath().length()); // 登录页、静态资源直接放行 if (path.equals("/login.jsp") || path.equals("/login") || path.startsWith("/css/") || path.startsWith("/js/")) { chain.doFilter(req, resp); return; } if (session == null || session.getAttribute("user") == null) { response.sendRedirect(request.getContextPath() + "/login.jsp"); return; } chain.doFilter(req, resp); } }

这段代码的核心逻辑是白名单放行 + 会话检查。登录页和静态资源直接放行是因为还没登录也要能访问;其他路径都必须过 session 检查,session 没有 user 属性说明未登录,统一重定向到登录页。如果连 session 都是 null,说明根本没有会话对象,更不能放行。这个 Filter 加上去后,系统的访问控制就从“靠自觉”变成了“靠机制”,答辩时被问到安全性就有话说了。

6.2 成绩导出 Excel:用 POI 还是 CSV

很多课设项目导出成绩是用拼接 HTML 表格骗浏览器下载,这种方式打开 Excel 时会有警告且容易乱码。我一般推荐用 CSV 方案,不引入额外依赖,代码量也小。CSV 本质是文本,但 Excel 能直接打开。要注意中文乱码问题,解决方案是输出 UTF-8 BOM 头,Excel 才能正确识别编码。

response.setContentType("text/csv;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Disposition", "attachment;filename=scores.csv"); PrintWriter out = response.getWriter(); out.print("\uFEFF"); // BOM,防止 Excel 打开乱码 out.println("学号,课程号,成绩,考试时间"); // scoreList 是查询出来的成绩数据 for (Score s : scoreList) { out.println(s.getSno() + "," + s.getCno() + "," + s.getScore() + "," + s.getExamTime()); } out.flush(); out.close();

这段代码里的 BOM 输出是整个方案的关键,没有\uFEFF这行,Excel 打开 CSV 文件中文全乱码;有它,一切正常。Content-Disposition 设置成 attachment 告诉浏览器这是下载而不是页面跳转。注意文件名不要带中文,某些浏览器对中文文件名处理不一致,直接用 scores.csv 最稳妥。如果你用的是 Spring MVC 或 SSM,也可以在 pom.xml 加 poi 依赖导出真正的 xlsx,但对课设场景,CSV 已经足够。

我早期接手这类项目时,最喜欢先改代码再跑通,结果 90% 的报错都来自环境而不是逻辑。后来养成习惯,拿到任何 JavaWeb 源码包,第一小时只做三件事:看目录结构、检查数据库脚本、对照 web.xml 的路径映射。这三件事做完,项目能不能跑、卡在哪,心里基本有数。希望这个习惯也帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询