当前位置: 首页 > news >正文

基于JavaBean的三角形测试系统的设计与实现(SpringMVC + 动态粒子背景)

基于JavaBean的三角形测试系统的设计与实现(SpringMVC + 动态粒子背景)

一、实验概述

本次实验为《Web编程技术》课程实验八,要求使用SpringMVC框架设计一个动态网站,基于JavaBean实现三角形的判定及面积求解。用户在客户端输入三个自然数作为边长,系统判断是否能构成三角形;若不能则输出原因提示,若能则判断三角形类型(锐角/直角/钝角)并计算面积。项目同时具备美观的玻璃拟态界面与动态粒子背景,并成功部署至阿里云ECS服务器。


二、目录

  • 1. 实验目的与要求
  • 2. 实验使用环境
  • 3. 项目目录结构与整体概述
  • 4. 核心代码解析
    • 4.1 JavaBean层(bean包)
    • 4.2 Controller层(controller包)
    • 4.3 JSP视图层(input.jsp / result.jsp)
    • 4.4 动态粒子背景(particle.js)
    • 4.5 样式文件(glass.css / form.css等)
    • 4.6 SpringMVC配置文件
  • 5. 本地部署与调试过程
  • 6. 阿里云ECS服务器部署
  • 7. 实验小结(小组分工与感想)
  • 8. 附录

1. 实验目的与要求

实验目的:掌握JavaBean技术在JSP页面设计中的应用,理解MVC设计模式的思想,熟悉SpringMVC框架的部署。

实验内容:使用SpringMVC框架设计动态网站,基于JavaBean控件实现三角形的判定及面积求解。客户端任意输入3个自然数做为边长,判断它们是否构成一个三角形,若不能输出原因提示信息,否则判断输出三角形的类型(锐角、直角、钝角)并且能计算输出该三角形的面积(不能构成三角形时面积设置为0)。


2. 实验使用环境

  • 操作系统:Microsoft Windows 10 / Windows Server 2019(云端)
  • 编程环境:JDK 1.8、Tomcat 9.0、Eclipse IDE for Web Developers
  • 远程服务器:阿里云ECS(公网IP:118.31.44.31)

3. 项目目录结构与整体概述

项目采用MVC分层设计,以下为完整目录结构(滚动查看):

task8/
├─Java Resources/
│ └─src/
│   ├─com.task8.bean/
│   │ ├─TriangleBean.java      # 存储三角形边长,提供getter/setter
│   │ ├─TriangleJudge.java     # 判断三角形类型和是否构成三角形
│   │ └─TriangleArea.java      # 根据三角形边长计算面积(海伦公式)
│   └─com.task8.controller/
│     └─TriangleController.java # SpringMVC控制器
├─WebContent/
│ ├─css/
│ │ ├─layout.css               # 页面基础布局
│ │ ├─background.css           # 动态渐变背景
│ │ ├─glass.css                # 毛玻璃效果卡片
│ │ └─form.css                 # 表单输入框与按钮样式
│ ├─js/
│ │ └─particle.js              # 粒子动画逻辑
│ └─WEB-INF/
│   ├─jsp/
│   │ ├─input.jsp              # 用户输入页面
│   │ └─result.jsp             # 结果显示页面
│   ├─springmvc-servlet.xml    # SpringMVC配置
│   └─web.xml                  # Web部署描述文件

项目概述:系统基于SpringMVC框架,采用MVC分层设计。用户在浏览器输入三边长度后,控制器调用JavaBean业务逻辑判断三角形合法性、计算面积,并返回结果页面。页面采用动态粒子背景与玻璃拟态卡片,视觉效果突出。


4. 核心代码解析

4.1 JavaBean层(bean包)

TriangleBean.java – 保存三角形数据

