
简介这是一套基于JavaWeb的证券分时数据监控管理系统完整源码与数据库文件主要面向Java Web技术初学者、正在做课程设计或毕业设计的高校学生以及需要快速搭建证券数据监控原型系统的开发者。系统实现了用户登录认证、证券分时行情的图形化监控、实时数据刷新、后台数据管理等功能前端采用HTML/CSS/JavaScript结合ECharts绘制分时走势图后端基于Servlet与Spring等Java技术栈处理业务逻辑并通过JDBC连接MySQL数据库执行增删改查整体遵循典型的MVC架构能够帮助学习者理解前后端数据交互、会话管理与权限控制流程。压缩包共81个文件包括38个Java源文件、7个XML配置文件、3个HTML页面、3个JavaScript脚本、5个CSS样式表、2个SQL数据库初始化脚本以及若干图片、字体、ECharts图表库和项目说明文档压缩包仅2.25MB目录结构按后端、前端、数据库与文档划分便于在IDE中直接导入并二次开发升级。目前已吸引182人学习下载内含完整可运行的项目源码和数据库初始化脚本既可作为课程设计的参考模板也能为证券类Web监控系统的企业级开发提供入门范本。1. 证券分时数据监控系统一份能直接跑的 JavaWeb 全栈监控源码证券分时数据监控系统核心是用户登录后能实时看到指定证券的分时价格曲线和成交量变化。这份资源不是教学片段而是一套完整的 JavaWeb 源码加数据库脚本前端登录页、监控主界面、ECharts 分时图都是成品后端是可打包的 Maven 工程sdsx.sql 建库脚本也一起给了。它解决的问题很具体——缺一个能演示、能答辩、能二次开发的证券行情监控 Demo尤其是 JavaWeb 课程设计和毕业设计场景。适合两类人一类是要交课程设计、需要能跑通能讲清楚的作品另一类是刚接触监控类系统想研究定时采集、数据落库、图表轮询这条完整链路的从业者。拿到手先跑通再按自己的需求改。2. 架构与数据链路从登录到分时图是怎么串起来的2.1 项目结构前后端目录分离先分清谁是谁解压压缩包顶层是 monitoringsystem 和 shine-sdsx-master 两套同名目录内容基本是同一份工程的两次导出实际使用认准带 Code 的那套。Code 是后端 Maven 工程FrontEnd 是纯静态前端两个目录分开摆这在课程项目和小型管理系统里很常见前端只负责展示后端只暴露 JSON 接口。FrontEnd 里几个关键文件login.html登录页配合 login.css、Init.css 完成样式输入用户名密码后跳转 index.htmlindex.html监控主页面引入 echarts.min.js 和 index.jsindex.js页面的数据中枢负责请求分时接口、组装图表配置、定时刷新echarts.min.js本地打包的 ECharts 压缩文件分时图全靠它渲染注意 echarts.min.js 是本地文件而不是 CDN 引用这点在答辩和离线演示时很有用——断网环境图表照样能画不会因为外网资源加载失败白屏。index.js 干的事可以归纳成三步取数据、拼 option、setOption。分时图和普通折线图的区别在于它有两个绘图区上半部分画价格线下半部分画成交量柱对应 ECharts 里两套 grid 和两套坐标轴。下面这段配置是这类监控页面最常见的基础写法// 分时图核心配置价格线 成交量双 Y 轴布局 var trendChart echarts.init(document.getElementById(trendChart)); var option { tooltip: { trigger: axis }, grid: [ { left: 60, right: 24, top: 30, height: 55% }, // 价格区 { left: 60, right: 24, top: 68%, height: 18% } // 成交量区 ], xAxis: [ { type: category, data: timeList, boundaryGap: false }, { type: category, gridIndex: 1, data: timeList, boundaryGap: false } ], yAxis: [ { type: value, name: 价格, scale: true }, { type: value, gridIndex: 1, name: 量 } ], series: [ { name: 分时价, type: line, data: priceList, smooth: true, symbol: none, lineStyle: { width: 1.5, color: #e64340 } }, { name: 成交量, type: bar, xAxisIndex: 1, yAxisIndex: 1, data: volumeList, barWidth: 4, itemStyle: { color: #3d7eff } } ] }; trendChart.setOption(option, true);注意几个参数grid 数组里第二个 grid 用top: 68%和height: 18%把成交量区压到图表下半部和股票软件的分时图布局一致series 里成交量 bar 通过xAxisIndex: 1, yAxisIndex: 1绑定到第二套坐标轴setOption(option, true)的第二个参数表示不合并旧配置、直接整体替换轮询刷新时能避免旧数据残留导致曲线拖尾。页面要动起来index.js 里一般会再起一个定时器每 3 秒拉一次最新分时数据把新点追加到数组里再重新 setOption。有的版本用 jQuery 的 $.ajax有的用 fetch逻辑一样// 每 3 秒向后端要一次最新分时点追加到图表 let lastTime null; setInterval(function () { fetch(/monitor/quote/latest?code stockCode lastTime (lastTime || )) .then(function (res) { return res.json(); }) .then(function (points) { if (!points || !points.length) return; points.forEach(function (p) { timeList.push(p.quoteTime); priceList.push(p.price); volumeList.push(p.volume); }); lastTime points[points.length - 1].quoteTime; // 增量游标 trendChart.setOption(option, true); }) .catch(function (err) { console.error(分时数据拉取失败, err); }); }, 3000);这里的 lastTime 是关键我一般叫它增量游标。前端记住最后一次拿到的时间点下次请求只带这个时间之后的数据避免每次把全天 240 个点重发一遍后端只需要按时间过滤接口压力小前端也不会因为数据量大而卡顿。如果你拿到手的源码里没有这个参数而是每次全量返回也正常只是效率差一些。2.2 后端链路Servlet 接口加数据库聚合后端是标准的 JavaWeb Maven 工程pom.xml 里主要依赖 Servlet API、MySQL JDBC 驱动和 JSON 序列化相关库没有上 Spring 全家桶。好处是结构直白、答辩好讲坏处是很多基础设施要自己写。实际项目里常见的分层是 Servlet 接收请求、DAO 查 MySQL、工具类转 JSON 返回。分时数据接口大致长这样// 分时行情接口按证券代码返回最近 N 条记录 WebServlet(/quote/latest) public class QuoteLatestServlet extends HttpServlet { Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String code req.getParameter(code); // 证券代码如 600519 String lastTime req.getParameter(lastTime); // 增量游标可不传 resp.setContentType(application/json;charsetUTF-8); ListQuote quotes QuoteDao.findAfterTime(code, lastTime); // 查库 resp.getWriter().write(JsonUtil.toJson(quotes)); // 转 JSON } }参数就两个code 指定看哪只证券lastTime 做增量过滤。前端把 code 写死在脚本里或者做成可下拉切换的选项lastTime 每次回传就构成了最简单的增量行情链路。DAO 层查库时用 PreparedStatement 绑定参数避免 SQL 拼接// 分时数据查询 DAO按代码和时间游标过滤 public ListQuote findAfterTime(String code, String lastTime) { String sql SELECT stock_code, quote_time, price, avg_price, volume, amount FROM stock_quote WHERE stock_code ? ; if (lastTime ! null) { sql AND quote_time ? ; } sql ORDER BY quote_time ASC LIMIT 100; // 用 PreparedStatement 绑定参数防止 SQL 注入 // 这里只示意拼装逻辑实际绑定在 try-with-resources 里完成 }那分时数据本身从哪来课程项目里最常见的做法是用一个后台定时任务Timer 或 Quartz每几秒往 stock_quote 表里插一条模拟行情前端轮询这张表就有数据看了。真实生产环境则是把定时任务替换成行情采集线程从行情服务商的接口拉数据再落库这个改造我在第 5 章单独讲。整体链路就是「定时任务造数 → MySQL 存 → Servlet 查 → JSON 返回 → ECharts 画」一环扣一环。2.3 数据库设计sdsx.sql 里的核心表长什么样sdsx.sql 是整套系统的初始化脚本导入之后表、数据、默认账号都在。这里面最值得看的是两张表证券基础信息表和分时行情表它们基本决定了整个系统的数据模型-- 证券基础信息表 CREATE TABLE stock_info ( stock_id INT PRIMARY KEY AUTO_INCREMENT, stock_code VARCHAR(10) NOT NULL COMMENT 证券代码, stock_name VARCHAR(32) NOT NULL COMMENT 证券名称, market VARCHAR(8) DEFAULT SH COMMENT 市场SH/SZ, update_time DATETIME COMMENT 最后更新时间 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 分时行情表每个时间点一行 CREATE TABLE stock_quote ( id BIGINT PRIMARY KEY AUTO_INCREMENT, stock_code VARCHAR(10) NOT NULL COMMENT 证券代码, quote_time DATETIME NOT NULL COMMENT 行情时间, price DECIMAL(10,2) COMMENT 最新价, avg_price DECIMAL(10,2) COMMENT 均价线, volume BIGINT COMMENT 累计成交量手, amount DECIMAL(18,2) COMMENT 累计成交额元, KEY idx_code_time (stock_code, quote_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;字段含义我列一下字段类型说明stock_codeVARCHAR(10)证券代码两张表的关联键quote_timeDATETIME行情时间点分时图上 X 轴priceDECIMAL(10,2)最新价分时主曲线avg_priceDECIMAL(10,2)均价线很多分时图会叠加第二根线volumeBIGINT累计成交量底部柱状图提示价格用 DECIMAL 不用 FLOAT是为了避开浮点误差联合索引 idx_code_time 就是给「按代码和时间查分时」这个高频查询准备的数据量大了以后能省掉全表扫描。另外 sys_user 表管登录初始账号密码都写在这张表里导入后可以用SELECT * FROM sys_user;查出来别去赌什么默认密码。压缩包里还有 111.eapx那是 Enterprise Architect 的 UML 工程文件画用例图、时序图用的源文件答辩画图直接改它就行汇报 PPT 就是现成的答辩材料。3. 本地复现从建库到浏览器里看到分时图的完整步骤3.1 环境准备版本别乱配这套 JavaWeb 项目建议按下面的组合去配环境版本不匹配的坑我在第 4 章会细讲这里先统一列出来组件推荐版本说明JDK1.8项目按 1.8 编译装 17 反而可能不适配Maven3.6.x3.8 对镜像源更敏感不是不能用Tomcat8.5 或 9.0别用 Tomcat 10Servlet 包名从 javax 改成 jakarta老代码编译不过MySQL5.7 或 8.05.7 更稳8.0 需要换驱动类名见 3.3IDEA 建议 2020 之后任意版本。这几个版本任何一个差了启动阶段就会开始翻车与其后面排查不如一开始就对齐。3.2 导入数据库先建库再执行脚本打开终端先建库再导脚本。库名要和代码里的连接配置一致这套系统的默认库名一般是 sdsxmysql -uroot -p CREATE DATABASE sdsx DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; exit; # 导入脚本 mysql -uroot -p sdsx sdsx.sql建库时指定 utf8mb4 很关键很多乱码问题就是在这里埋下的。导入成功后进 MySQL 验证一下USE sdsx; SHOW TABLES; SELECT COUNT(*) FROM stock_quote;能查到表、分时表里有数据说明脚本正常。如果提示 SQL 语法错误大概率是 MySQL 版本太老5.5 以下或脚本里带了版本敏感的关键字优先换 5.7 再试。3.3 改数据库连接配置用 IDEA 把 Code 目录作为 Maven 工程导入找到数据库连接配置文件老 Maven Web 项目一般叫 db.properties 或 jdbc.properties改成自己的连接地址、账号密码jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/sdsx?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai jdbc.usernameroot jdbc.password你自己数据库的密码参数逐个说useUnicodetrue 和 characterEncodingutf8 是防中文乱码的必须带serverTimezoneAsia/Shanghai 是 MySQL 8.0 的硬要求不加会报时区异常如果你本地是 MySQL 5.7驱动类用 com.mysql.jdbc.Driver如果是 8.0要改成 com.mysql.cj.jdbc.Driver同时 pom.xml 里的 mysql-connector-java 版本提到 8.0.x。3.4 Maven 打包部署到 Tomcat配置改完先构建一次看看依赖有没有问题mvn clean package -DskipTests命令含义clean 清掉上次的 targetpackage 把项目打成 war 包生成在 target 目录下-DskipTests 跳过测试类省得因为环境差异在单测上报错。构建成功后把 war 包丢进 Tomcat 的 webapps 目录再启动cp target/monitoringsystem.war 你的Tomcat目录/webapps/ 你的Tomcat目录/bin/startup.sh然后看启动日志tail -f 你的Tomcat目录/logs/catalina.out注意日志里打印的 Context path比如Context path: /monitoringsystem这个路径就是你后面访问 URL 的一部分少了它就是你后面 404 的根源。前端页面有两个放法一个把 FrontEnd 整个目录拷到 webapp 下和 war 包共存访问http://localhost:8080/monitoringsystem/login.html另一个是前端独立起静态服务但那样后端接口要额外配跨域过滤器课程项目里一般用第一种省事。3.5 登录验证与数据刷新确认浏览器访问登录页用 sys_user 表里的账号登录。登录成功进入 index.html 后做三件事第一看分时图是否渲染出价格曲线和成交量柱第二盯着图表等 6 到 10 秒看曲线有没有往前推进这一步验证定时任务和轮询都在工作第三按 F12 打开控制台切 Network 面板找到 quote 接口确认返回的 JSON 里 quote_time 字段是递增的。也可以回 MySQL 里确认后台在持续写数SELECT stock_code, COUNT(*), MAX(quote_time) FROM stock_quote GROUP BY stock_code;每次查询 count 都在涨、max 时间在往后走说明造数任务活着。三步都过这套系统就真正跑起来了后面改代码心里就有底了。4. 避坑指南分时图不动、白屏、乱码与连库失败的真实排查4.1 前端图表相关空白和白屏别急着改代码现象一登录能跳转到 index.html但整个图表区域是空白控制台也不报错。原因这是 ECharts 最常见的坑装图表的容器 div 设置了width: 100%; height: 100%但它的父级没有实际高度浏览器算下来容器高度是 0图表画在一个零高度的盒子里自然什么都看不见。解决把容器的 CSS 改成固定高度比如#trendChart { width: 100%; height: 480px; }或者在 index.js 里加一行兜底window.addEventListener(resize, function () { trendChart.resize(); });。我一般两个都做页面全屏和窗口缩放都不会翻车。现象二分时图一动不动等了一分钟曲线还在原地。原因用 F12 切 Network 看 quote 接口通常是三类问题——接口 404说明前端请求路径和后端 Servlet 映射对不上接口通了但返回空数组说明后台定时任务没在往 stock_quote 表里写数还有一个隐蔽情况是前端和后端分开部署浏览器跨域请求被拦。解决404 就去核对 FrontEnd 里 index.js 的请求地址和 Servlet 的WebServlet路径context path 要带对返回空就去看定时任务日志确认任务有没有启动跨域就在后端加一个最简 CORS 过滤器设置Access-Control-Allow-Origin: *或者干脆把前端放进 webapp 里同源访问后一种更省事。4.2 部署与数据库相关404、乱码和时区现象三Tomcat 起来了localhost:8080 能打开但项目路径访问就是 404。原因war 包名和实际 context path 不一致。IDEA 里部署时可能设置了自定义 context path或者 war 包被改过名浏览器里还按老路径访问。解决看 catalina.out 里Context path实际打出来的值照抄到 URL 里想省事就把 war 改名成 ROOT.war 重新部署直接访问http://localhost:8080/login.html不用带项目路径。现象四登录后页面上的证券名称全是问号或乱码。原因建库时用了默认字符集可能是 latin1或者连接串没带 characterEncodingutf8中文在入库和查询两个环节被转没了。解决按第 3 章的建库语句重建数据库指定 utf8mb4连接串补上useUnicodetruecharacterEncodingutf8同时确认 index.html 的meta charsetutf-8。三个环节都对齐中文就不会出问题。现象五MySQL 8.0 下启动报错日志里是 ClassNotFoundException 或 Communication link failure / timezone 异常。原因驱动类名不对或者驱动 JAR 版本和 MySQL 8.0 服务器不匹配8.0 强制要求 JDBC 连接串里带 serverTimezone。解决pom.xml 里把 mysql-connector-java 升到 8.0.x驱动类改成 com.mysql.cj.jdbc.Driver连接串末尾加serverTimezoneAsia/Shanghai。整套改完重新mvn clean package再部署一次。排查这类问题我习惯按「先看日志、再查配置、最后怀疑版本」的顺序走能少走不少弯路。5. 改造进阶把模拟行情替换成真实行情源的思路跑通之后这套系统就像一个能改的骨架最大的改造点就是把模拟数据换成真实行情。方向是保留前端轮询和图表逻辑不动只换后端数据来源——写一个行情采集线程定时从行情接口拉数据落库前端照旧查表// 行情采集线程每 5 秒批量拉取一次真实行情并落库 public class QuoteCollector implements Runnable { private volatile boolean running true; Override public void run() { while (running) { // 从行情服务商接口批量拉取注意限频 ListQuote quotes MarketApi.fetchQuotes(stockCodes); QuoteDao.batchInsert(quotes); // 批量写入 stock_quote try { Thread.sleep(5000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } }这里有三个注意点一是行情接口普遍限频别一只证券开一个线程要批量拉取二是 stock_quote 表要定期清理只保留当天数据否则表越滚越大查询越来越慢三是真实行情接口的字段名和表结构往往对不上写个 DTO 做字段映射别在 DAO 层硬编码。再往下走可以加一条价格异动提醒前端每轮拉完数据对比上一根的价格涨跌幅超过阈值就把曲线上的点标红同时在页面上弹一条提示。这就是把监控系统往「监控加告警」的方向推进了一小步答辩时能多讲一个亮点。从那以后我每次拿到这类带数据库脚本的 JavaWeb 源码都会强制先走一遍从建库到部署的完整流程确认能跑再动代码——这个习惯替我挡掉了至少一半的伪报错。希望帮到你。本文还有配套的精品资源点击获取