尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SpringBoot+Android民宿预订系统毕设实战:从数据库到App联调全解析

SpringBoot+Android民宿预订系统毕设实战:从数据库到App联调全解析 每年到毕业季我都会收到不少学弟学妹的私信问“毕设做什么题目好”“SpringBoot和Android能不能结合”“有没有完整能跑的源码”。如果你正在被这些问题困扰那么基于SpringBootAndroid的民宿预订系统是一个非常值得考虑的选题——它既有后端业务逻辑的复杂度又有移动端界面与交互的呈现还踩中了当下旅游住宿数字化的大众需求。这套系统的典型能力包括用户注册登录、房源浏览与搜索、房间详情查看、在线下单预订、订单状态管理待支付/已支付/已入住/已退房、个人中心与消息提醒配合后台管理端还可以实现房源管理、订单管理、用户管理等功能。麻雀虽小五脏俱全无论是用来完成本科毕设还是作为求职简历里的完整项目都非常有说服力。本文不打算做泛泛的“项目介绍”我会把这套民宿预订系统从选题逻辑、数据库设计、接口规划到Android端实现过程中的核心代码片段、联调注意事项、论文写作思路以及我亲测踩过的一些坑一次性拆开揉碎讲明白。如果你正准备开始动手或者已经写了一半卡在某个环节这篇文章应该能帮你省下不少时间。1. 毕设选型为什么是SpringBoot Android民宿预订系统1.1 选题价值与技术栈合理性分析先解决一个根本问题毕设题目那么多为什么要选民宿预订我对这个题目的判断是它的复杂度刚刚好——既不会简单到让答辩老师觉得你没干活也不会复杂到让一个在校生在几个月内无法完成。从业务层面看民宿预订天然具备一套完整但边界清晰的业务闭环。用户端需要注册登录、筛选房源、查看房型、提交订单、模拟支付、个人中心管理端需要房源的增删改查、订单审核与状态流转、基础数据统计。这个闭环覆盖了绝大多数Web/App系统都有的核心流程基于角色的权限区分、用户与房源的关联、订单状态的可迁移性。相比之下做一个“图书管理系统”或“学生管理系统”虽然也能跑通但业务太单薄答辩时容易陷入“为什么这么简单”的尴尬而做电商平台、大型社交软件又会陷入订单拆分、消息推送、高并发的泥潭中不适合在校生的时间安排。从技术选型看SpringBoot Android的组合在近几年的毕设题目里热度一直很高原因也很实在。SpringBoot是目前Java后端开发的事实标准它简化了Spring的配置流程内嵌Tomcat容器搭配MyBatis-Plus可以快速完成数据持久化层的编码。Android端则用Java或Kotlin开发原生App不依赖第三方小程序平台数据交互走RESTful API技术点清晰、可控性强。一套代码下来把Spring生态、Android生命周期、数据库设计、HTTP通信、JSON解析这些知识点全部串起来正好覆盖面试官和答辩老师最看重的基础能力。提示部分学校对毕设题目中的技术栈有“新旧程度”的隐性要求。SpringBoot 2.x AndroidJava是目前兼容性最好的组合网上资料最多遇到问题也最容易搜到解决方案。如果你手里已经装好了Android Studio和JDK建议沿用这套组合不要贸然挑战新框架组合时间成本往往比想象中高。1.2 面向的用户角色与核心业务场景不少同学在做设计的时候花了很多精力在技术细节上却没有把用户角色和业务场景梳理清楚导致后面的功能设计东一榔头西一棒子。这里我把自己常用的一套分析思路分享出来。这套民宿预订系统的使用场景可以简化为三个角色游客/未登录用户可以浏览首页推荐房源、查看房源详情但在提交订单前必须注册或登录。这个设定在答辩时很加分说明你考虑到了数据归属问题而不是“都能看都能买”的粗放设计。注册用户C端消费者登录后可以搜索房源、筛选价格区间、查看房间图片和设施列表、提交订单、模拟支付、查看订单状态、发起退订还可以在个人中心修改头像和昵称。管理员B端运营人员通过单独的管理端入口登录可以维护民宿房源上架、下架、编辑价格和库存、处理订单状态确认入住、标记退房、查看注册用户列表。常见业务场景重复度高但这反而是好事一套代码的核心逻辑可以被反复调用你不需要为了每一个功能从零搭建。比如“根据城市搜索民宿”、“根据价格区间筛选”、“根据入住日期判断房间是否可订”这些本质上都是SQL查询条件组合的问题订单状态流转在数据库中其实就是status字段的更新配合创建时间和更新时间来做记录。1.3 数据库设计先行核心表结构与关系说明我特别想强调一点做这种前后端分离的毕设项目永远先设计数据库再写代码。我见过太多同学先写接口、后改表结构结果到联调阶段发现字段对不上改起来想砸电脑。这张表设计了几个核心表数据结构直接粘贴一份常见的模板供参考用户表user用户ID、昵称、手机号登录账号、密码MD5加密存储、头像URL、角色标识普通用户/管理员、创建时间。民宿表homestay民宿ID、名称、所在城市、详细地址、封面图URL、简介、价格元/晚、可订房间数、设施列表用JSON字符串或逗号分隔存储、状态上架/下架、创建时间。订单表order订单ID、订单编号唯一便于展示和检索、下单用户ID、民宿ID、入住日期、退房日期、入住人数、订单金额、状态待支付/已支付/已取消/已入住/已退房、创建时间、支付时间。这几个表之间的关系也比较直观一个用户可以下多个订单一个民宿可以被多个订单关联订单表中冗余民宿名称和价格快照防止民宿信息修改后订单数据失真这就是典型的订单快照设计面试的时候可以拿出来说。数据库创建时建议用utf8mb4字符集否则保存民宿简介里的特殊符号和emoji时会报错。这一点在后面Android端传数据时尤其容易出现我后面会专门提到。2. 后端SpringBoot设计与开发要点2.1 项目初始化与必要依赖引入SpringBoot项目的创建方式很成熟直接在IDEA里通过Spring Initializr创建即可或者去官网start.spring.io生成压缩包再导入效果一样。这里给出pom.xml中必要的核心依赖列表大家可以对照检查自己是否漏引。dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-validation/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency如果你不想用MyBatis-Plus用Spring Data JPA也行但MyBatis-Plus的BaseMapper内置了常用的增删改查方法分页插件用起来也方便适合快速完成项目。实际开发中你会发现80%的数据库操作用内置方法就够了只有少数复杂统计查询需要手写SQL。这一点可以写进论文作为“技术选型理由”。2.2 用户登录与JWT Token鉴权登录鉴权是几乎所有C端项目的核心。民宿预订系统里Android端每次请求需要携带当前登录用户的身份凭证这里我选了JWTJSON Web Token方案而不是传统的Session。原因是Android端不像Web端天然支持Cookie自动携带JWT放在请求头里更灵活而且用SpringBoot实现起来也不复杂。我设计了一个简单的结构用户登录成功后后端用用户ID和角色标识生成Token设置过期时间例如2天。前端每次请求时在Header里附带token字段。后端用一个拦截器HandlerInterceptor统一校验放行登录接口和房源列表接口其余接口全部要求登录。关于密码处理这里多说一句别用明文存储。我建议至少用MD5加盐的形式salt可以取用户手机号后四位或固定的盐值字符串。如果你动手能力强可以用Spring Security的BCryptPasswordEncoder但相对会多一些配置工作量。对毕设来说MD5加盐是性价比最高的方案答辩时也能说得清楚。// 简单示例拦截器中校验token public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token request.getHeader(token); if (StringUtils.isBlank(token)) { response.setStatus(401); return false; } // 解析token失败则返回401 try { Claims claims JwtUtil.parseToken(token); request.setAttribute(userId, claims.get(userId)); return true; } catch (Exception e) { response.setStatus(401); return false; } }2.3 核心接口设计与响应格式统一接口设计看似是各写各的但如果没有统一规范到了Android端对接时会非常痛苦。我常用的做法是定义统一返回体Result包含三个字段code状态码、message提示信息、data业务数据。Data public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(操作成功); result.setData(data); return result; } public static T ResultT error(Integer code, String message) { ResultT result new Result(); result.setCode(code); result.setMessage(message); return result; } }这样Android端拿到响应后只要判断code是否等于200就能确定请求是否成功。常见的code设计为200成功、401未登录、500服务器异常、400参数错误。核心接口清单大概如下POST /api/user/register注册POST /api/user/login登录GET /api/homestay/list民宿分页列表支持关键字/城市/价格筛选GET /api/homestay/detail?idxxx民宿详情POST /api/order/create创建订单GET /api/order/list?userIdxxx查看我的订单PUT /api/order/cancel取消订单POST /api/admin/homestay/save管理员新增/编辑房源GET /api/admin/order/list管理员查看订单列表写接口时注意一个细节列表接口务必做分页哪怕是毕设也要传页码page和每页数量pageSize。否则数据量稍大Android端一次性加载所有数据会明显卡顿答辩现场很尴尬。MyBatis-Plus的分页插件配置网上随处可见不赘述。2.4 后端部署前的配置项说明application.yml中关键配置项要写全尤其是日期格式、Jackson序列化、数据库连接参数。很多同学联调时接口返回的时间是一串数字时间戳就是因为在yml中没设置日期格式。spring: datasource: url: jdbc:mysql://localhost:3306/homestay_db?useUnicodetruecharacterEncodingutf8mb4serverTimezoneAsia/Shanghai username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8 mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl务必在url里加上useUnicodetruecharacterEncodingutf8mb4很多中文乱码、emoji无法存储的问题源头就在这里。3. Android端App设计、实现与联调3.1 项目结构划分与基础封装Android端的包结构我建议按模块划分而不是按类型堆叠否则后期找文件找到怀疑人生。比如这样组织activity存放各个页面Activityadapter列表相关的Adapter民宿列表、订单列表等api网络请求接口定义Retrofit接口entity实体类对应后端返回的JSON数据util工具类SP存储、日期转换等这里我用了Retrofit2 OkHttp作为网络请求框架Gson作为JSON解析工具。如果你们还没接触过Retrofit用HttpURLConnection或Volley当然也行但Retrofit的代码简洁度和维护性要明显高出一截简历和论文里也更耐看。网络层封装时注意两个点统一的拦截器在请求头中加入token统一的异常处理网络超时和连接失败要给出清晰提示而不是让App崩溃。OkHttpClient client new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .addInterceptor(new Interceptor() { Override public Response intercept(Chain chain) throws IOException { Request original chain.request(); String token SpUtil.getInstance().getToken(); Request request original.newBuilder() .header(token, token null ? : token) .method(original.method(), original.body()) .build(); return chain.proceed(request); } }) .build();3.2 民宿列表页卡片式列表与筛选条件民宿列表是整个App最核心的界面。Android端用RecyclerView实现列表展示每个item用CardView包裹展示封面图、名称、城市、价格、可订状态。封面图用Glide加载这部分是通用技能点。“根据城市搜索”的功能实现也非常直观搜索框输入城市关键字调用接口GET /api/homestay/list?cityxxpage1pageSize10后端执行模糊查询后返回结果。价格区间筛选可以用RangeSliderMaterial Components库如果没有特殊UI要求可以直接用两个EditText输入最低价和最高价简单且不出错。提示Android端访问本机后端接口时不能写localhost或127.0.0.1必须写电脑的局域网IP例如http://192.168.1.101:8080。否则真机调试时永远连不上。这一点每年都有大量同学踩坑。模拟器里可以用10.0.2.2映射宿主机但真机调试还是用局域网IP最稳。3.3 民宿详情与预订下单流程点击列表项进入详情页展示多张轮播图、价格、设施列表、民宿介绍下面放一个“立即预订”按钮点击后弹出一个底部弹窗选择入住日期和退房日期系统自动算出入住天数最少1晚和总价点击提交即创建订单。订单金额计算逻辑放在后端比较安全前端只做展示。后端在createOrder接口中根据民宿每晚单价和入住天数计算订单金额同时要校验退房日期必须晚于入住日期且所选时间段内房间剩余量充足。这一段代码里有三个关键校验入住日期不能早于当前日期退房日期必须大于入住日期民宿状态必须为上架状态。校验通过后生成订单编号格式推荐yyyyMMddHHmmss 4位随机数保证唯一性。3.4 Android上传图片到后端的实现头像/房源图片我单独把这个功能拎出来是因为很多同学做到一半会卡在这一步。民宿后台添加房源时需要上传封面图用户修改头像也需要上传文件。Android端选择图片用系统相册或相机获取到图片的URI后转成File对象通过OkHttp的MultipartBody上传到后端的文件上传接口。Java实现里这个逻辑不复杂但有个大坑是不同手机的FileProvider配置网上相关的解决方案很零碎。后端接收文件的接口也很简单PostMapping(/api/upload) public ResultString upload(RequestParam(file) MultipartFile file) { if (file.isEmpty()) { return Result.error(400, 文件为空); } String originalFilename file.getOriginalFilename(); String extName originalFilename.substring(originalFilename.lastIndexOf(.)); String fileName UUID.randomUUID().toString().replace(-, ) extName; // 保存到指定目录 file.transferTo(new File(uploadPath, fileName)); return Result.success(/images/ fileName); }图片上传后的访问路径是个容易疏忽的点。如果你的文件保存到项目本地磁盘要配置静态资源映射SpringBoot可以通过WebMvcConfigurer的addResourceHandlers方法将/images/**映射到本地上传目录否则Android端拿到的URL根本加载不出图片。3.5 订单状态流转与用户交互体验订单状态是这个系统的业务命脉。我设计的流转规则是待支付 → 已支付 → 已入住 → 已退房中间状态可以取消待支付时可取消已支付后取消视为退订。Android端“我的订单”页面用TabLayout ViewPager2切换不同状态每个Tab对应一个订单状态码列表展示订单摘要。这一部分把RecyclerView复用、多状态UI切换、下拉刷新都练习到了是典型的Android综合实践场景。值得一说的是接口的返回数据组织。为了让前端少点嵌套请求后端在订单列表接口里可以一次性返回订单详情、民宿简要信息名称、封面图和民宿所在城市等字段用VO类来组装而不是让前端拿到订单后又继续请求民宿接口。写论文时把“VO组装”这个点拿出来能让你的系统设计比普通代码堆砌高一个档次。4. 管理端后台数据管理与权限控制4.1 后台功能清单与设计思路后台管理端我采用了一个轻量方案复用Android端App通过登录时识别角色标识普通用户或管理员动态显示不同的菜单入口。不用单独做Web后台工作量会小很多而且答辩时App上直接演示管理员功能也更直观。后台功能清单房源管理新增房源、编辑房源、上架/下架操作订单管理查看所有用户订单、修改订单状态确认入住、确认退房用户管理查看注册用户列表如果时间充裕可以再加一个“数据统计”页面展示订单总量、营收总额、热门城市Top5使用MPAndroidChart画柱状图或饼图这个点很能提升项目的视觉完成度。4.2 权限拦截的实现细节后端拦截器对“管理员接口”需要双重校验一是校验token是否存在且有效二是校验token中携带的角色标识是否为管理员。Android端在普通用户登录状态下即使手动拼接接口URL也访问不了管理员接口这就是后端权限控制的必要之处。拦截器里可以在JWT的Claims中加入role字段然后在preHandle里读取并比对。如果只是简单地在后端接口里用if判断角色会造成大量重复代码不够优雅。MyBatis-Plus的字段自动填充功能也建议用起来创建时间、更新时间、逻辑删除这些公共字段统一处理既能减少代码量也能保证数据一致性。系统中所有表都建议统一增加create_time和update_time两个字段答辩时讲数据审计观念老师会认可。5. 论文撰写、答辩演示与常见问题排查5.1 毕业论文框架与各章节写作技巧关于论文我给你一套不容易出错的八章结构第一章 绪论背景意义、国内外研究现状、论文组织结构第二章 相关技术介绍SpringBoot、Android、MySQL、MyBatis-Plus第三章 系统分析可行性分析、需求分析、用例图、业务流程第四章 系统设计总体架构图、功能模块设计、数据库设计E-R图、表结构第五章 系统实现各模块的核心代码与截图第六章 系统测试功能测试用例表格、测试结论第七章 总结与展望第八章可选 参考文献与致谢写论文最大的误区是“堆需求描述”罗列“用户可以注册、可以登录、可以下单”这类车轱辘话。老师真正想看到的是你做出的关键决策和理由比如为什么用JWT而不是Session为什么用MyBatis-Plus为什么订单表要冗余民宿价格。每一个技术选型背后都有逻辑把逻辑写清楚论文的层次感立刻就不一样了。5.2 答辩演示节奏与加分技巧答辩时的演示顺序我建议按照“用户端完整业务流 → 管理端后台操作”来安排节奏别乱。第一步演示注册/登录简单带过第二步进入首页浏览民宿演示城市搜索和价格筛选第三步点击民宿详情切换图片选择入住日期并提交订单第四步演示订单状态从待支付到已支付的流转第五步切换管理员账号演示订单状态更新和房源上下架。整个过程控制在8到12分钟最合适。演示前务必备份数据把演示用的测试数据准备好不要临时用全新空库否则列表一旦空白场面会非常冷。另外电脑要提前连接手机并开启USB调试最好准备一张纸质的备用演示方案录屏或截图防止现场无法投屏。答辩老师大概率会关注这几个问题订单并发情况下如何防止超卖、密码如何存储、图片如何存储、Token过期如何处理。你只要能把这几个问题的解决方案讲清楚效果就会很好哪怕实现得不算完美思路正确老师也会给分。5.3 联调常见问题速查表最后我把自己和指导的学生在开发中经常遇到的坑整理成一个速查表建议你收藏起来对照排查问题现象常见原因解决办法Android端访问后端超时使用了localhost地址改为电脑局域网IP中文乱码数据库字符集或连接串未指派utf8mb4建库用utf8mb4url加characterEncodingutf8mb4接口返回时间是一串数字未配置Jackson日期格式yml中配置jackson date-format和time-zone上传图片后URL无法访问缺少静态资源映射配置addResourceHandlers映射到上传目录订单列表重复加载或数据错乱没做分页或分页参数不对统一使用page/pageSize后端分页插件真机安装后闪退没有联网权限AndroidManifest中加INTERNET权限注册时密码显示太长密码字段长度过小数据库字段设为varchar(128)以上Token失效后页面无响应未做全局401处理Retrofit回调中判断code401并跳转登录页如果你准备用这套系统作为毕设我的建议是别一开始就想着把功能做得像携程一样齐全先把主流程跑通也就是“注册登录 浏览房源 下单支付 后台管理”再把细节一点点补上。代码能跑通论文有思路答辩讲清楚这三件事比什么都重要。我个人在实际操作中的体会是毕设最大的门槛往往不是某个技术难点而是整个系统的串并联协调能力。前后端数据格式、字段命名、状态码是否统一决定了你后期的联调效率。如果你现在正在为选题或实现发愁不妨就按这个思路把SpringBoot和Android两端拆开逐步攻克最终你会发现自己完成的不仅仅是一个毕设项目更是一套完整的全栈开发方法论。
返回列表