package com.task8.bean;public class TriangleBean {private double a;      // 三角形边长aprivate double b;      // 三角形边长bprivate double c;      // 三角形边长cprivate boolean triangle; // 是否构成三角形private String type;   // 三角形类型private double area;   // 三角形面积private String message; // 错误提示信息public TriangleBean() {}public TriangleBean(double a, double b, double c) {this.a = a;this.b = b;this.c = c;}public double getA() { return a; }public void setA(double a) { this.a = a; }public double getB() { return b; }public void setB(double b) { this.b = b; }public double getC() { return c; }public void setC(double c) { this.c = c; }public boolean isTriangle() { return triangle; }public void setTriangle(boolean triangle) { this.triangle = triangle; }public String getType() { return type; }public void setType(String type) { this.type = type; }public double getArea() { return area; }public void setArea(double area) { this.area = area; }public String getMessage() { return message; }public void setMessage(String message) { this.message = message; }
}

TriangleJudge.java – 三角形判定与类型判断

package com.task8.bean;
import java.util.Arrays;public class TriangleJudge {public static boolean isTriangle(TriangleBean t) {double a = t.getA(), b = t.getB(), c = t.getC();if (a <= 0 || b <= 0 || c <= 0) return false;return a + b > c && a + c > b && b + c > a;}public static String getType(TriangleBean t) {double[] side = { t.getA(), t.getB(), t.getC() };Arrays.sort(side);double a = side[0], b = side[1], c = side[2];double left = a*a + b*b;double right = c*c;if (Math.abs(left - right) < 0.0001) return "直角三角形";if (left > right) return "锐角三角形";return "钝角三角形";}
}

TriangleArea.java – 面积计算(海伦公式)

package com.task8.bean;
public class TriangleArea {public static double calculateArea(TriangleBean bean) {if (!TriangleJudge.isTriangle(bean)) return 0;double a = bean.getA(), b = bean.getB(), c = bean.getC();double p = (a + b + c) / 2.0;return Math.sqrt(p * (p - a) * (p - b) * (p - c));}
}

4.2 Controller层(controller包)

TriangleController.java – SpringMVC控制器

package com.task8.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import com.task8.bean.*;@Controller
public class TriangleController {@GetMapping("/")public String index() {return "input";}@PostMapping("/calculate")public String calculate(@RequestParam("a") double a,@RequestParam("b") double b,@RequestParam("c") double c,Model model) {TriangleBean triangle = new TriangleBean(a, b, c);if (a <= 0 || b <= 0 || c <= 0) {model.addAttribute("valid", false);model.addAttribute("message", "边长必须为正数");model.addAttribute("area", 0);return "result";}boolean valid = TriangleJudge.isTriangle(triangle);model.addAttribute("valid", valid);if (!valid) {model.addAttribute("message", "不能构成三角形");model.addAttribute("area", 0);} else {model.addAttribute("message", "可以构成三角形");model.addAttribute("type", TriangleJudge.getType(triangle));model.addAttribute("area", TriangleArea.calculateArea(triangle));}return "result";}
}

4.3 JSP视图层(input.jsp / result.jsp)

input.jsp – 用户输入页面

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>三角形判定系统</title><link rel="stylesheet" href="${pageContext.request.contextPath}/css/background.css"><link rel="stylesheet" href="${pageContext.request.contextPath}/css/layout.css"><link rel="stylesheet" href="${pageContext.request.contextPath}/css/glass.css"><link rel="stylesheet" href="${pageContext.request.contextPath}/css/form.css">
</head>
<body>
<canvas id="particleCanvas"></canvas>
<div class="glass-container"><h1>三角形判定系统</h1><form action="${pageContext.request.contextPath}/calculate" method="post"><input type="number" name="a" placeholder="边长A" required><input type="number" name="b" placeholder="边长B" required><input type="number" name="c" placeholder="边长C" required><button type="submit">开始计算</button></form>
</div>
<script src="${pageContext.request.contextPath}/js/particle.js"></script>
</body>
</html>

