【第二步+前后分离调】检查各java Web项目各文件【含代码】
✅✅【全代码】// 1. Servlet 异常基类:处理Servlet运行时的异常// 2. WebServlet 注解:用来配置Servlet的访问路径,代替web.xml配置// 3. HttpServlet 基类:所有Servlet都要继承它,提供请求处理能力// 4. HttpServletRequest:封装浏览器发送过来的所有请求数据(参数、地址、头信息等)// 5. HttpServ
·
(一)Maven框架文件正确


这 5 个文件是你项目里真正必写的,我用 ✅ 给你标出来:
✅ 必写(业务核心)
src/main/java/dey7/ScoreServlet.javasrc/main/java/dey7/test11.java
✅ 必存在(配置 / 页面,哪怕是空的)
src/main/webapp/WEB-INF/web.xmlsrc/main/webapp/index.jsp-
src/main/webapp/register.html
【全代码】
(1)ScoreServlet.javapackage dey7; // 1. Servlet 异常基类:处理Servlet运行时的异常 import javax.servlet.ServletException; // 2. WebServlet 注解:用来配置Servlet的访问路径,代替web.xml配置 import javax.servlet.annotation.WebServlet; // 3. HttpServlet 基类:所有Servlet都要继承它,提供请求处理能力 import javax.servlet.http.HttpServlet; // 4. HttpServletRequest:封装浏览器发送过来的所有请求数据(参数、地址、头信息等) import javax.servlet.http.HttpServletRequest; // 5. HttpServletResponse:封装服务器返回给浏览器的响应数据 import javax.servlet.http.HttpServletResponse; // 6. IOException:输入输出异常,处理网络传输、读写数据时的错误 import java.io.IOException; // 7. ArrayList:基于数组实现的集合,用来存储多个学生成绩 import java.util.ArrayList; // 8. List:集合接口,定义存储成绩的规范(增删改查) import java.util.List; /** * 成绩计算核心 Servlet * 功能:接收前端传来的学生人数 + 各科成绩,计算平均分,然后跳转到结果页面展示 */ // 注解配置访问路径:前端通过 /scoreServlet 访问这个类 @WebServlet("/scoreServlet") public class ScoreServlet extends HttpServlet { /** * 处理 POST 请求(前端表单提交默认走 POST) */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // ===================== 1. 解决中文乱码 ===================== // 设置请求数据编码为 UTF-8,防止中文乱码 request.setCharacterEncoding("UTF-8"); // ===================== 2. 获取前端传来的学生人数 ===================== // request.getParameter:获取前端传递的参数 int n = Integer.parseInt(request.getParameter("n")); // ===================== 3. 接收所有学生成绩 ===================== // 用于存放所有成绩 List<Double> scores = new ArrayList<>(); // 总分,用于计算平均分 double sum = 0; // 循环获取每一个学生的成绩 for (int i = 0; i < n; i++) { // 获取参数名:score0、score1、score2... String scoreStr = request.getParameter("score" + i); // 把字符串转成 double 类型 double score = Double.parseDouble(scoreStr); // 把成绩存入集合 scores.add(score); // 累加到总分 sum += score; } // ===================== 4. 计算平均分 ===================== double average = sum / n; // ===================== 5. 把数据存入请求域,传给页面 ===================== // 把成绩列表存进去 request.setAttribute("scores", scores); // 把平均分存进去 request.setAttribute("average", average); // ===================== 6. 跳转到结果页面展示数据 ===================== // 请求转发到 index.jsp request.getRequestDispatcher("/index.jsp").forward(request, response); } /** * 处理 GET 请求 * 作用:让 GET 和 POST 走同一套逻辑 */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
(2)test11.java
// 声明当前类所在的包,和Servlet同包 dey7 package dey7; // 导入Scanner类:用于接收键盘手动输入数据 import java.util.Scanner; /** * 成绩统计工具类 * 功能:控制台录入班级人数、录入每位同学成绩 * 自带输入合法性校验,自动计算:平均分、最高分、最低分 */ public class test11 { /** * 程序入口主方法 * 程序从这里开始执行 */ public static void main(String[] args) { // 创建Scanner扫描器对象,专门用来读取键盘输入 Scanner sc = new Scanner(System.in); // 定义变量n:用来存储班级人数,初始值设为0 int n = 0; // 死循环:一直输入,直到输入合法人数才跳出循环 while (true) { // 控制台提示文字:请用户输入班级人数 System.out.print("请输入班级人数:"); // 判断用户输入的是不是整数 if (sc.hasNextInt()) { // 读取输入的整数,赋值给变量n n = sc.nextInt(); // 判断人数必须大于0才合法 if (n > 0) { // 合法,跳出死循环,往下执行 break; } else { // 输入0或负数,提示错误 System.out.println("人数不能为0或负数,请重新输入!"); } } else { // 输入不是整数(字母、符号等),提示错误 System.out.println("请输入有效的整数!"); // 清除非法输入,防止死循环卡住 sc.next(); } } // 创建double类型数组,长度为n,用来存放n个同学的成绩 double[] scores = new double[n]; // 提示开始依次录入每位同学成绩 System.out.println("请依次输入每个人的成绩(0-100):"); // 循环n次,逐个录入每个同学成绩 for (int i = 0; i < n; i++) { // 内层死循环:保证单个成绩输入合法才进入数组 while (true) { // 提示当前是第几个同学输入成绩 System.out.print("第" + (i + 1) + "个同学的成绩:"); // 判断输入是不是小数/数字 if (sc.hasNextDouble()) { // 读取输入的成绩 double score = sc.nextDouble(); // 校验成绩范围:必须在0~100之间 if (score >= 0 && score <= 100) { // 合法成绩存入数组对应位置 scores[i] = score; // 跳出内层循环,录入下一位同学 break; } else { // 超出0-100范围,提示重新输入 System.out.println("成绩必须在0-100之间,请重新输入!"); } } else { // 输入不是数字,提示错误 System.out.println("请输入有效的数字!"); // 清空非法输入,避免卡死 sc.next(); } } } // 换行分隔,打印标题 System.out.println("\n===== 全班成绩列表 ====="); // 遍历数组,把所有录入的成绩全部打印出来 for (int i = 0; i < n; i++) { System.out.println("第" + (i + 1) + "个同学成绩:" + scores[i]); } // 定义总分变量,初始0,用来累加所有成绩 double sum = 0; // 定义最高分,先默认第一个同学成绩为最高分 double max = scores[0]; // 定义最低分,先默认第一个同学成绩为最低分 double min = scores[0]; // 增强for循环:逐个取出数组里的每一个成绩 for (double score : scores) { // 累加总分 sum += score; // 如果当前成绩比记录的最高分还大,更新最高分 if (score > max) { max = score; } // 如果当前成绩比记录的最低分还小,更新最低分 if (score < min) { min = score; } } // 总分除以人数,计算平均分 double avg = sum / n; // 打印统计信息标题 System.out.println("\n===== 成绩统计 ====="); // 格式化输出平均分,保留2位小数 System.out.printf("平均分:%.2f\n", avg); // 输出最高分 System.out.println("最高分:" + max); // 输出最低分 System.out.println("最低分:" + min); // 关闭扫描器,释放资源 sc.close(); } }
(3)web.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML声明:版本1.0,编码UTF-8,保证中文不乱码 --> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- web-app:根标签,表示这是一个Java Web项目配置文件 xmlns:命名空间,固定写法,让服务器识别这是Web配置 xsi:schemaLocation:约束文件地址,规定标签怎么写 version="4.0":使用Servlet 4.0版本 --> <!-- 欢迎页列表:配置项目默认打开的页面 --> <welcome-file-list> <!-- 欢迎页:访问项目根路径时,自动打开 index.jsp --> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
(4)index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%-- page指令:JSP页面核心配置 contentType:设置页面类型为HTML,编码UTF-8,解决中文乱码 language:指定页面使用Java语言 --%> <html> <%-- HTML根标签,整个页面内容都写在这里 --%> <head> <%-- 头部区域:配置页面标题、样式、字符集等 --%> <title>全班成绩列表</title> <%-- 浏览器标签页显示的标题 --%> <style> <%-- CSS样式区域:美化页面外观 --%> body { font-family: Arial, sans-serif; /* 设置页面字体 */ margin: 50px; /* 页面外边距,让内容不贴边 */ } h1 { color: #333; /* 标题文字颜色 */ } table { border-collapse: collapse; /* 合并表格边框,更美观 */ width: 400px; /* 表格宽度 */ margin-top: 20px; /* 表格上边距 */ } th, td { border: 1px solid #ddd; /* 单元格边框 */ padding: 8px; /* 单元格内边距 */ text-align: center; /* 文字居中 */ } th { background-color: #f2f2f2; /* 表头背景色 */ } a { display: inline-block; /* 链接以块级显示 */ margin-top: 20px; /* 链接上边距 */ color: #0066cc; /* 链接文字颜色 */ text-decoration: none; /* 去掉下划线 */ } a:hover { text-decoration: underline; /* 鼠标悬浮时显示下划线 */ } </style> </head> <body> <%-- 页面主体区域:用户能看到的所有内容 --%> <h1>===== 全班成绩列表 =====</h1> <%-- 一级标题:成绩列表标题 --%> <table> <%-- 表格:展示学生序号和对应成绩 --%> <tr> <%-- 表格表头行 --%> <th>序号</th> <th>成绩</th> </tr> <%-- JSP注释:用原生Java代码遍历成绩,避免第三方标签报错 --%> <% // 1. 从request域中获取Servlet传递过来的成绩集合 java.util.List<Double> scores = (java.util.List<Double>) request.getAttribute("scores"); // 2. 判断集合不为空且有数据,防止空指针异常 if (scores != null && !scores.isEmpty()) { // 3. 循环遍历所有成绩 for (int i = 0; i < scores.size(); i++) { // 获取当前下标对应的成绩 double score = scores.get(i); %> <%-- 循环生成表格行,展示学生序号和成绩 --%> <tr> <td>第<%= i + 1 %>个同学</td> <%-- 输出序号(从1开始) --%> <td><%= score %></td> <%-- 输出当前学生成绩 --%> </tr> <% } } else { // 集合为空时,显示暂无数据 %> <tr> <td colspan="2">暂无成绩数据</td> <%-- 合并两列显示提示 --%> </tr> <% } %> </table> <%-- ===================== 显示全班平均分 ===================== --%> <% // 1. 从request域中获取Servlet传递的平均分 Double average = (Double) request.getAttribute("average"); // 2. 判断平均分不为空时才显示 if (average != null) { %> <h2 style="color: #0066cc; margin-top: 20px;"> <%-- 格式化输出平均分,保留2位小数 --%> 全班平均分:<%= String.format("%.2f", average) %> 分 </h2> <% } %> <%-- ========================================================== --%> <a href="register.html">返回重新录入</a> <%-- 跳转链接:点击返回录入页面,重新提交数据 --%> </body> </html>
(5)register.html
<!DOCTYPE html> <!-- 文档类型声明:告诉浏览器这是 HTML5 标准页面 --> <html lang="zh-CN"> <!-- HTML 根标签,lang="zh-CN" 表示页面语言为简体中文 --> <head> <!-- 头部配置区:页面编码、标题、样式等 --> <meta charset="UTF-8"> <!-- 设置页面字符编码为 UTF-8,解决中文乱码 --> <title>班级成绩录入</title> <!-- 浏览器标签页显示的标题 --> <style> <!-- CSS 样式:美化页面布局 --> body { font-family: Arial, sans-serif; /* 页面字体 */ margin: 50px; /* 页面外边距,内容不贴边 */ } .form-group { margin: 15px 0; /* 输入框组上下间距 */ } label { display: inline-block; /* 标签横向排列 */ width: 120px; /* 标签固定宽度,对齐美观 */ } input { padding: 5px; /* 输入框内边距 */ width: 200px; /* 输入框宽度 */ } button { padding: 8px 20px; /* 按钮内边距 */ cursor: pointer; /* 鼠标悬浮变成小手 */ } </style> </head> <body> <!-- 页面主体:用户能看到的所有内容 --> <h1>班级成绩录入系统</h1> <!-- 页面大标题 --> <!-- 表单:提交数据到后端 Servlet,method="post" 表示提交方式 --> <form action="scoreServlet" method="post"> <!-- 班级人数输入区域 --> <div class="form-group"> <label>班级人数:</label> <!-- 输入人数,类型数字,最小1,必填 --> <input type="number" name="n" min="1" required> </div> <!-- 动态生成成绩输入框的容器 --> <div id="scoreInputs"></div> <!-- 按钮1:点击生成成绩输入框,不提交表单 --> <button type="button" οnclick="generateScoreInputs()">生成成绩输入框</button> <!-- 按钮2:提交表单数据到后端 --> <button type="submit">提交成绩</button> </form> <script> <!-- JavaScript 脚本:实现动态生成输入框功能 --> // 函数作用:根据班级人数,自动生成对应数量的成绩输入框 function generateScoreInputs() { // 1. 获取用户输入的班级人数 const n = document.querySelector('input[name="n"]').value; // 2. 校验人数是否有效 if (!n || n < 1) { alert("请输入有效的班级人数(≥1)"); return; // 无效则退出函数 } // 3. 获取存放成绩输入框的容器 const scoreInputsDiv = document.getElementById("scoreInputs"); // 4. 清空容器里之前的内容,防止重复生成 scoreInputsDiv.innerHTML = ""; // 5. 循环生成 N 个成绩输入框 for (let i = 0; i < n; i++) { // 创建 div 容器 const div = document.createElement("div"); // 设置样式类名 div.className = "form-group"; // 设置 div 内容:标签 + 成绩输入框 div.innerHTML = ` <label>第${i+1}个同学的成绩:</label> <input type="number" name="score${i}" step="0.01" required> `; // 把生成好的输入框添加到页面 scoreInputsDiv.appendChild(div); } } </script> </body> </html>
启动Tomcat跑通(不会的请看第一步)




openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)