news 2026/10/20 9:57:23

基于SSM+Vue的天气查询毕设:从选题架构到部署上线的完整实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于SSM+Vue的天气查询毕设:从选题架构到部署上线的完整实战

又一个毕设季,后台经常有人问我:“不想做商城系统,也不想做博客了,有没有一个题目既不像玩具、又不会把自己写崩?”我的回答通常是同一个:天气查询。别小看这个小题目,它几乎没有支付、权限、并发这些“毕设杀手”,却能把需求分析、前后端分离、接口设计、数据库建表、部署上线切成一条完整的链路。这篇文章就以一套基于SSM加Vue的简单天气查询App为例,完整复盘毕设从选题、架构、编码、论文到打包交付的全过程。不管你现在是临时换题,还是想把项目做得更稳,这套思路都能直接用。

1. 毕设选题为什么要选“天气查询”:一个被低估的稳妥型题目

1.1 为什么它比商城、外卖项目“抗造”

很多同学对毕设难度的判断是“功能越多越好”,于是选了商城、外卖、校园二手交易,结果做到后期才发现:支付接口需要资质、地图定位需要权限、消息通知需要WebSocket,这些复杂点任何一个都可能把进度卡死。而天气查询的系统边界非常清晰,核心需求就是“用户查天气、看预报、保存常用城市”。它不依赖复杂硬件,不需要第三方支付的审核流程,数据源也能通过网络接口稳定获得,所以从工作量上更容易收口。

更重要的是,这种“看似简单”的题恰恰考察你做完整项目的工程能力:你同样要设计数据库、写接口、处理前端交互、做异常兜底,一个完整软件开发流程的每一步都不会缺席。换句话说,它把技术栈里最难应付的“变量”全部剔掉,只留下最基础、最核心、也最能体现学习成果的东西。

1.2 SSM和Vue的搭配真的“过时”了吗

目前的教学环境里,SSM仍然是很多学校课程设计的默认技术栈:Spring负责管理对象,SpringMVC负责接收请求,MyBatis负责操作数据库,三者配合多年,资料极多。Vue则用来构建页面,页面通过JSON和后端通信。两者组合,就是典型的前后端分离结构:前端一个工程,后端一个工程,部署时前端静态文件可以丢进Nginx,后端war包丢进Tomcat。

技术方案优点缺点适合的场景
传统JSP资料最多,页面直出,简单前后端耦合,维护性差老项目改造,教学示例
SSM + JSP后端分层清晰,页面开发快接口复用差,前端表现力受限单机版课设,不强调前后端分离
SSM + Vue前后端分离,交互体验好,结构清晰前后端要联调,部署多一步毕设首选,答辩能讲出完整分层
Spring Boot + Vue配置简化,启动快,社区主流如果学校平时不教,答辩容易被追问有Spring Boot基础的同学

闭设答辩里,老师通常最熟悉的还是SSM这套,你讲得出“Controller调Service,Service调Mapper”这条链路,他基本就不会深追。Spring Boot固然新,但对基础一般的同学来说,配置越简单反而越难解释底层原理。

1.3 什么样的学生适合这个题目

这个题不是“高手专用”,反而适合三类人:第一类是基础一般、只想完整走通一个项目流程的;第二类是系统设计能力偏弱、需要题目自带清晰业务逻辑的;第三类是担心答辩被追问底层、希望每个知识点都在自己能力范围内的。

当然它也有短板:没有算法亮点、没有高并发话题。所以论文里必须把“设计过程”写厚,把“实现细节”写具体,用工程完整度去弥补技术深度。这一点后面论文部分会详细展开。

2. 系统架构与数据链路:从Vue页面到第三方天气数据源

2.1 一条查询请求到底经过了哪些环节

先理清整体数据流:用户在Vue页面输入城市名,前端把请求发给自己的后端服务,后端做参数校验,查一下数据库里有没有这个城市,然后带着自己配置的天气服务凭证去请求第三方天气数据服务商,拿到JSON后把需要用到的字段解析出来,再组合成统一的结构返回给页面;同时后端会把这次查询记录写入历史表,方便后续做“最近查询”功能。

这条链路看起来长,但每一段都是为了解决一个具体问题。前端只负责展示和交互,不直接接触外部数据源;后端负责业务处理和外部通信;数据库负责用户、收藏、历史的持久化。划分清晰之后,论文里的架构图能画,答辩能讲,写代码也不会东西一团浆糊。

