ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

毕业设计实战:Spring Boot+Thymeleaf+AI智能天气出行系统解析

2026/9/2 3:42:37 拓冰建站 浏览量
毕业设计实战:Spring Boot+Thymeleaf+AI智能天气出行系统解析 每年都有不少同学在毕业设计选题里看到一个几乎一模一样的名字“基于 Spring Boot Thymeleaf AI 的智能天气出行服务系统”。乍一听非常“新”有 AI 大模型有天气数据有出行规划听着比学生管理系统、图书管理系统高级不少。但真正动手以后很多人会发现这个题目的难点根本不是“接入大模型”而是怎么让页面、后端、天气接口、AI 接口、数据库几个环节串成一条稳定可演示的链路。我见过太多人卡在同一个地方花了一周研究大模型 API调通了之后才发现天气接口又报了 401页面表单提交后返回 500数据库字段和你写的前端属性对不上最后演示时脑子一片空白。这个题目的价值恰恰不体现在“AI 有多聪明”而是你是否能用工程化的方式把一个不稳定的外部能力嵌入到一个确定的业务系统里。这篇文章不想再复制一段“项目介绍”而是想从技术选型、功能设计、落地步骤、答辩准备几个维度把这类毕业设计真正需要想清楚的问题拆开讲一遍。1. 先想清楚这个毕业设计到底在考察什么能力1.1 不是堆新技术而是把一条业务链路跑通很多同学选这个题目是被“AI 大模型”四个字吸引的觉得只要把大模型接进来就比传统管理系统高出一截。但毕业设计的评分标准通常不会因为“用了大模型”就直接给高分。老师更关心的是你能否把一个需求描述变成一套可运行、可演示、可解释的系统。这个题目真正的业务链路是用户打开页面 - 填写出发地、目的地、出行日期 - 系统查询两地天气 - 系统结合天气数据和用户偏好生成出行建议 - 页面展示结果 - 用户历史记录被保存。AI 大模型只是其中一个环节它的作用是生成“天气解读”和“出行建议”。如果只做了大模型对话没有天气数据联动这个系统就只是一个聊天框包装如果只做了天气查询没有 AI 建议那也只是一般的信息管理系统。在开始写代码之前先画一张链路图把所有环节标出来然后再决定先实现哪一块。这个动作比写代码更能决定你能不能按时完成。1.2 从需求拆解看系统由哪几块组成把这个题目拆开它至少包含四个独立模块模块核心功能关键技术点难度评估用户模块注册、登录、偏好设置Spring Boot 拦截器、Session、数据库设计中等天气模块查询实时天气、未来预报调用第三方天气 API、解析 JSON、异常兜底偏低出行模块输入出发地目的地日期生成出行计划业务规则 数据组织与 AI 模块联动中等AI 模块基于天气和出行意图生成建议大模型 HTTP 接口调用、提示词设计、流式/非流式处理中等这一张表看起来简单但它说明了一个关键判断这个题目的难点不是某一个单点技术特别深而是模块与模块之间的“衔接工作量”比想象中大。天气接口返回的字段、大模型返回的格式、页面上要展示的数据结构如果不提前统一设计后面会出现大量因为字段不匹配而导致的返工。1.3 给这个题目一个评价框架我建议你在动手前先拿下面的标准给自己打分功能完整度是否覆盖了用户、天气、出行建议、历史记录、页面展示。链路稳定性断网或接口异常时系统是否还能演示。代码结构Controller、Service、Client 是否分层是否把外部接口调用封装成了独立组件。数据设计用户、行程记录、AI 调用记录是否存在合理表结构中。文档一致性设计文档里的架构图、流程图、功能描述和实际代码是否对得上。这套评价框架不是学校官方标准但它能帮你避开“功能看着很多但跑不通”的风险。毕业设计不是技术竞赛它更像是一次完整的软件工程训练把模糊需求转化为可运行交付物的能力。2. 技术选型为什么是 Spring Boot Thymeleaf AI 大模型2.1 Spring Boot 负责解决什么问题Spring Boot 在这个项目里的角色很明确它负责后端服务、请求路由、业务逻辑和模板渲染。相比传统 SSM 框架Spring Boot 的自动配置能让项目省掉大量 XML 配置尤其适合毕业设计这种需要在有限时间内跑通完整链路的场景。如果只是做一个小的服务系统Spring Boot 内嵌 Tomcat打包后一个 jar 就能运行。答辩时老师问“项目怎么启动”你只需要说“启动 Application 类访问 8080 端口”即可。这一点在演示现场非常重要因为演示环境往往不给你时间配复杂的部署环境。依赖管理上核心只需要引入dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-thymeleaf/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency对于毕设项目数据库使用 H2 内存库或者 MySQL 都可以。如果只是演示H2 更方便如果文档和测试需要展示真实数据MySQL 更完整。建议不要在这里花太多时间纠结。2.2 Thymeleaf 为什么在这个题目里很合适很多人会问现在不是流行前后端分离吗为什么还要用服务端渲染的 Thymeleaf答案很简单这个题目本身就是“传统 Web 应用 AI 大模型”而不是一个重交互的中后台产品。Thymeleaf 可以在服务端把天气信息、出行建议这些数据直接渲染到 HTML 页面省去和前端联调跨域、接口鉴权、异步请求异常处理的大量沟通成本。对于毕业设计它还有一个隐性优势几乎所有代码都在你熟悉的 Java 后端里页面只需要掌握简单的 th:each、th:text、th:action 等语法。即使页面不好看你也可以通过 Bootstrap 或 CSS 框架快速补救。但要注意适用边界如果你的题目要求做一个微信小程序或 Vue 管理系统那就不适合用 Thymeleaf。你需要把后端改成纯 REST API前端另建项目。而本题标题里已经明确写了 Thymeleaf所以在答辩时不要一会说前后端分离一会说模板引擎容易自己把自己绕进去。2.3 AI 大模型集成本质是一次 HTTP 接口调用在这个系统里大模型不是本地部署的一套模型服务而是通过 HTTP 接口完成对话补全。目前常见的接入方式大致可以分为两种调用中立的在线大模型 API通常给出一个 Base URL、API Key、模型名称发送包含 system 和 user 消息的 JSON 请求拿到返回文本。本地部署可运行的开源模型通过兼容接口暴露 HTTP 服务再把 Spring Boot 里的调用地址指向本机端口。无论哪种方式后端集成逻辑都是一样的用 RestTemplate 或 WebClient 发送 POST 请求携带model、messages、temperature等参数然后从返回 JSON 中提取choices[0].message.content这一段文本。这里我给你一个非常通用的 Java 调用结构具体服务地址和参数名按你选择的模型服务文档来调整Service public class AiChatClient { private final RestTemplate restTemplate; public AiChatClient(RestTemplate restTemplate) { this.restTemplate restTemplate; } public String chat(String systemPrompt, String userPrompt) { String url https://your-llm-endpoint/compatible-api; // 替换成实际服务的地址 MapString, Object requestBody new HashMap(); requestBody.put(model, your-model-name); requestBody.put(temperature, 0.7); ListMapString, String messages new ArrayList(); messages.add(Map.of(role, system, content, systemPrompt)); messages.add(Map.of(role, user, content, userPrompt)); requestBody.put(messages, messages); MapString, Object response restTemplate.postForObject(url, requestBody, Map.class); if (response ! null) { // 按照返回结构做解析这里以常见的 choices[0].message.content 为例 return response.get(choices) .get(0) .get(message) .get(content) .toString(); } return 抱歉AI 服务暂时不可用; } }这段代码不是某个官方 SDK 的固定写法而是让你明白核心逻辑你只需要把“查询到的天气数据”拼到 prompt 里再发送给大模型等待返回即可。2.4 一个重要的架构取舍做这个系统时你可以把 AI 模块设计成“可替换的”。什么意思就是后端不要直接硬编码某一个具体模型服务而是定义一个AiClient接口再写一个OpenAiCompatibleClient实现类。这样如果今天用 A 模型明天换 B 模型只需要改配置不需要改业务代码。同样天气数据源也可以定义WeatherDataSource接口包含getCurrentWeather(String city)方法然后分成RemoteWeatherClient和MockWeatherClient两个实现。远程接口不稳定时启动一个 mock profile 就能继续演示。这个“接口隔离”设计对毕业设计可能不是必需品但它能在很大程度上减少答辩翻车概率也容易在“系统设计与分析”部分拿到分。3. 功能设计把天气、出行、AI 建议串成一个闭环3.1 核心业务逻辑从输入到输出的完整链路做这个系统的第一步不是建表不是写页面而是确认核心流程。我通常建议用一条主链路去驱动开发把所有附加功能放后面。主链路如下用户打开系统首页看到出行规划表单。用户输入出发城市、目的城市、出行日期、出行偏好。后端收到请求先校验必填字段。调用天气服务获取出发地和目的地的天气信息。后端把用户输入 天气信息 业务规则拼成一个结构化提示词。调用大模型生成出行建议。后端把建议存入数据库并返回给 Thymeleaf 页面渲染。用户页面看到天气摘要和 AI 建议同时历史记录可查询。这条链路里第 5 步是最容易被低估的。很多人直接把“A 城市天气晴B 城市天气阴”扔给大模型只说“帮我写建议”。这样得到的回答往往很泛没有结合出行场景。更好的做法是把系统给大模型的提示词做成结构化模板明确要求它输出穿衣建议、携带物品、交通方式、风险提醒四个板块。3.2 天气数据层第三方接口和模拟数据天气数据通常来自第三方接口比如高德天气、和风天气等。申请 API Key 后可以通过一个 URL 请求获取城市天气 JSON。实际项目中这类接口的调用方式无外乎三步拼接 URL - 发送 GET 请求 - 解析 JSON 字段。一般都会返回当前温度、天气现象、风力等级等字段。但这里有个容易踩的坑第三方接口免费额度有限且不同服务的返回字段名不一致。比如有的字段叫text有的叫condition有的叫weather。你写的时候要先打印一次返回的完整 JSON看清楚结构再写解析代码不要凭感觉猜字段名。更关键的是你要准备好“模拟数据源”。什么情况下用答辩现场网络不稳定、API Key 过期、接口调整、演示时对方网络屏蔽第三方域名这些情况都不是小概率事件。我建议你定义这样一个接口public interface WeatherDataSource { WeatherInfo getCurrentWeather(String city); }远程实现类负责真实 HTTP 调用本地 Mock 实现类返回一组固定的数据Service ConditionalOnProperty(name weather.source, havingValue mock) public class MockWeatherDataSource implements WeatherDataSource { Override public WeatherInfo getCurrentWeather(String city) { WeatherInfo info new WeatherInfo(); info.setCity(city); info.setCondition(晴); info.setTemperature(24); info.setWindLevel(3级); return info; } }这样你可以在application.yml里通过weather.sourcemock一键切换。这个设计在文档里也可以写成“系统具有良好的容错设计和可测试性”。3.3 AI 能力层提示词设计是核心很多人以为 AI 大模型接入最难的是调用代码其实代码十分钟就能写完。真正决定 AI 建议质量的是提示词。我给这个系统设计了一个最小可用的提示词模板你是一个智能出行助手。请根据以下信息生成出行建议。 出发城市北京 目的城市上海 出行日期2025-06-01 出发地天气晴27℃微风 目的地天气小雨22℃东南风3级 用户偏好少走路、喜欢室内景点 请按以下结构输出 1. 天气总结两句话 2. 穿衣建议 3. 携带物品 4. 交通方式建议 5. 风险提醒 全文不超过200字语气简洁。这个提示词有几个关键设计点角色限定告诉模型“你是出行助手”避免泛泛而谈。输入信息结构化天气、偏好都放在一段固定文本里。输出结构固定要求按板块输出方便前端渲染。长度限制防止生成一大段不可控内容。温度参数一般设置为 0.7 左右太低会显得机械太高容易跑偏。在答辩时老师很可能会问“大模型回答不准确怎么办”。你可以说系统不只是依赖大模型而是先用规则代码做一层兜底比如下雨天自动提醒带伞温度低于 10 度自动提醒注意保暖。大模型负责润色和综合建议规则负责基础保障。3.4 出行模块规则与大模型结合出行模块不要只做一个“问大模型的聊天框”。这样做会显得没有业务设计。更好的做法是构建一个“规则引擎 大模型生成”的复合逻辑。比如如果目标城市未来三天有雨系统先给一个基础风险标识。如果温差超过 10 度系统提醒增减衣物。如果用户偏好是“少走路”系统优先推荐打车或地铁。这些规则可以先在 Service 层计算出来作为“结构化建议”再把结构化建议和天气数据一起传给大模型让它生成更自然的一段话。这样做的好处是即使大模型暂时不可用基础建议仍然可以展示系统看起来没有完全瘫痪。4. 实战落地从零搭一个最小可运行版本4.1 环境准备和项目初始化开发这个项目建议环境如下JDK 8 或 11 及以上Maven 3.6IntelliJ IDEA 或 EclipseMySQL 5.7 / H2 可选一个可调用的 AI 大模型接口或本地模型运行环境项目初始化可以直接用 Spring Initializr选择Spring Web、Thymeleaf、Spring Data JPA、Validation。如果不想用数据库也可以暂时用内存 Map 存储但为了文档完整建议至少建一张travel_record表。4.2 后端分层和最小 Controller建议按这样的包结构组织代码com.example.weathertravel ├── controller ├── service ├── client ├── model ├── repository └── configController 层只负责接收请求、调用 Service、把结果放入 Model。不要在 Controller 里直接写 HTTP 调用代码。一个最小可运行的 Controller 示例如下Controller public class TravelController { private final TravelService travelService; public TravelController(TravelService travelService) { this.travelService travelService; } GetMapping(/) public String index() { return index; } PostMapping(/travel/plan) public String plan(Valid TravelRequest request, Model model) { TravelPlan plan travelService.generatePlan(request); model.addAttribute(plan, plan); return result; } GetMapping(/history) public String history(Model model) { model.addAttribute(records, travelService.listRecords()); return history; } }这个 Controller 只做三件事展示表单、处理表单、展示历史记录。后续如果要加“AI 问答”可以继续加一个/api/chat的 POST 接口。4.3 Thymeleaf 页面与表单交互Thymeleaf 页面建议保留一个简单的首页表单form th:action{/travel/plan} methodpost label出发城市/label input typetext namefromCity required / label目的城市/label input typetext nametoCity required / label出行日期/label input typedate nametravelDate required / label出行偏好/label select namepreference option valuenormal常规/option option valuelessWalking少走路/option option valuefood美食为主/option /select button typesubmit生成出行建议/button /form在结果页展示建议时可以用th:each展示历史记录也可以用th:text直接输出 AI 返回内容。建议把 AI 返回的文本按换行拆成段落再渲染避免一大段挤在一起div classsuggestion pre th:text${plan.suggestion}/pre /div4.4 AI 接口对接的通用写法前面给过AiChatClient的核心代码。实际对接时你只需要关注两点一是请求地址和模型名二是超时设置。在 Spring Boot 中自定义一个 RestTemplate Bean 并设置超时时间不要直接用默认值Bean public RestTemplate restTemplate() { SimpleClientHttpRequestFactory factory new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(5000); factory.setReadTimeout(15000); return new RestTemplate(factory); }AI 接口通常响应较慢读取超时设置 15 秒左右比较合适。太短容易误判失败太长会让页面一直转圈。4.5 先跑通单条链路再补功能我见过很多毕设团队一开始就铺开做登录、注册、聊天记录、后台管理最后主链路都没走通。最稳妥的开发顺序是先写一个静态首页。不做数据库用固定数据返回一次出行建议。接入天气接口先用 mock让天气数据出现在页面上。接入大模型接口让 AI 建议和天气数据拼在一起。再加入用户模块、历史记录、异常提示。每完成一步都启动一次项目确认没有断点。这样做看起来慢实际上比最后一次性联调更快。5. 最容易翻车的几个地方5.1 第三方接口的风险与应对先说最常见的三种情况API Key 失效、接口地址变更、返回字段和文档不一致。面对这些问题我的建议是不要把 Key 写死在代码里放到application.yml或环境变量里。写一个日志拦截器打印请求和响应的核心内容。所有外部调用都包一层 try/catch最低限度保证程序不报 500。准备好 mock 数据源并让 mock 和真实源可以一键切换。这是一个对你长期有用的习惯。毕业后进入团队对接第三方系统也会遇到完全一样的情况。5.2 大模型响应慢、超时、内容不可控你无法控制大模型服务的响应速度但你可以控制自己的超时设置和兜底策略。建议把 AI 调用封装成单独的方法并设定降级逻辑public String generateSuggestion(TravelRequest request) { try { String prompt promptBuilder.build(request); return aiChatClient.chat(systemPrompt, prompt); } catch (Exception e) { log.error(AI 调用失败, e); return fallbackSuggestion(request); } }fallbackSuggestion里可以写一段模板把天气数据套进固定话术“当前天气晴适合出行请携带防晒用品。” 这样即便 AI 挂了页面仍然有结果输出。5.3 表结构设计混乱这个项目至少需要两张表用户表和出行记录表。出行记录表可以记录用户输入、天气快照、AI 建议、生成时间。建议使用 JPA 自动建表实体类为例Entity public class TravelRecord { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String fromCity; private String toCity; private String travelDate; private String weatherInfo; private String suggestion; private LocalDateTime createTime; }不要把所有字段都塞进一个字符串里。文档中可以用 ER 图说明表关系答辩时也会更好解释。5.4 实际排查问题的顺序如果演示或测试时 AI 没有返回结果不要一上来就改代码。按下面的顺序排查看现象页面是空白、报错还是长时间加载看后端日志请求是否进入 ControllerAI 调用是否抛异常看输入用户填写的城市是否为空日期格式是否正确看配置API Key 是否配置正确服务地址是否可达看参数温度参数是否写错模型名是否存在看工具边界是不是第三方接口限流是不是大模型服务临时不可用把这六步写在设计文档的“系统测试与排查”章节里能让答辩老师认为你有真实的工程经验。6. 答辩和材料准备源码、LW、PPT、讲解怎么配合6.1 文档LW不是抄代码而是讲清楚“为什么”很多同学会把大量篇幅用来粘贴代码这是文档写作最常见的误区。设计文档的核心应该是可行性分析、需求分析、系统设计、数据库设计、测试分析。不要只输出“技术说明书”而是要回答三个问题这个系统解决了什么现实问题为什么选择这几种技术关键模块是怎么设计的有没有考虑到异常情况文档结构可以参考绪论背景、意义、国内外现状。需求分析功能需求、非功能需求、用例图。系统设计架构图、模块设计、数据库设计。系统实现关键功能说明配合核心代码片段。系统测试功能测试表、异常测试、结果分析。总结与展望不足和后续改进方向。注意文档里的“总结与展望”不是凑字数而是展示你的学习能力。可以写“目前系统对大模型返回结果缺少结构化校验后续可以引入 JSON Schema 进行校验”这句话比空谈“未来可研究”要有力。6.2 PPT 怎么组织重点不是大模型介绍PPT 最容易犯的错误是前面用大量篇幅介绍什么是大模型、什么是 Spring Boot。这样讲 10 页老师只会觉得你在凑内容。更好的做法是封面题目、姓名、学号、指导教师。背景与意义2 到 3 页说清楚为什么需要智能天气出行服务。技术选型1 页表格对比突出 Spring Boot Thymeleaf AI 大模型组合的合理性。系统功能模块图用一张图展示用户、天气、出行建议、历史记录四个模块。核心流程图展示从用户输入到 AI 建议输出的完整链路。数据库设计列出主要的表和字段。核心实现不要贴大段代码只放关键方法或架构截图。演示视频或录屏放一段 1 分钟内的效果演示。问题与改进说清楚你在实现过程中遇到的坑和解决方案。PPT 的总页数控制在 15 到 20 页即可。讲的时候不要念文字要说“我这样设计的理由”。6.3 演示脚本怎么设计演示环节是毕业设计最容易翻车的地方。我建议准备一份“3 分钟演示脚本”不要临场发挥。脚本示例打开系统首页说这是面向用户的出行规划首页。输入“北京到上海明天”点击生成。页面出现两地天气和 AI 出行建议。点击历史记录展示刚才的查询已经被保存。切换一次天气模式展示一个雨天出行的例子让 AI 建议有明显变化。最后补充一句如果外部天气接口不可用系统会切换到 mock 数据源保证基本功能可用。演示前至少完整跑两遍并把可能用到的数据提前准备好。如果现场网络不稳定提前准备录屏或截图作为备用不要等到现场才手忙脚乱。6.4 答辩常见问题与思路这里整理几个高频问题每个问题的回答思路比标准答案更重要。问题 1为什么选择 Thymeleaf 而不是前后端分离可以说这个系统以服务端渲染为主业务不复杂Thymeleaf 能直接复用后端数据减少前端联调成本更适合单人完成的毕业设计。如果要扩展成小程序后端可以再拆成 REST API。问题 2大模型返回的建议不准确怎么办可以说系统不把大模型作为唯一决策来源而是先用天气规则做基础判断再让大模型综合生成。同时通过提示词约束输出结构降低随机性。问题 3天气接口不可用怎么办可以说系统抽象了天气数据源接口提供远程和 mock 两种实现。测试环境和演示时可以通过配置切换保证系统核心链路不中断。问题 4这个系统有什么可以改进的地方可以说可以引入 Redis 缓存天气数据减少第三方接口调用次数可以用异步队列处理 AI 请求提升页面响应速度可以接入地图服务实现更细粒度的路线规划。但这些都是后续演进方向当前版本优先保证了核心链路稳定。7. 从毕设到工程这个题目还能往哪延伸7.1 从单机应用到中间件演进毕业设计做完之后如果你还想把项目写进简历或继续深入至少有三个方向可以扩展。第一是缓存。天气数据其实具有明显的时效性可以在 Service 层加入 Redis 缓存同一城市 30 分钟内不重复调用第三方接口。这样能明显减少外部 API 依赖。第二是异步化。大模型接口响应时间往往较长会影响页面体验。可以引入消息队列或 Spring 的Async把 AI 请求从同步链路中分离出去先返回“正在生成”再通过轮询或 WebSocket 推送结果。第三是日志与监控。给外部接口调用加上日志记录、耗时统计和异常报警能让你更清楚系统运行状态。这些方向不需要在毕设阶段全部实现但你应该知道“往工程化方向走”长什么样。7.2 AI 层的发展从 Prompt 到 Agent当前系统里的 AI 只是“被动的回答者”你给它天气数据它给你建议。如果继续深入可以把 AI 模块做成一个简单的 Agent让它自己决定是否需要调用天气接口或路线规划接口。比如用户输入“明天从北京去上海需要带伞吗”系统先触发意图识别决定调用哪一个天气函数再根据函数返回结果生成回答。这是目前大模型应用开发的常见演进路线。毕设文档的“展望”部分写这个方向会比写空话有价值。7.3 适用边界和最后建议这个题目适合什么人适合后端基础一般但希望在一个完整项目里把 Spring Boot、模板引擎、外部 API、数据库串起来的同学。适合想要一个能稳定演示、容易解释、不依赖复杂分布式环境的毕业设计。不适合想做大规模高并发系统或深度学习算法创新的同学。如果你正打算选这个题目我的建议是不要第一天就想把 AI 做得“很智能”。先跑通从表单到数据库的最小闭环再逐步加入天气接口和大模型。单次跑通只能说明流程没有断真正能通过答辩靠的是你把每条链路、每个异常、每个设计决策都讲清楚。这类“AI 传统系统”的毕业设计本质上是在训练一个能力把真实场景里的不确定因素收拾进可控的系统框架里。这个能力比单纯会用某个大模型 API 值钱得多。