
简介本资源是一套面向高校计算机相关专业毕业设计的完整项目源码主题为基于Java与MVC架构的天气预报穿衣搭配APP同时覆盖PC服务端与安卓Android客户端适合需要完成毕设或学习三层架构开发的学生与开发者参考。压缩包共424个文件约2.73MB包含93个java源文件、86个xml配置、31个jsp页面、50个class编译文件以及gif、png、jpg等界面素材和sql数据库脚本服务端与客户端代码结构清晰。项目采用界面层、业务逻辑层、数据层三层分离设计服务端与客户端通过XML和json格式通信涵盖地区天气发布、用户信息管理、生活模块穿衣搭配提示等实体与功能模块并附有视频文件用于虚拟人物搭配展示。目前已有265人学习下载可帮助读者快速理解MVC在天气类APP中的落地方式掌握数据库设计、接口通信与安卓端界面搭建的完整思路。1. 从一份毕设源码说起JavaMVC 的天气预报穿衣搭配 APP 到底怎么落地很多同学做毕业设计时选题卡在“天气预报”和“穿衣搭配”这两个词上觉得太简单、没技术含量。但真正动手才发现要把天气数据拉取、穿衣规则引擎、PC 端和 Android 端同时跑通还要用 JavaMVC 把代码写得像样工作量并不小。这个标题指向的是一套完整的、可运行的毕业设计项目后端用 Java 写业务逻辑MVC 三层架构做分层PC 端和 Android 手机 APP 共用同一套接口核心功能是根据天气数据推荐穿衣搭配。它适合正在找 Java 课程设计案例源码、需要一套能跑通且结构清晰的毕设项目的同学也适合想通过一个完整项目理解 MVC 设计模式、Spring MVC 请求流转、Android 网络请求的开发者。接下来我会按“先理解架构、再动手跑通、最后避开坑”的顺序把这条路径拆开讲清楚。2. 先搞懂这套 JavaMVC 架构的骨架为什么不是随便写几个 Servlet2.1 MVC 三层架构在天气穿衣 APP 里的具体分工MVC 三层架构不是背概念而是决定你后面改代码时会不会把自己绕晕。在这套天气穿衣搭配 APP 里Model 层负责数据实体和业务规则比如 Weather 实体类存温度、湿度、风力、天气状况ClothingRule 类根据温度区间和天气类型计算推荐搭配View 层在 PC 端是 JSP 或 Thymeleaf 页面在 Android 端是 Activity 和 XML 布局Controller 层用 Spring MVC 的 DispatcherServlet 统一接收请求把/api/weather/today这类接口映射到具体方法调用 Service 后再返回 JSON 给前端。我一般会把 Service 层单独抽出来不让 Controller 直接调 DAO。因为穿衣推荐逻辑会随着季节、城市、用户偏好变化放在 Service 里改起来不影响接口层。PC 端和 Android 端共用同一套 REST 接口返回格式统一为{code, msg, data}这样 Android 端用 Retrofit 或 OkHttp 解析时不用为每个接口写不同逻辑。提示如果你的毕设要求里写了“必须体现 MVC”那 Controller 里不要写业务计算Service 里不要写 SQLDAO 里不要写页面跳转。答辩时老师一眼就能看出分层是否清晰。2.2 天气数据从哪来接口选型和本地缓存策略天气数据是这套 APP 的输入源。常见做法是接第三方天气 API比如和风天气、心知天气、OpenWeatherMap。选型时看三个点免费额度够不够毕设演示、返回字段里有没有温度、天气现象、风力、湿度、紫外线指数、返回格式是不是 JSON。我一般会选返回字段全、文档中文友好的因为 Android 端解析字段时少踩编码坑。拿到数据后不要每次请求都打第三方接口。PC 端和 Android 端都加一层本地缓存PC 端用 Redis 或 CaffeineAndroid 端用 Room 或 SharedPreferences 存最近一次成功返回的 JSON并记录时间戳。缓存过期时间设 30 到 60 分钟因为天气预报本身更新频率不高。这样即使第三方接口临时限流APP 还能展示上一次的数据不至于白屏。// WeatherService.java 片段先查缓存再决定是否调第三方 public WeatherDTO getTodayWeather(String cityCode) { String cacheKey weather: cityCode; String cached redisTemplate.opsForValue().get(cacheKey); if (cached ! null) { return JSON.parseObject(cached, WeatherDTO.class); } // 缓存未命中调第三方接口 String url https://api.example.com/weather?city cityCode key apiKey; String resp restTemplate.getForObject(url, String.class); WeatherDTO dto parseWeatherResponse(resp); // 写入缓存过期时间 45 分钟 redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(dto), 45, TimeUnit.MINUTES); return dto; }这段代码的关键参数是45, TimeUnit.MINUTES你可以根据第三方接口的更新频率调整。如果接口每小时更新一次缓存设 50 分钟比较稳。cityCode建议用城市拼音或行政区划代码不要用中文城市名直接拼 URL否则 Android 端请求时容易出现编码问题。2.3 穿衣搭配规则引擎用配置表代替硬编码 if-else穿衣推荐最怕写成一堆if (temp 30) return 短袖; else if (temp 20) ...。这种写法改一个温度区间就要重新编译Android 端和 PC 端还得各写一遍。我一般会建一张clothing_rule表字段包括min_temp、max_temp、weather_type、suggestion、layer_count。Service 层根据当前温度和天气现象查表匹配返回推荐文案和搭配层级。CREATE TABLE clothing_rule ( id INT PRIMARY KEY AUTO_INCREMENT, min_temp INT NOT NULL, max_temp INT NOT NULL, weather_type VARCHAR(32) NOT NULL, suggestion VARCHAR(255) NOT NULL, layer_count INT DEFAULT 1 ); INSERT INTO clothing_rule (min_temp, max_temp, weather_type, suggestion, layer_count) VALUES (28, 50, 晴, 短袖T恤 短裤注意防晒, 1), (20, 27, 多云, 长袖衬衫 薄长裤早晚可加薄外套, 2), (10, 19, 阴, 卫衣 夹克 长裤, 2), (0, 9, 雨, 毛衣 防风外套 长裤带伞, 3), (-20, -1, 雪, 羽绒服 保暖内衣 围巾手套, 4);这样 PC 端和 Android 端都调同一个/api/clothing/recommend接口传城市和日期后端返回推荐结果。改规则时只改数据库不用重新发版。注意weather_type要和第三方接口返回的天气现象做映射比如接口返回“小雨”要归到“雨”这一类否则匹配不到规则。3. 把 PC 端和 Android 端同时跑起来环境、接口联调和最小可运行步骤3.1 PC 端最小运行步骤从 Java 环境到页面出数据PC 端通常是 Spring Boot Thymeleaf 或 JSP。先确认本机 Java 环境java -version看到 1.8 或 11 以上即可。Maven 用mvn -v检查。数据库建好后改application.yml里的spring.datasource.url、username、password以及第三方天气 API 的 key。# 1. 初始化数据库 mysql -u root -p schema.sql # 2. 编译并启动 PC 端 mvn clean package -DskipTests java -jar target/weather-app-0.0.1-SNAPSHOT.jar # 3. 浏览器访问 # http://localhost:8080/weather?citybeijing启动后先访问一个测试接口比如/api/weather/today?citybeijing看返回 JSON 里有没有temperature、weatherType、suggestion字段。如果没有先查 Controller 有没有正确映射再查 Service 有没有抛异常。PC 端页面用 Thymeleaf 的话注意模板文件放在src/main/resources/templates/下静态资源放在static/下。3.2 Android 端最小运行步骤Android Studio 导入与网络权限Android 端用 Android Studio 打开项目等待 Gradle 同步完成。如果 Gradle 下载慢可以在gradle-wrapper.properties里换成本地已缓存的版本或者用阿里云镜像。同步完成后检查AndroidManifest.xml里有没有加网络权限uses-permission android:nameandroid.permission.INTERNET / uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE /然后在build.gradle里确认 Retrofit 和 Gson 依赖已添加。如果 PC 端跑在本机Android 模拟器访问本机要用10.0.2.2代替localhost真机则要用电脑的局域网 IP并确保手机和电脑在同一网段。// ApiClient.java 片段Retrofit 基础配置 public class ApiClient { private static final String BASE_URL http://10.0.2.2:8080/; private static Retrofit retrofit; public static Retrofit getInstance() { if (retrofit null) { retrofit new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); } return retrofit; } }BASE_URL末尾的斜杠不能省否则 Retrofit 拼接路径时会丢字段。真机调试时把10.0.2.2换成电脑 IP比如http://192.168.1.100:8080/。如果请求失败先看 Android Studio 的 Logcat 有没有CLEARTEXT communication not permittedAndroid 9 以上默认禁止明文 HTTP需要在AndroidManifest.xml的application标签加android:usesCleartextTraffictrue。3.3 接口联调PC 端和 Android 端共用一套返回格式PC 端和 Android 端同时跑通的关键是接口返回格式统一。我一般定义{ code: 200, msg: success, data: { city: beijing, temperature: 26, weatherType: 晴, suggestion: 短袖T恤 短裤注意防晒, layerCount: 1 } }PC 端用 Thymeleaf 取data.suggestion渲染页面Android 端用 Gson 解析成WeatherResponse对象。如果 Android 端解析出来字段为 null先检查 Gson 的SerializedName注解有没有和 JSON 字段名对齐。PC 端如果页面显示乱码检查server.servlet.encoding.charsetUTF-8和数据库连接串的characterEncodingutf8。4. 避坑与排查这套毕设项目最容易翻车的 5 个地方4.1 现象Android 端请求接口返回 404PC 端浏览器却正常原因通常是 Android 端BASE_URL写成了localhost或127.0.0.1模拟器里这两个地址指向模拟器自身不是你的电脑。解决模拟器用10.0.2.2真机用电脑局域网 IP并确认电脑防火墙没有拦截 8080 端口。4.2 现象穿衣推荐结果和天气对不上比如 30 度推荐羽绒服原因多半是温度区间匹配逻辑写反了或者weather_type映射没做。比如第三方接口返回“晴”数据库里存的是“晴天”匹配不上就落到默认规则。解决在 Service 层加一层天气类型归一化把“晴”“晴天”“晴朗”统一映射成“晴”再查规则表。4.3 现象PC 端启动报Table weather_db.clothing_rule doesnt exist原因是没有执行建表 SQL或者application.yml里配的数据库名和实际建库名不一致。解决先手动执行schema.sql再用show tables;确认表存在。如果用了 JPA 的ddl-autoupdate检查实体类有没有加Table(name clothing_rule)。4.4 现象Android Studio 同步 Gradle 卡住或报依赖下载失败原因通常是网络问题或 Gradle 版本和 Android Gradle Plugin 版本不匹配。解决在项目根目录build.gradle里确认 AGP 版本在gradle-wrapper.properties里确认 Gradle 版本两者要对应。如果下载慢在settings.gradle里加阿里云 Maven 镜像。4.5 现象第三方天气接口返回 401 或 403原因一般是 API key 没填、填错、或者免费额度用完。解决先到第三方控制台确认 key 状态和剩余次数再检查代码里 key 有没有被硬编码成占位符。建议把 key 放在application.yml里用Value(${weather.api.key})注入不要直接写在 Java 代码里。5. 进阶技巧把穿衣推荐从“能跑”做到“像样”的两个具体手法5.1 用用户反馈表做推荐结果的闭环修正基础版推荐只靠天气和温度但不同人对冷热的感受差异很大。我一般会加一张user_feedback表记录用户对推荐结果的评分1 到 5 分和实际穿着。当某个温度区间内平均评分低于 3 分时在后台标记该规则需要调整。PC 端加一个简单的反馈按钮Android 端在推荐卡片下方加“合适/偏冷/偏热”三个选项。数据积累多了之后你可以按用户 ID 做个性化偏移比如怕冷的人温度阈值整体上移 3 度。CREATE TABLE user_feedback ( id INT PRIMARY KEY AUTO_INCREMENT, user_id INT NOT NULL, city_code VARCHAR(32), temperature INT, weather_type VARCHAR(32), rating TINYINT, feedback_time DATETIME DEFAULT CURRENT_TIMESTAMP );查询时按temperature每 5 度一个区间分组算平均评分。如果某个区间平均分低于 3就把该区间的suggestion拿出来人工复核。这个表不用做太复杂毕设答辩时能展示“有反馈闭环”就是加分项。5.2 用定时任务预热缓存避免演示时接口超时答辩演示时最怕第三方接口突然变慢或限流。我一般会加一个 Spring 的Scheduled定时任务每 30 分钟把常用城市北京、上海、广州、深圳的天气和推荐结果提前拉取并写入缓存。这样演示时直接读缓存响应时间从几百毫秒降到几毫秒。Scheduled(fixedRate 30 * 60 * 1000) public void preloadWeatherCache() { ListString hotCities Arrays.asList(beijing, shanghai, guangzhou, shenzhen); for (String city : hotCities) { try { getTodayWeather(city); // 内部会写缓存 } catch (Exception e) { log.warn(预热失败: {}, city, e); } } }fixedRate单位是毫秒30 分钟就是30 * 60 * 1000。注意在启动类上加EnableScheduling否则定时任务不生效。如果第三方接口有每日调用上限把预热城市控制在 5 个以内避免额度耗尽。这两个手法都不复杂但能让你的毕设从“能跑”变成“有思考”。我自己的习惯是先把基础链路跑通再挑一个点做深不要一开始就铺太大。希望帮到你。本文还有配套的精品资源点击获取