2.2 为什么天气数据必须由“后端代理”获取,而不是前端直连

有的同学图省事,把天气服务商的接口地址直接写在Vue的代码里,用浏览器去请求。这在毕设demo里能跑,但答辩要问起来往往答不上来:第一,凭证会在前端源码里暴露,这是安全隐患;第二,很多天气接口有访问频率限制,页面一刷新就可能把免费额度刷爆;第三,跨域问题会让联调变得很痛苦。

所以正确做法是后端包一层代理接口,前端只调自己的后端地址,由后端去和外部天气服务打交道。这样做还有一个额外好处:你可以在Service层做缓存、做降级,论文里能多写一整节“健壮性设计”。这块内容虽然简单,却是区分“会调接口”和“会做系统”的关键分水岭。

2.3 数据库表结构:小项目也要有四张表

天气查询看起来不涉及业务,但我还是设计了四张核心表,既满足功能,又让ER图有东西可画:

  • 用户表(t_user):用户id、用户名、密码、创建时间。
  • 城市表(t_city):城市id、城市名、省份、经度、纬度。
  • 收藏表(t_favorite):收藏id、用户id、城市id、创建时间、是否为默认城市。
  • 查询记录表(t_history):记录id、用户id、城市名、天气现象、温度、湿度、查询时间。
