Spring MVC 的案例小练习
目录
案例练习
加法计算器
需求
准备工作
约定前后端交互接口
需求分析
接口定义
请求参数
响应数据
服务器代码
postman 测试
调整前端页面代码
启动测试
用户登录
需求
准备工作
需求分析
接口定义:
检验:
请求参数
响应数据
查询登录用户
请求参数:
响应数据:
服务端代码
校验
查询登录用户接口
postman 测试
调整前端页面代码
login.html
编辑
调整首页代码
运行测试
留言板
需求
准备工作
需求分析
接口定义
响应
实现服务端代码
学习 lombok
编辑
服务器代码
postman 测试
修改前端代码
运行测试
图书管理系统
需求
约定前后端交互接口
接口定义
服务器代码
前端代码调整
运行测试
应用分层
代码重构
企业规范
案例练习
目标:
1. 理解前后端交互过程
2. 接口传参,数据返回,以及界面展示
加法计算器
需求
输入两个整数,点击“点击相加”按钮,显示计算结果
准备工作
创建 SpringBoot 项目,引入 Spring Web 依赖,把前端页面放入项目中
约定前后端交互接口
此处的接口,同样不是我们 java 代码中的 interface 的概念。
指的是,应用程序对外提供的服务的描述,用于交换信息和执行任务。
简单来说,就是描述清楚,允许客户端给服务器发送那些 HTTP 请求,并且每种请求预期获得什么样的 HTTP 响应。
现在前后端分离的模式,前端后端由不同团队负责。双方团队在开发之前,会提前约定好相互交互的方式,客户端发出请求,服务端提供对应的服务。
接口,其实就是我们前面提到过的 “应用层协议”,把双方约定的内容以文档的形式显示,就是接口文档。
需求分析
对两个整数进行相加。需要客户端提供参与计算的两个数据,服务端返回两个整数计算的结果。
接口定义
请求参数
响应数据
服务器代码
postman 测试
当我们完成后端代码后,可以进行小步测试,即先直接使用 postman 对后端代码进行测试。
测试正常,先基本确认后端代码可以基本实现功能。
调整前端页面代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<form action="calc/sum" method="post"><h1>计算器</h1>数字1:<input name="num1" type="text"><br>数字2:<input name="num2" type="text"><br><input type="submit" value=" 点击相加 ">
</form>
</body></html>
启动测试
符合预期
用户登录
需求
用户输入账号和密码,后端进行校验密码是否正确
1. 如果不正确,前端提示用户
2. 如果正确,跳转到首页,首页显示当前登录用户
3. 后续再访问首页,可以获取到登录用户信息
准备工作
前端代码:
需求分析
对于后端开发人员,只需要提供两个功能
1. 登录页面,通过用户输入的账号和密码,校验输入的账号密码是否正确,并告知前端
2. 首页,告知前端当前登录用户。如果当前已经有用户登录,返回登录的账号,如果没有,返回空
接口定义:
检验:
请求参数
响应数据
查询登录用户
请求参数:
无
响应数据:
服务端代码
校验
查询登录用户接口
postman 测试
均符合预期。
调整前端页面代码
login.html
对于前端而言,点击登录按钮时候,需要把用户输入的信息传递到后端进行校验。后端校验成功,则跳转到首页:index.html。后端校验失败,则直接弹窗。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>登录页面</title>
</head><body>
<h1>用户登录</h1>
用户名:<input name="userName" type="text" id="userName"><br>
密码:<input name="password" type="password" id="password"><br>
<input type="button" value="登录" onclick="login()"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>function login() {$.ajax({type:"post",url:"/user/login",data:{"userName":$("#userName").val(),"password":$("#password").val(),},success:function (result) {if (result) {location.href = "/index.html"} else {alert("账号或密码错误")}}})}</script>
</body></html>
调整首页代码
<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>用户登录首页</title>
</head><body>
登录人: <span id="loginUser"></span><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>$.ajax({type:"get",url:"/user/getLoginUser",success:function (result) {$("#loginUser").text(result);}})
</script>
</body></html>
运行测试
符合预期
留言板
需求
1.输入留言信息,点击提交,后端把数据存储起来
2. 页面展示输入的留言板的信息
准备工作
需求分析
后端需要提供两个服务:
1. 提交留言:用户在前端输入留言信息后,后端需要把浏览信息保存起来
2. 展示留言:页面展示的时候,需要从后端获取到所有的留言信息
接口定义
1. 获取全部留言
我们可以用 List 表达,用 JSON 来描述这个 List 数据
响应
2. 发表新留言
实现服务端代码
学习 lombok
Lombok 是一个 Java 工具库,通过加注解的方式,方便 Java 开发
引入依赖:
或者下载 EditStrats 插件 然后一键引入:
Lombok 可以通过一些注解的方式,帮我们消除一些冗长的代码,让代码看起来更加简洁。
@Data 注解会帮我们自动生成一些方法,包括 getter / setter equals toString ...
@Data 如果认为比较粗暴,lombok 也提供了一些更精细的注解
服务器代码
postman 测试
符合预期
修改前端代码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>留言板</title><style>.container {width: 350px;height: 300px;margin: 0 auto;/* border: 1px black solid; */text-align: center;}.grey {color: grey;}.container .row {width: 350px;height: 40px;display: flex;justify-content: space-between;align-items: center;}.container .row input {width: 260px;height: 30px;}#submit {width: 350px;height: 40px;background-color: orange;color: white;border: none;margin: 10px;border-radius: 5px;font-size: 20px;}</style>
</head><body>
<div class="container"><h1>留言板</h1><p class="grey">输入后点击提交, 会将信息显示下方空白处</p><div class="row"><span>谁:</span> <input type="text" name="" id="from"></div><div class="row"><span>对谁:</span> <input type="text" name="" id="to"></div><div class="row"><span>说什么:</span> <input type="text" name="" id="say"></div><input type="button" value="提交" id="submit" onclick="submit()"><!-- <div>A 对 B 说: hello</div> -->
</div><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>$.ajax({type:"get",url:"/message/getList",success:function (result) {for (var message of result) {var divE = "<div>" + message.from + "对" + message.to + "说" + message.message + "</div>"$(".container").append(divE);}}})function submit(){//1. 获取留言的内容var from = $('#from').val();var to = $('#to').val();var say = $('#say').val();if (from== '' || to == '' || say == '') {return;}$.ajax({type:"post",url:"/message/publish",data:{from:from,to:to,message:say},success:function (result) {if (result) {// 2. 构造节点var divE = "<div>" + from + "对" + to + "说" + say + "</div>";// 3. 把节点添加到页面上$(".container").append(divE)// 4. 情况输入框的值$('#from').val("")$('#to').val("")$('#say').val("")} else {alert("发表留言失败")}}})}</script>
</body></html>
运行测试
符合预期
补充:此时我们每次提交的数据都会发送给服务器,每次打开页面的时候,页面都会从服务器加载数据,因此即使刷新页面,数据也不会丢失。
但,此时的数据是存储在服务器的内存中(private List<MessageInfo> messageInfos = new ArrayList<>())一旦服务器重启,数据仍然会丢失。
图书管理系统
需求
1. 登录:用户输入账号,密码完成登录功能
2. 列表展示:展示图书
约定前后端交互接口
根据需求可知,后端需要提供两个接口:
1. 账号密码校验接口:根据输入的用户名和密码校验登录是否通过
2. 图书列表:提供图书列表信息
接口定义
1.登录接口:
2. 图书列表展示
服务器代码
创建图书类 BookInfo
创建 UserController 实现登录验证接口
创建 BookController 获得图书列表
补充:此处数据采用 mock 的方式,实际数据应该从数据库中进行获取
mock:模拟的,假的。用于在开发和测试过程中,协同开发,进度不一致时候,对数据进行模拟样本,用来辅助开发和测试工作。
前端代码调整
登录页面:
图书列表展示:
运行测试
符合预期~
页面工程并未完善,后期我们可以再进行完善~
应用分层
我们通过上面三个案例,学习了一些 Spring MVC 简单功能的开发。但上面我们程序的代码比较杂乱~
在阿里的开发手册中,关于工程结构部分,定义了一些常见工程的应用分层结构
应用分层,是一种软件开发设计思想,将应用程序分为 N 个层次,N 个层次分别有鸽子的职能,多个层次之间协同合作,完成完整的功能~
MVC 模式,就是应用分层的一种具体体现~
现在的主流开发方式是“前后端分离”的方式,我们后端工程师不再需要关注前端的实现,所以对于 Java 后端开发者,有了一种新的分层架构:把整体架构分为表现层,业务逻辑层和数据层,称之为 “三层架构”。
表现层:展示数据结果和接收用户指令,最靠近用户的一层
业务逻辑层:负责处理业务逻辑,里面有复杂业务的具体实现
数据层:负责存储和管理与应用程序相关的数据
而我们前面的代码,则是将之都混为一谈了~
Spring MVC 将上面的代码分层转换为如下三部分:
Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。
Service:业务逻辑层。处理具体的业务逻辑。
Dao:数据访问层。也成为持久层。负责数据的访问操作,包括数据的增删改查。
代码重构
我们使用上面的分层思想,对图书管理系统的代码及逆行改造~
创建对应的包路径,并把对应的代码移动到对应的目录
代码拆分:
控制层:接收前端发送的请求,对请求进行处理,并响应数据
业务逻辑层:处理具体的业务逻辑
数据访问层:负责数据访问操作,数据的增删改查
企业规范
1. 类名使用大驼峰
2. 方法名,参数名,成员变量,局部变量,统一使用小驼峰
3. 包名统一使用小写