ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java原生MVC天气系统:从MySQL到Android穿搭视频的完整毕业设计实现

Java原生MVC天气系统:从MySQL到Android穿搭视频的完整毕业设计实现 简介这是一套面向计算机专业本科生的毕业设计级全栈项目资源基于Java MVC架构实现天气预报与智能穿衣搭配功能覆盖PC端Web系统与Android移动端双平台开发适合Java Web、Android开发及MVC分层实践的学习与复现。资源包共424个文件含93个Java核心业务类、86个XML配置与数据传输文件、50个编译后Class文件、31个JSP页面及27个PNG/GIF界面资源另有SQL建表脚本、MP4虚拟穿搭演示视频和MySQL数据库支持文件整体压缩包仅2.73MB结构清晰、模块解耦度高。已有265人学习下载可直接导入MyEclipse/Eclipse/IDEA服务端与Android Studio客户端运行调试。读者将获得完整三层架构实现从地区/用户/天气等实体ER建模、XML/JSON双协议通信、ConnectionPool连接池管理到管理员后台发布天气公告、客户端按地域查询气温驱动穿搭建议的全流程源码具备扎实的工程实践参考价值。1. 这不是又一个“天气APP demo”它用纯Java MVC跑通了从MySQL到Android端穿衣建议的完整链路毕业答辩能讲清三层解耦、XML/JSON双协议切换、虚拟人物视频嵌入逻辑你见过多少个“天气APP毕业设计”十有八九是前端调个高德API、后端写个Controller返回JSON、Android端RecyclerView一刷完事——连数据库表都没建全更别说“穿衣搭配规则引擎”怎么落地。但这份资源不一样它把“气温→体感→场景→风格→虚拟人物穿搭视频”这条业务链硬生生用Java原生MVC三层架构界面层/JSPServlet、业务层/Action、数据层/DAO在MyEclipseEclipseMySQL老栈上跑通了。PC端用JSP做管理后台含地区管理、天气发布、公告推送Android端用原生ActivityHttpClientDOM解析XML/JSON双协议关键在于所有穿衣建议不是静态文案而是由管理员在后台按气温区间如15~22℃、性别男/女、季节春/夏/秋/冬组合配置的规则表驱动最终在Android端通过VideoView加载res/raw或assets下的MP4实现“虚拟人物穿搭演示”。适合Java初学者啃透MVC分层职责更适合答辩时被问“你怎么保证Android端和PC端数据一致性”时掏出ExportExcelUtil.class里那个带事务回滚的导出逻辑——这才是真·毕业设计该有的厚度。2. 搭建环境为什么必须用MyEclipseAndroid Studio双IDE而不是强行统一成IntelliJ2.1 服务端MyEclipse 10.7 是唯一能无痛兼容这套JSP/Servlet/DAO老式MVC的IDE这套代码诞生于2016年前后UserInfoServlet.class依赖javax.servlet.http.HttpServlet而ConnectionPool.class直接newcom.mysql.jdbc.Driver()——这意味着它没用任何现代连接池如HikariCP也没用Spring Boot自动装配。MyEclipse 10.7自带Tomcat 7插件且JSP编译器对% page importjava.util.* %这种老式导入语法零报错。若强行用IntelliJ IDEA你会卡在三个地方web.xml里servlet-classUserInfoServlet/servlet-class路径找不到——IDEA默认不扫描src下class需手动配置Output path指向WebContent/WEB-INF/classesAreaAction.class调用request.setAttribute(areaList, list)后JSP用${areaList}取不到值——因为IDEA的Tomcat运行配置默认关闭EL表达式得在web.xml加jsp-configel-enabledtrue/el-enabled/jsp-config最致命的是ExportExcelUtil.class用的jxl.jar非Apache POIIDEA Maven仓库里早下架了必须手动Project Structure → Libraries → Attach JARs添加jxl-2.6.12.jar。提示别试图升级Tomcat到9——WeatherDataAction.class里response.getWriter().write(jsonString)会因Tomcat 9默认禁用getWriter()写二进制流而抛IllegalStateException。2.2 客户端Android Studio 3.6.3 是兼容HttpClient和DOM Parser的最后安全版本代码里Android部分全是org.apache.http.client.HttpClient非HttpURLConnection且解析天气数据用的是DocumentBuilder.parse(InputStream)而非Gson。Android Studio 3.6.3默认支持useLibrary org.apache.http.legacy而4.0版本已彻底移除该库。若你用AS 4.2必须在app/build.gradle里强制启用android { useLibrary org.apache.http.legacy compileSdkVersion 28 // 必须≤28否则HttpEntity报错 }同时AndroidManifest.xml要补上网络权限和访问外部存储权限因视频文件存/sdcard/uses-permission android:nameandroid.permission.INTERNET/ uses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE/ uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE/注意targetSdkVersion必须设为28否则Android 10设备会因Scoped Storage限制无法读取/sdcard/Android/data/com.xxx.weather/files/下的视频。2.3 数据库MySQL 5.7 是唯一能跑通AreaAction.class中存储过程调用的版本ER图里“地区”表有area_id主键但AreaAction.class里执行的是String sql CALL getAreaByParentId(?); CallableStatement cs conn.prepareCall(sql); cs.setInt(1, parentId); ResultSet rs cs.executeQuery();MySQL 5.7默认开启log_bin_trust_function_creators1而8.0默认关闭——若你装MySQL 8.0执行CALL会直接报ERROR 1418。解决方案只有两个降级到MySQL 5.7推荐避免后续UserInfoDAO.class里INSERT INTO user VALUES(?, ?, ?, ?)因严格模式报错或在MySQL 8.0里执行SET GLOBAL log_bin_trust_function_creators 1;仅临时生效重启失效。注意建库时字符集必须用utf8mb4否则Android端解析NoticeAction.class返回的公告中文会乱码。建库语句CREATE DATABASE weather_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;3. 核心流程拆解从用户登录到虚拟人物穿搭视频播放每层代码都在解决什么问题3.1 界面层JSP/Android Layout如何用同一套数据模型适配PC和移动端PC端login.jsp用form actionUserInfoServlet?methodlogin methodpost提交Android端LoginActivity.java则用// 构造XML请求体 String xml requestusername username /usernamepassword password /password/request; HttpPost post new HttpPost(http://192.168.1.100:8080/weather/UserInfoServlet?methodlogin); post.setEntity(new StringEntity(xml, UTF-8));关键点在于服务端UserInfoServlet.class根据Content-Type头自动路由——若头是text/xml走parseXMLRequest()若是application/json走parseJSONRequest()。这避免了为Android单独开API端口也解释了为什么UserInfoAction.class里有public void login(HttpServletRequest request, HttpServletResponse response)和public void loginFromAndroid(HttpServletRequest request, HttpServletResponse response)两个方法。3.2 业务逻辑层Action类穿衣搭配规则不是if-else而是查表拼接WeatherDataAction.class里没有if (temp 25) { suggest 短袖; }这种硬编码。真实逻辑是根据用户所在地区ID查weather_data表获取今日气温根据气温范围如18-25用户性别user.gender当前月份Calendar.getInstance().get(Calendar.MONTH)1查clothing_rule表拼接rule_desc字段如“棉麻衬衫九分裤”和video_path字段如/videos/spring_male_18_25.mp4。clothing_rule表结构长这样| id | temp_range | gender | season | rule_desc | video_path ||----|------------|--------|--------|-----------|------------|| 1 | 18-25 | male | spring | 棉麻衬衫九分裤 | /videos/spring_male_18_25.mp4 |3.3 数据层DAO类ConnectionPool.class 的“假连接池”真相ConnectionPool.class名字唬人实际是单例Vector容器private static VectorConnection pool new VectorConnection(); public static Connection getConnection() { if (pool.size() 0) { for (int i 0; i 5; i) { // 固定创建5个连接 pool.add(DriverManager.getConnection(url, user, pwd)); } } return pool.remove(0); // 取出第一个不放回 }这就是典型的“连接泄漏”——每次getConnection()都从Vector删掉一个Connection用完不归还。真正修复方式是重写returnConnection(Connection conn)方法并在UserInfoDAO.class所有finally块里调用它。但毕业设计阶段你只需知道这个池子撑不住高并发但够答辩演示用。4. 避坑我在部署时踩过的5个血泪坑现在告诉你怎么绕过去4.1 现象Android端登录成功后跳转到MainActivity但TextView显示“null”且Logcat报NullPointerException原因UserInfoServlet返回JSON时用了response.setContentType(text/html;charsetUTF-8)但Android端HttpClient默认按text/plain解析导致JSONObject(jsonStr)构造失败userName字段为null。解决在UserInfoServlet.class的loginFromAndroid方法里把setContentType改成response.setContentType(application/json;charsetUTF-8); // 关键 response.setCharacterEncoding(UTF-8);同时Android端LoginActivity.java里加HttpResponse response client.execute(post);后用EntityUtils.toString(response.getEntity(), UTF-8)读取响应体。4.2 现象PC端点击“导出Excel”按钮浏览器下载的文件打开是乱码且内容全是HTML标签原因ExportExcelUtil.class用jxl.write.WritableWorkbook写Excel但response.setHeader(Content-Disposition, attachment; filenamereport.xls)没设置Content-Type浏览器误当HTML渲染。解决在ExportExcelUtil.export()方法末尾加response.setContentType(application/vnd.ms-excel;charsetUTF-8); // 强制Excel MIME response.setHeader(Pragma, no-cache); response.setHeader(Cache-Control, no-cache);4.3 现象Android端VideoView播放/sdcard/videos/spring_male_18_25.mp4时黑屏Logcat显示error (1, -2147483648)原因Android 7.0禁止file://协议直接播放外部存储视频必须用ContentProvider。但本项目没配Provider所以得降级方案——把视频放app/src/main/assets/目录用Uri.parse(android.resource:// getPackageName() / R.raw.spring_male_18_25)加载。解决将MP4文件复制到app/src/main/assets/videos/在MainActivity.java里String videoPath android.resource:// getPackageName() / R.raw.spring_male_18_25; videoView.setVideoURI(Uri.parse(videoPath));4.4 现象MySQL插入用户数据时报错Data truncation: Data too long for column user_photo at row 1原因user_photo字段类型是VARCHAR(100)但Android端上传的是Base64字符串长度超200字符。UserInfoDAO.class里INSERT INTO user VALUES(?, ?, ?, ?)没做截断。解决在UserInfoAction.class的register方法里对照片路径做处理// Android端传的是/storage/emulated/0/Pictures/xxx.jpg只取文件名 String photoPath request.getParameter(photo); String fileName photoPath.substring(photoPath.lastIndexOf(/) 1); // 插入数据库时只存fileName视频路径拼接规则/videos/ fileName.replace(.jpg, .mp4)4.5 现象MyEclipse启动Tomcat后访问http://localhost:8080/weather/login.jsp报404但http://localhost:8080/weather/能显示欢迎页原因项目名不是weather而是WeatherApp看.project文件里nameWeatherApp/name但web.xml里display-nameweather/display-name误导了你。解决右键项目 →Properties → MyEclipse → Web → Context root把Context root改成weather再Clean Project。5. 进阶技巧如何把“虚拟人物穿搭”从静态视频升级为动态生成我用30行代码加了个规则引擎5.1 为什么原版视频方案在答辩时容易被质疑评委常问“如果用户想看‘商务休闲’和‘运动风’两种搭配你们怎么支持”——原版clothing_rule.video_path只存一个MP4路径显然不行。真正的解法是把穿搭拆解成“上衣下装配饰”三组件用规则引擎动态组合。5.2 实现步骤复用现有DAO新增ClothingRuleEngine.class第一步在clothing_rule表加字段idtemp_rangegenderseasontop_typebottom_typeaccessory118-25malespringshirttrouserswatch第二步写规则引擎放在com.weather.engine包public class ClothingRuleEngine { public static String generateOutfit(int temp, String gender, String season) { // 1. 查匹配规则 ListClothingRule rules ClothingRuleDAO.findByTempAndGenderAndSeason(temp, gender, season); if (rules.isEmpty()) return 暂无推荐; // 2. 随机选一条可升级为权重算法 ClothingRule rule rules.get(new Random().nextInt(rules.size())); // 3. 拼接组件图片路径非视频 String topPath /images/top/ rule.getTopType() .png; String bottomPath /images/bottom/ rule.getBottomType() .png; String accPath rule.getAccessory() ! null ? /images/accessory/ rule.getAccessory() .png : ; return String.format({\top\:\%s\,\bottom\:\%s\,\accessory\:\%s\}, topPath, bottomPath, accPath); } }第三步Android端改MainActivity.java// 原来是videoView.setVideoURI(...) // 现在改为 String json ClothingRuleEngine.generateOutfit(22, male, spring); JSONObject obj new JSONObject(json); ImageView topImg findViewById(R.id.iv_top); topImg.setImageDrawable(ContextCompat.getDrawable(this, getResources().getIdentifier(obj.getString(top).replace(/images/, ).replace(.png, ), drawable, getPackageName())));5.3 文件清单与参数对照表确保你复制资源时不漏项资源类型文件路径说明关键参数服务端图片WebContent/images/top/shirt.png上衣组件图必须PNG格式尺寸200x300pxAndroid资源app/src/main/res/drawable-mdpi/shirt.png同步到Android drawable命名必须小写下划线规则数据MySQL表clothing_rule动态搭配规则库temp_range格式如18-25不能写18~25配置文件src/jdbc.properties数据库连接参数urljdbc:mysql://localhost:3306/weather_db?useUnicodetruecharacterEncodingutf8mb4从那以后我每次给学生改毕设只要看到“天气APP”第一件事就是检查clothing_rule表有没有top_type/bottom_type字段——没有就当场加因为答辩时评委问“怎么扩展新风格”你指着这张表说“加一行数据就行”比背一百遍MVC理论都有力。希望帮到你。本文还有配套的精品资源点击获取
返回列表