CREATE TABLE `t_user` ( `id` INT NOT NULL AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL, `password` VARCHAR(100) NOT NULL, `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `t_city` ( `id` INT NOT NULL AUTO_INCREMENT, `city_name` VARCHAR(50) NOT NULL, `province` VARCHAR(50) DEFAULT NULL, `longitude` DECIMAL(10, 6) DEFAULT NULL, `latitude` DECIMAL(10, 6) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `t_favorite` ( `id` INT NOT NULL AUTO_INCREMENT, `user_id` INT NOT NULL, `city_id` INT NOT NULL, `is_default` TINYINT(1) DEFAULT 0, `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `t_history` ( `id` INT NOT NULL AUTO_INCREMENT, `user_id` INT NOT NULL, `city_name` VARCHAR(50) NOT NULL, `weather_text` VARCHAR(50) DEFAULT NULL, `temperature` VARCHAR(10) DEFAULT NULL, `humidity` VARCHAR(10) DEFAULT NULL, `query_time` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

为什么用四张表而不是一张大表?因为每张表都有独立存在意义:用户表是所有系统的基础;城市表是为了统一城市名,避免用户输入“北京”和“北京市”造成重复;收藏表支撑常用城市列表;历史表支撑首页的“最近查询”。答辩时被问“为什么要这张表”就有话可说。

3. 后端SSM骨架搭建:Controller、Service、Mapper三层怎么分

3.1 后端工程目录与依赖清单

后端是Maven工程,包结构可以这样分:controller、service、mapper、entity,再加一个config包放跨域配置和自定义拦截器。依赖上,spring-webmvc、mybatis、mybatis-spring、druid连接池、mysql-connector-java、httpclient、JSON解析库,这些基本够用。

这里特别提醒:SSM工程里调用外部天气接口时,很多人会漏掉HTTP客户端的依赖,导致后端代理接口一直报“找不到类”。如果你觉得原生的HttpClient API太啰嗦,可以再把请求封装到一个单独的WeatherApiClient类里,所有外部调用都走这一个入口,后面统一加缓存、加超时也比较方便。

3.2 Controller的URL该怎么规划

接口设计遵循一个约定:/api/weather/now、/api/weather/daily、/api/weather/history、/api/city/search、/api/user/login、/api/user/register、/api/fav/add、/api/fav/list。用REST风格,语义清楚,前端联调时一眼能看出每个接口是干什么的。

@RestController @RequestMapping("/api/weather") public class WeatherController { @Resource private WeatherService weatherService; @GetMapping("/now") public Result getNowWeather(@RequestParam String city) { return Result.ok(weatherService.getNowWeather(city)); } @GetMapping("/daily") public Result getDailyWeather(@RequestParam String city) { return Result.ok(weatherService.getDailyWeather(city)); } }

别在Controller里写业务,它只负责参数接收和结果包装。所有查询逻辑放在Service层,数据库访问放在Mapper层,答辩被问到分层时才能讲清楚。Result是一个统一返回结构,包含code、message、data三个字段,前端所有请求都按这个格式解析。

3.3 第三方天气接口对接的JSON解析

Service层里写一个WeatherApiClient,用HTTP客户端GET请求,带上城市参数和凭证,拿到JSON字符串后用JSON库解析。这里要特别注意:不同天气服务商的字段名不一样,有的叫condition,有的叫text;有的温度字段是字符串,有的是数字。所以不要在Service里到处散落解析代码,而是统一封装成自己的WeatherDetail实体类。

天气接口返回的结构通常是这样的:

{ "code": "200", "updateTime": "2025-05-11T16:35:00+08:00", "now": { "temp": "24", "feelsLike": "25", "text": "多云", "windDir": "东南风", "windScale": "2", "humidity": "60" }, "daily": [ { "date": "2025-05-11", "tempMax": "27", "tempMin": "18", "text": "多云" } ] }

解析后,只挑前端真正需要的字段返回,别把外部接口的原始JSON一股脑丢给前端,那样既不安全,也会让页面字段乱掉。这一步对毕设来说,就是“自定义DTO”的应用,论文里可以专门写一小节说明为什么要做字段裁剪和结构统一。

3.4 收藏和历史记录怎么用事务保证一致性

有一个容易出错的点:收藏操作需要验证用户是否存在、城市是否存在,然后插入收藏表。如果验证通过后插入时服务出问题,用户侧体验就是“点了收藏但没存住”,所以Service方法上要加事务注解,保证要么全成功、要么全回滚。

但历史记录插入就不一样,它发生在天气查询成功之后,不应该因为插入历史失败导致天气数据返回失败,所以这个操作不需要做成强事务,用try-catch包住,失败时写日志即可。两者区别在于:什么时候必须保证一致性,什么时候可以容忍局部失败。答辩时如果能说清这一点,比单纯背“事务隔离级别”的概念要加分很多。

4. Vue前端的页面落地与跨域联调细节

4.1 Vue2、Vue3与UI库怎么选

毕设环境里,Vue2加Element UI的教程存量最大,遇到问题几乎都能搜到,适合求稳。如果学校要求较新,用Vue3加Element Plus也行,但要注意部分组件API有差异。整套页面复杂度不高,无外乎布局、输入框、按钮、卡片、列表,所以完全没必要引入重型组件库。

前端工程目录建议按组件拆分:Header、SearchBar、WeatherCard、ForecastList、HistoryList。每个组件只管一块内容,代码量小,调试方便,论文里也好截图说明。

4.2 首页天气展示与城市切换的实现逻辑

核心页面做的事情:顶部输入城市名,点搜索后调用后端接口,拿到WeatherDetail渲染到卡片上。城市切换有两种做法:一种是在输入框里重新搜索,另一种是点击收藏列表里的城市直接触发查询。两种方式都调用同一个fetchWeather方法。

async fetchWeather(city) { this.loading = true try { const { data } = await this.$http.get('/api/weather/now', { params: { city } }) this.weather = data.data } catch (e) { this.$message.error('查询失败,请稍后重试') } finally { this.loading = false } }

注意这里通过后端代理调用,前端代码里没有任何外部服务商地址和凭证,和前面说的“后端代理”设计是呼应的。搜索按钮加一个空值校验,城市为空时直接提示,避免无效请求把后端日志塞满。

4.3 七日预报与生活指数的页面组织

七日预报用卡片列表平铺,生活指数(穿衣、洗车、紫外线占用一行图标加文字展示)即可。这些数据在后端Service里已经统一成自己的结构,前端只需要遍历渲染。页面不复杂,但要注意空数据状态:城市名输错、第三方服务商返回异常,前端必须渲染“暂无数据”而不是白屏。

建议在页面加载时默认查询一个常用城市,比如首页进入就显示当前城市天气,这样演示效果比空页面好很多。也可以让页面记住上次查询的城市,用localStorage存起来,用户刷新后自动加载上次的城市天气。

4.4 跨域配置与Axios封装

前端开发时最容易卡住的是跨域。我用Vue CLI自带的devServer代理,在vue.config.js中配置:

module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } }

