SpringMVC综合性练习
在对SpringMVC有了一定学习后,我们可以通过做一些小案例,来掌握以下知识点:
1.理解前后端交互过程
2.接口传参,数据返回,以及页面展示
练习一:加法计算器
需求:输入两个整数,点击"点击相加"按钮,显示计算结果
这里我们主要是学习后端开发,所以该练习的前端代码我们不做过多解释
1.约定前后端交互接口
约定"前后端接口"是进行web开发中的关键环节
接口又叫API(Application Programming Interface) ,我们一般讲到的API或者接口是一个东西
是指应用程序对外提供的服务描述,用于交换信息和执行任务(与JAVASE阶段的类和接口不是一回事)
简单来说,就是允许客户单给服务器发送哪些HTTP请求,并且每种请求预期获取什么样的HTTP响应
接口,其实也就是我们前面网络模块学习到的"应用层协议",把约定的内容写到文档上,就是"接口文档",接口文档也可以理解为应用程序的"操作说明书"
需求开发前,先定义接口文档 前后端双方都按照接口文档进行开发
我们这个小案例中,要求对两个整数进行相加,需要客户端提供参与计算的两个数,服务端返回这两个数相加的结果
基于上述分析,我们来定义接口
请求路径:calc/sum
请求方式:get/post
接口描述:计算两个整数相加
请求参数:
|------|---------|------|-----------|
| 参数名 | 类型 | 是否必需 | 备注 |
| num1 | Integer | 是 | 参与计算的第一个数 |
| num2 | Integer | 是 | 参与计算的第二个数 |
响应数据:
Content-Type:text/html
响应内容:计算结果
2.服务器代码
java
@RestController
@RequestMapping("/calc")
public class CalcController {
@RequestMapping("/sum")
public String sum(Integer num1,Integer num2){
Integer sum = num1 + num2;
return "<h1>计算结果: " + sum +"</h1>";
}
}
3.调整前端页面代码
html
<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>
效果展示如下


练习二:用户登录
需求:用户输入账号和密码,后端进行校验密码是否正确
1.如果不正确,前端需进行用户告知
2.如果正确,跳转到首页,首页显示当前登录用户
3.后续再访问首页,可以获取到登录用户信息
1.约定前后端交互接口
需求分析:
对于后端开发人员来说,不涉及前端页面的展示,只需要提供给两个功能:
1.登录页面:通过账号和密码,校验输入的账号密码是否正确,并告知前端
2.首页:告知前端当前登录用户,如果当前已经有用户登录,返回登录的账号,如果没有,返回空
接口定义:
1.校验接口:
请求路径:/user/login
请求方式:POST
接口描述:校验账号密码是否正确
|----------|--------|------|-------|
| 参数名 | 类型 | 是否必须 | 备注 |
| userName | String | 是 | 校验的账号 |
| password | String | 是 | 校验的密码 |
响应数据:
Content-Type:text/html
响应内容: true//账号密码验证成功
false//账号密码验证失败
2.查询登录用户接口
请求路径:/user/getUserLogin
请求方式:GET
接口描述:查询当前登录的用户
请求参数:无
响应数据:
Content-Type:text/hmtl
响应内容:当前登录用户的名称
2.服务端代码
这里StringUtils.hasLength()是Spring提供的一个工具方法,用来判断字符串是否有值
字符串为null/""时,返回false,其余返回空 我们尽量把常量写在前面,否则可能会报空指针异常
java
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public boolean login(String userName, String password, HttpSession session){
//账号/密码为空
if(!StringUtils.hasLength(userName)||!StringUtils.hasLength(password)){
return false;
}
//校验账号密码是否正确
//理论上应该从数据库中获取账号密码,校验是否正确,但当前我们还为学习数据库的操作,我们这里先把这个账号密码写死
if(!"july".equals(userName)||!"060702".equals(password)){
return false;
}
session.setAttribute("userName",userName);
return true;
}
}
java
@RequestMapping("/getUserLogin")
public String getUserLogin(HttpSession session){
//从Session中获取用户登录信息
String userName = (String)session.getAttribute("userName");
if(StringUtils.hasLength(userName)){
return userName ;
}
return "";
}
3.调整前端页面
1.调整login.html
对于前端而言,当点击登录页面的时候,需要把用户输入的信息传递到后端进行校验,后端校验成功,则跳转到首页index.html 后端校验失败,则直接弹窗
html
<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>
页面跳转的三种方式:1.window.location.href ="xx.html" 2.window.location.assign("xx.html")
3,window.location.replace("xx.html")
我们通常省略window
2.调整首页代码
html
<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/getUserLogin",
success:function(result){
$("loginUser").text(result);
}
});
</script>
</body>
效果展示


