(一)Maven框架文件正确



5 个文件是你项目里真正必写的,我用 ✅ 给你标出来:

必写(业务核心)

  • src/main/java/dey7/ScoreServlet.java
  • src/main/java/dey7/test11.java

必存在(配置 / 页面,哪怕是空的)

  • src/main/webapp/WEB-INF/web.xml
  • src/main/webapp/index.jsp
  • src/main/webapp/register.html


    【全代码】
    (1)ScoreServlet.java

    package 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跑通(不会的请看第一步)







     

Logo

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

更多推荐