这样前端请求/api/weather/now会由Node开发服务器自动转发到后端地址,本地联调不需要在后端单独开CORS。但打包部署后如果前后端分属两个端口,还要在后端全局配置跨域拦截器。很多同学本地能跑、部署后却不显示数据,多半就是漏了这一步。

Axios封装时,统一处理后端返回的code字段,比如code不是200就弹提示并抛错,避免每个页面重复写一堆判断逻辑。拦截器里还可以统一追加token到请求头,登录模块和收藏模块都会用到。

5. 论文撰写顺序与答辩常见的“重系统、轻设计”问题

5.1 论文的章节应该怎么排

毕设论文一般七到八章,顺序大致是:摘要、绪论、关键技术、需求分析、系统设计、系统实现、系统测试、总结展望。天气项目的特点是每个章节都有实在内容可写,不会出现“设计章全是代码粘贴”的情况。

比如行列:“关键技术”一章可以只讲SSM三层架构、Vue组件化、HTTP接口交互和JSON数据结构;“系统设计”一章有架构图、ER图、每张表的字段说明;“系统实现”一章按模块拆,登录注册、搜索天气、收藏列表、历史记录各写一小节;“系统测试”一章放功能测试用例表。整个论文的逻辑就是从需求到设计再到实现测试,层层递进。

5.2 代码和论文到底谁先写

我建议代码先行,但要做到“边开发边截图”。每完成一个功能模块,立刻把界面截图、接口返回结果、测试日志保存好,同时记录遇到的问题和解决方法。这些素材最后会变成论文第六章的界面图和测试数据。

如果先写论文再补功能,就会出现论文里的截图和当前系统界面不一致的情况。答辩时老师现场看一眼页面,再翻一翻论文,两张图对不上,印象分会大打折扣。反过来,如果代码先跑通,论文只是把已经发生的内容记录下来,整个过程会顺畅很多。

5.3 图表规范与“只贴代码”的误区

论文中不要贴Tomcat控制台的乱码截图,也不要截一堆“程序运行成功”的证明图。真正有用的是三类图:系统架构图、数据库ER图、核心模块界面截图。表格则主要是“功能测试用例表”,比如输入城市名、预期结果、实际结果、是否通过。这张表越完整,越能体现测试思维和工程习惯。

所有图表要编号、加标题、在正文中要有文字引用,比如“如图5-1所示”,而不是孤零零放一张图在文档里。答辩老师翻到第六章时,通常会先看图再看文字,图如果是自己画的、能说清来龙去脉,就是很大的加分项。

5.4 答辩时最怕被问的五个问题

问题方向建议回答思路
第三方天气接口挂了你怎么办后端会做简单缓存,接口异常时提示用户稍后再试,而不是直接崩溃
密码为什么不存明文表示在设计时考虑过安全问题,用加盐哈希处理,并说明选型原因
查询历史表数据越来越多怎么办分页查询或只展示最近20条,SQL里加上LIMIT,必要时做定期清理
前端请求报错怎么排查先看浏览器Network面板,再看后端日志,逐步定位是前端参数还是后端逻辑问题
为什么不直接用Spring Boot结合学校课程安排,强调SSM分层更明显、对底层原理理解更深入,但表示自己也了解Spring Boot的便利性

每个问题不需要长篇大论,关键是能把自己的设计思路讲清楚。模板背熟没用,因为老师会根据你的项目问细节,只有真的动手写过、踩过坑,才能答得自然。

6. 从调试到打包:交付前最容易翻车的几个小地方

6.1 接口凭证千万别写死在页面里

第三方的天气服务凭证要放在后端配置文件里,并且区分开发环境和生产环境,比如用两个配置文件或者占位符切换。这样即使代码交给别人,也能避免密钥泄漏。天气服务商的免费额度通常有限,调试时建议在Service层加一个简单缓存:一分钟内同样城市不重复请求外部接口,直接返回缓存数据。这个缓存用HashMap加过期时间就够用,没必要为一个小场景上Redis,徒增复杂度。

6.2 数据库初始化脚本要能一键执行

毕设验收时最尴尬的场景是老师说“现场跑一下”,你却说“要先把数据库手动导一下”。正确做法是准备一个init.sql,包含建库、建表、插入常用城市和测试用户。脚本必须自包含、可重复执行,建表和删表之间用IF EXISTS兜底。现场只要执行一条命令就能把环境拉起来,这种细节会让答辩印象分高一大截。

