简介:本资源是一套面向高校计算机相关专业毕业设计的完整项目源码,主题为基于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. 从一份毕设源码说起:Java+MVC 的天气预报穿衣搭配 APP 到底怎么落地
很多同学做毕业设计时,选题卡在“天气预报”和“穿衣搭配”这两个词上,觉得太简单、没技术含量。但真正动手才发现,要把天气数据拉取、穿衣规则引擎、PC 端和 Android 端同时跑通,还要用 Java+MVC 把代码写得像样,工作量并不小。这个标题指向的是一套完整的、可运行的毕业设计项目:后端用 Java 写业务逻辑,MVC 三层架构做分层,PC 端和 Android 手机 APP 共用同一套接口,核心功能是根据天气数据推荐穿衣搭配。它适合正在找 Java 课程设计案例源码、需要一套能跑通且结构清晰的毕设项目的同学,也适合想通过一个完整项目理解 MVC 设计模式、Spring MVC 请求流转、Android 网络请求的开发者。接下来我会按“先理解架构、再动手跑通、最后避开坑”的顺序,把这条路径拆开讲清楚。
2. 先搞懂这套 Java+MVC 架构的骨架:为什么不是随便写几个 Servlet
2.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 里不要写 SQL,DAO 里不要写页面跳转。答辩时老师一眼就能看出分层是否清晰。
2.2 天气数据从哪来:接口选型和本地缓存策略
天气数据是这套 APP 的输入源。常见做法是接第三方天气 API,比如和风天气、心知天气、OpenWeatherMap。选型时看三个点:免费额度够不够毕设演示、返回字段里有没有温度、天气现象、风力、湿度、紫外线指数、返回格式是不是 JSON。我一般会选返回字段全、文档中文友好的,因为 Android 端解析字段时少踩编码坑。
拿到数据后不要每次请求都打第三方接口。PC 端和 Android 端都加一层本地缓存:PC 端用 Redis 或 Caffeine,Android 端用 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?city=beijing启动后先访问一个测试接口,比如/api/weather/today?city=beijing,看返回 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:name="android.permission.INTERNET" /> <uses-permission android:name="android.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 permitted,Android 9 以上默认禁止明文 HTTP,需要在AndroidManifest.xml的application标签加android:usesCleartextTraffic="true"。
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.charset=UTF-8和数据库连接串的characterEncoding=utf8。
4. 避坑与排查:这套毕设项目最容易翻车的 5 个地方
4.1 现象:Android 端请求接口返回 404,PC 端浏览器却正常
原因通常是 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' doesn't exist
原因是没有执行建表 SQL,或者application.yml里配的数据库名和实际建库名不一致。解决:先手动执行schema.sql,再用show tables;确认表存在。如果用了 JPA 的ddl-auto=update,检查实体类有没有加@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() { List<String> 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 个以内,避免额度耗尽。
这两个手法都不复杂,但能让你的毕设从“能跑”变成“有思考”。我自己的习惯是先把基础链路跑通,再挑一个点做深,不要一开始就铺太大。希望帮到你。
本文还有配套的精品资源,点击获取