result.jsp – 结果显示页面

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>计算结果</title><link rel="stylesheet" href="${pageContext.request.contextPath}/css/background.css"><link rel="stylesheet" href="${pageContext.request.contextPath}/css/layout.css"><link rel="stylesheet" href="${pageContext.request.contextPath}/css/glass.css"><link rel="stylesheet" href="${pageContext.request.contextPath}/css/form.css">
</head>
<body>
<canvas id="particleCanvas"></canvas>
<div class="glass-container"><h1>计算结果</h1><%String message = (String) request.getAttribute("message");Boolean valid = (Boolean) request.getAttribute("valid");Object type = request.getAttribute("type");Object area = request.getAttribute("area");%><p><%= message %></p><% if (valid != null && valid) { %><p>三角形类型:<%= type %></p><p>面积:<%= area %></p><% } else { %><p>面积:0</p><% } %><a href="<%= request.getContextPath() %>/">返回首页</a>
</div>
<script src="${pageContext.request.contextPath}/js/particle.js"></script>
</body>
</html>

4.4 动态粒子背景(particle.js)

window.onload = function() {const canvas = document.getElementById("particleCanvas");if (!canvas) return;const ctx = canvas.getContext("2d");function resize() {canvas.width = window.innerWidth;canvas.height = window.innerHeight;}resize();window.addEventListener("resize", resize);const mouse = { x: null, y: null, radius: 150 };window.addEventListener("mousemove", function(e) {mouse.x = e.x;mouse.y = e.y;});class Particle {constructor() {this.x = Math.random() * canvas.width;this.y = Math.random() * canvas.height;this.size = Math.random() * 4 + 1;this.speedX = (Math.random() - 0.5) * 1.5;this.speedY = (Math.random() - 0.5) * 1.5;}update() {this.x += this.speedX;this.y += this.speedY;if (this.x < 0 || this.x > canvas.width) this.speedX *= -1;if (this.y < 0 || this.y > canvas.height) this.speedY *= -1;let dx = mouse.x - this.x;let dy = mouse.y - this.y;let distance = Math.sqrt(dx * dx + dy * dy);if (distance < mouse.radius) {this.x -= dx / 25;this.y -= dy / 25;}}draw() {ctx.beginPath();ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);ctx.fillStyle = "rgba(255,255,255,0.8)";ctx.fill();}}const particles = [];for (let i = 0; i < 150; i++) particles.push(new Particle());function connect() {for (let a = 0; a < particles.length; a++) {for (let b = a; b < particles.length; b++) {let dx = particles[a].x - particles[b].x;let dy = particles[a].y - particles[b].y;let distance = dx * dx + dy * dy;if (distance < 12000) {ctx.strokeStyle = "rgba(255,255,255,0.08)";ctx.lineWidth = 1;ctx.beginPath();ctx.moveTo(particles[a].x, particles[a].y);ctx.lineTo(particles[b].x, particles[b].y);ctx.stroke();}}}}function animate() {ctx.clearRect(0, 0, canvas.width, canvas.height);particles.forEach(p => {p.update();p.draw();});connect();requestAnimationFrame(animate);}animate();
};

4.5 样式文件(glass.css / form.css等)

layout.css – 全局布局

html, body {margin: 0;padding: 0;width: 100%;height: 100%;overflow: hidden;font-family: "Microsoft YaHei";
}

background.css – 动态渐变背景 + Canvas定位

html, body {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden;
}
body {background: linear-gradient(-45deg, #0f2027, #203a43, #2c5364, #1a2a6c, #0f3460);background-size: 500% 500%;animation: gradientMove 15s ease infinite;
}
@keyframes gradientMove {0% { background-position: 0% 50%; }50% { background-position: 100% 50%; }100% { background-position: 0% 50%; }
}
#particleCanvas {position: fixed;left: 0;top: 0;width: 100%;height: 100%;z-index: -1;
}

glass.css – 毛玻璃卡片效果

.glass-container {width: 520px;padding: 35px;position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);background: rgba(255,255,255,0.12);border: 1px solid rgba(255,255,255,.2);backdrop-filter: blur(18px);-webkit-backdrop-filter: blur(18px);border-radius: 20px;color: white;text-align: center;box-shadow: 0 0 30px rgba(0,255,255,.25), 0 0 60px rgba(0,100,255,.2);animation: floatCard 4s ease-in-out infinite;
}
@keyframes floatCard {0% { transform: translate(-50%, -50%); }50% { transform: translate(-50%, -53%); }100% { transform: translate(-50%, -50%); }
}
.glass-container h1 {margin-bottom: 25px;font-size: 34px;letter-spacing: 2px;
}
.glass-container p {font-size: 18px;line-height: 35px;
}