6.3 前端打包后的部署路径问题

Vue打包默认资源路径相对路径,但放在Tomcat下如果部署在子级路径,偶尔会碰到静态资源404。稳妥做法是:把前端打包后的dist目录放到Tomcat的webapps/ROOT下,后端war包部署到同一个Tomcat,前端请求同一域名的/api,等于规避了大部分跨域问题。

如果后端在8080端口、前端在9090端口,又不想配Nginx,就一定要在后端加CORS配置。这两种部署方式我都试过,后者在答辩现场会因为浏览器安全策略带来很多不确定性,能选前者就尽量选前者。

6.4 交付前按这个清单走一遍

  • 后端war包能独立启动,不依赖IDE。
  • 前端dist页面能正常打开,浏览器控制台无报错。
  • init.sql可重复执行,测试账号可登录。
  • 天气接口能正常返回,城市名输入“北京”和“北京市”都能查到。
  • 论文里的截图与当前系统界面一致。
  • 答辩PPT控制在15分钟以内,重点是架构图、ER图、核心界面和测试表。
  • 准备一份300字以内的项目介绍,应对老师开场“你这个项目做了什么”的提问。

我个人在操作中的体会是:这套题目最大的价值不是“写完了”,而是把它当成一次完整的工程演练。你会在联调时发现接口字段对不上,在打包时发现路径不对,在答辩前发现论文截图和当前页面不一样,这些坑都是真实项目里每天都在发生的。项目本身可以简单,但流程不能简化;天气查询App这份毕设最大的加分项,是让老师看到一个学生从头到尾完整做事、遇到问题能自己解决的过程。

最后再分享一个习惯:在项目根目录放一个README.md,把启动步骤、测试账号、接口文档、常见报错都写清楚。这不光帮自己备答辩,也是代码交付的基本素养。天气查询看起来是个小题目,但只要把这条完整的链路走通,你收获的远远不止一份毕设。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 9:56:28

文本切分器实测:分隔符顺序如何改变切分结果

版权与内容来源声明 本文为原创整理。文中涉及官方文档、开源仓库、论文与公开报道的内容,均在附表 A 中标注来源;引用官方原文保持原样,不作改写。文中命令、版本号与界面截图以本文成文时的实测/核验结果为准,标注「待验证」的部…

作者头像 李华
网站建设 2026/10/20 9:55:59

去掉向量数据库:Sirchmunk用倒排索引与反馈实现自进化搜索

最近在折腾一个新的搜索项目,名字叫 Sirchmunk,核心思路一句话就能讲清楚:完全不要向量数据库,把搜索引擎做成一个能自己根据用户反馈持续进化的系统。是的,你没看错——不依赖那些动辄几十万维度的嵌入向量&#xff0…

作者头像 李华
网站建设 2026/10/20 9:55:57

选山东效果好的背单词软件品牌推荐?先搞懂这件事再买

“背单词和阅读哪个先?顺序搞反了,再好的工具也白搭。” 家人们,我花了3个月把主流背单词工具翻了个底朝天,又请教了几位英语老师,发现大多数人焦虑的根本不是工具不够多,而是单词记忆逻辑压根没理顺。这篇…

作者头像 李华
网站建设 2026/10/20 9:54:35

单片机计算机毕设之基于WIFI的指纹刷卡门禁与摄像头云端监控装置设计 基于STM32的智能门禁云平台管理与视频监控系统设计(033009)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/10/20 9:54:24

VS+MFC实战:Gerber光绘文件读取与分行显示

简介:这份资源面向使用 Visual Studio 与 MFC 进行桌面开发的 C 学习者,以及需要查看 PCB 设计文件的工程师,解决 Gerber 文件内容难以直观浏览的问题。项目基于 MFC 框架编写,通过 CFileDialog 选择 Gerber 文件,解析…

作者头像 李华
网站建设 2026/10/20 9:54:12

碰碰好评卡核心功能全链路开发实战与落地部署经验指南

碰碰好评卡核心功能全链路开发实战与落地部署经验指南 碰碰好评卡是本地生活、电商、社区服务等场景下,连接商户与用户的评价运营工具,能够帮助商家实现公开平台好评的正向引导,同时为用户提供匹配的权益激励,近年在多个垂直行业得…

作者头像 李华