如果重启服务器,则登录人显示:空(session存在内存中,如果不做任何处理,默认服务器重启,session数据就丢失了)
1.lombok介绍
在这里我们介绍一个新的工具包lombok
lombok是一个JAVA工具包,通过添加注解的方式,简化JAVA的开发
他的使用:1.引入依赖 2.lombok通过一些注解的方式,可以帮助我们消除一些冗长的代码
@Data注解会帮助我们自动生成一些方法,包含getter/setter/equals/toString等
lombok是一款在编译器生成代码的工具包

如果觉得@Data生成的方法太多,lombok也提供了一些更精细粒度的注解
|--------------------------|-----------------------------------|
| 注解 | 作用 |
| @Getter | 自动添加getter方法 |
| @Setter | 自动添加setter方法 |
| @ToString | 自动添加toString方法 |
| @EqualsAndHashCode | 自动添加equal和hashcode方法 |
| @NoArgsConstructor | 自动添加无参构造方法 |
| @AllArgsConstructor | 自动添加全属性构造方法,顺序按照属性的定义属性 |
| @NonNull | 属性不能为null |
| @RequiredArgsConstructor | 自动添加必需属性的构造方法,final+@NonNull属性未必需 |
| | |
更快捷的引入依赖:插件EditStarter
JSON.parseJSON字符串转对象
JSON.stringfy 对象转JSON字符串
应用分层
在上面的练习过程中,我们学习了SpringMVC简单功能的开发,但我们也发现了一些问题,目前我们程序的代码有一些杂乱,但我们目前只开发了一点点内容,随着功能的增多,代码会更加杂乱无章(文件乱,代码内容乱)
正是基于此,我们要学习应用分层
阿里开发手册中,关于工程结构部分,定义了常见工程的应用分层结构:

那么是什么是应用分层呢?
我们之前学习的MVC,就是把整体的系统划分成了Model,View ,Controller三个层次,也就是把用户视图和业务系统处理隔离开,并且通过控制器连接起来,很好的实现了表现和逻辑的解耦,是一种标准的软件分层架构
目前更主流的开发方式是"前后端"的方式,后端开发工程师不再需要关注前端的实现,所以对于后端开发者,又有了一种新的分层结构:把整体架构分为表现层,业务逻辑层和数据层.这种分层方式也称之为三层架构
1.表示层:就是展示数据结果和接受用户指令的,是最靠近用户的一层
2.业务逻辑层:负责处理业务逻辑,里面有复杂业务的具体实现
3.数据层:负责存储和管理与应用程序相关的数据

Controller:控制层.接受前端发送的请求,对请求进行处理,并响应数据
Service:业务逻辑层,处理具体的业务逻辑
Dao:数据访问层,也称之为持久层,负责数据访问操作,包括数据的增删改查
实体类:model,pojo,entiy
这里我们总结一下MVC和三层架构的区别和联系
从概念上两看,这两者都是软件工程领域中的架构模式
MVC架构模式由三部分组成,分别是:模型(Model),视图(View)和控制器(Controller)
三层架构将业务应用划分为:表现层(Controller),业务逻辑层(Service)和数据访问层(Dao)
MVC中,视图和控制器合起来对应三层架构中的表现层,模型对应三层架构中的业务逻辑层,数据层以及实体类
二者其实是从不同角度对软件工程进行了抽象
MVC模式强调的是数据和视图的分离,将数据展示和数据处理分开,通过处理器将两者组合
三层架构强调不同维度数据处理的高内聚和低耦合,将交互界面业务处理和数据库操作的逻辑分开
角度不同也就谈不上互相替代了,在日常的开发中,通常看到两者共存的情况,比如我们设计模型层的时候往往也会拆分出业务逻辑层和数据访问层
但是二者的目的是相同的,都是"解耦,分层,代码复用"
软件设计的原则:高内聚低耦合
高内聚指的是:一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句,程序段)之间的联系程度越高,则内聚性越高,即"高内聚"
低耦合是值:软件中各个层,模块之间的依赖关联程度越低越好,修改一处代码,其他模块的代码改动越少越好
高内聚和低耦合并不矛盾(高内聚指的是一个模块中各个元素之间联系的紧密程度,低耦合指的是各个模块直接的紧密程度)