form.css – 表单输入框与按钮样式

input {width: 90%;padding: 12px;margin: 12px 0;border: none;border-radius: 8px;outline: none;font-size: 16px;transition: .3s;
}
input:focus {box-shadow: 0 0 15px cyan;
}
button {margin-top: 15px;padding: 12px 35px;border: none;border-radius: 8px;cursor: pointer;font-size: 16px;color: white;background: linear-gradient(45deg, #00c6ff, #0072ff);transition: .3s;
}
button:hover {transform: scale(1.08);box-shadow: 0 0 20px cyan;
}

4.6 SpringMVC配置文件

springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><context:component-scan base-package="com.task8"/><mvc:annotation-driven/><mvc:resources mapping="/css/**" location="/css/"/><mvc:resources mapping="/js/**" location="/js/"/><mvc:default-servlet-handler/><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean>
</beans>

web.xml

<?xml version="1.0" encoding="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/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><display-name>task8</display-name><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

5. 本地部署与调试过程

  1. Eclipse中创建Dynamic Web Project,项目名task8,配置Tomcat 9.0运行时。
  2. 将Java类放入src/com.task8.beansrc/com.task8.controller
  3. 将JSP、CSS、JS文件放入WebContent对应目录。
  4. 检查springmvc-servlet.xmlweb.xml编码均为UTF-8。
  5. 运行Tomcat,访问http://localhost:8080/task8/

调试问题与解决

  • 初次访问出现404,原因是springmvc-servlet.xml中组件扫描路径写错,修改base-package="com.task8"后解决。
  • 静态资源(CSS/JS)无法加载,改为使用${pageContext.request.contextPath}动态获取项目路径解决。
  • 中文乱码:统一所有JSP页面编码为UTF-8,并在web.xml中配置字符编码过滤器。

图片1

图1:本地首页输入窗格效果

图片2

图2:本地结果页展示三角形类型与面积


6. 阿里云ECS服务器部署

  1. 上传项目:使用FTP将本地task8整个文件夹上传至ECS服务器的/tomcat/webapps/目录。
  2. 启动Tomcat:在服务器中执行startup.sh(Linux)或双击startup.bat(Windows)。
  3. 安全组配置:在阿里云控制台开放8080端口。
  4. 公网访问:浏览器访问http://118.31.44.31:8080/task8/

部署中遇到的问题

  • 最初访问出现HTTP 500,原因是缺少SpringMVC依赖JAR包,将spring-webmvcspring-context等JAR复制到WEB-INF/lib后解决。
  • 公网访问502错误,排查发现Tomcat未启动,重新启动后正常。
  • 确认ECS公网IP为118.31.44.31后,所有功能测试通过。

图片3

图3:云端首页输入窗格

图片4

图4:云端结果页展示


7. 实验小结(小组分工与感想)

本次实验是课程中首次完整采用SpringMVC框架进行Web应用开发,小组四人继续采用模块化协同开发模式,完成从需求分析、MVC架构设计、JavaBean业务逻辑、SpringMVC配置、JSP页面设计、本地测试到阿里云ECS部署的全流程。

7.1 方致沅(系统架构设计、SpringMVC框架搭建与核心业务逻辑)

我负责整体MVC架构设计、SpringMVC框架配置(DispatcherServlet、组件扫描、视图解析器)以及TriangleController的开发。调试过程中解决了Controller扫描路径错误导致的404问题,并对输入边长进行合法性验证(正数、三角形不等式),确保系统健壮性。

7.2 李润哲(页面视觉设计、动态背景效果与前端资源管理)

我负责前端页面设计,包括input.jspresult.jsp、四个CSS文件以及particle.js。采用深色渐变背景+毛玻璃卡片+Canvas粒子动画,使界面具有科技感。解决了静态资源路径错误(通过${pageContext.request.contextPath}统一引用),并优化了响应式布局。

7.3 王鑫杰(JavaBean开发、三角形判定算法与结果展示逻辑)

我完成了TriangleBeanTriangleJudgeTriangleArea三个核心JavaBean。实现了三角形合法性判断、类型判定(通过排序后比较平方和)以及海伦公式面积计算。调试中增加了非法边长保护(返回0面积),并解决了中文乱码问题(统一UTF-8编码)。

7.4 康奕彬(Tomcat部署、阿里云ECS发布与故障排查)

我负责本地Tomcat测试、云端环境搭建及公网发布。解决了一系列问题:补充缺失的Spring依赖JAR包、开放ECS安全组8080端口、排查Tomcat启动失败原因。最终成功通过http://118.31.44.31:8080/task8/公网访问。

7.5 团队协作总结

本次实验使我们深入理解了MVC设计模式、SpringMVC工作原理以及JavaBean在Web开发中的应用。通过解决404错误、中文乱码、静态资源失效、云端部署等工程问题,掌握了从开发到上线的完整流程。小组分工明确,沟通高效,为后续企业级Java Web开发打下了坚实基础。


8. 附录

  • 《Web编程技术》,余元辉主编,清华大学出版社,2014.5
  • 《JSP设计》(第三版),Hans Bergsten主编,林琪、朱涛江翻译,O'Reilly Media,Inc 2014年
http://www.rkmt.cn/news/1429307.html

相关文章:

  • Keil µVision打印设置优化指南
  • 5.30 太原黄金回收,今日大盘价附近报价 - 资讯纵览
  • 终极指南:如何快速掌握dnSpy .NET调试与反编译神器
  • 2026武汉五金工具展览会:解锁智能制造新风口
  • 2026年武汉留学中介推荐:五家优选深度解析 - 科技焦点
  • 训练素材库未做权属清洗?92%企业AI视频项目暗藏版权定时炸弹(含开源数据集合规性红黑榜)
  • 从WZ文件到游戏世界:Harepacker复活版深度技术指南
  • UVa 339 SameGame Simulation
  • 基于LoRa与ESP32的远程智能温控系统:无网络覆盖场景的自动化实践
  • 【Agent 开发】一文看懂三种 RAG 架构:Classic RAG、Graph RAG 与 Agentic RAG
  • 非标零件加工有哪些工艺?CNC、电火花、激光各有什么优缺点
  • 【A11】统一实体标识符(UEID)规范
  • 为什么92%的团队用Gemini生成报告仍被拒稿?——资深审稿人亲揭学术/合规双红线及5分钟修复法
  • 当Epson T3机器人遇上欧姆龙CJ2M:手把手教你用Fins TCP协议绕过Modbus限制
  • 基于树莓派打造可定制数字时钟:从硬件选型到软件配置全解析
  • AutoDock Vina终极指南:快速掌握分子对接神器,轻松完成药物筛选
  • 【Redis分布式缓存实战】第1章 分布式缓存前置认知:为什么企业首选Redis
  • 【系统学AI】15 RAG评测体系:RAGAS四维+TruLens+ARES全套方案
  • 洛谷-P11240 [KTSC 2024 R2] 回文判定 题解
  • 3DS游戏存档终极保护指南:用JKSM轻松备份和恢复你的游戏进度
  • DS4Windows技术深度解析:跨平台手柄映射架构设计与实现
  • 5步完全指南:掌握Unlock Music浏览器音乐解密终极方案
  • 合豚为什么更像“底层系统”,而不是普通设备商?
  • 【Gemini财务分析报告权威解读】:2024年Q2财报暗藏的5大现金流预警信号及3步应对法
  • 如何轻松下载抖音无水印视频:完整指南与实用技巧
  • Hitboxer:免费专业级SOCD按键重映射工具,彻底解决游戏输入冲突
  • 节假日亲子游玩好去处推荐,马岭天观登高祈福、山间游乐适配全年龄段 - 玖叁鹿geo
  • 终极Windows系统管理神器:Chris Titus Tech WinUtil一键优化完整指南
  • 2026年旧房翻新大揭秘!靠谱机构究竟该怎么选?
  • 技术方案:Figma-to-JSON实现设计文件与结构化数据的双向转换