Spring MVC (下)小项目实战
1. 加法计算器
需求分析:
客户端输入俩个数,服务端进行相加然后返回结果.
约定前后端交互接口:
接口的概念:
接口⼜叫API(ApplicationProgrammingInterface),我们⼀般讲到 接口或者API,指的都是同⼀个东西.是指应⽤程序对外提供的服务的描述,⽤于交换信息和执⾏任务(与JavaSE阶段学习的[类和 接口]中的 接口是两回事).简单来说,就是允许客户端给服务器发送哪些HTTP请求,并且每种请求预期获取什么样的HTTP响应.
现在"前后端分离"模式开发,前端和后端代码通常由不同的团队负责开发.双⽅团队在开发之前,会提前约定好交互的方式.客户端发起请求,服务器提供对应的服务.服务器提供的服务种类有很多,客户端按照双⽅约定指定选择哪⼀个服务.接口,计算机网络讲的的"应用层协议".把约定的内容写在文档上,就是"接口文档",接口文档也可以理解为是应用程序的"操作说明书".
简而言之: 接口(此接口就是api,就是我们刚刚一直访问的url,也就是RequestMapping里面,一般由客户端定义和服务端定义之后,客户端(前端)进行review(检查))
注意事项: 双方并行开发,接口定义之后,不轻易改变,改变了就要通知到每一个调用方,接口定义以接口文档(防止背锅)来进行呈现.
接口设计:
1. 接收什么(看后端完成这个功能需要什么)
2. 返回什么(1.后端能提供什么. 2. 前端页面显示需要什么)
我们这个加法计算器的接口:
请求路径: calc/sum
参数: num1,num2
返回: 俩个数相加的和(sum)
前端代码:
页面展示:
后端代码:
结果:
代码之间的关系:
2. 登录
需求分析:
用户输⼊账号和密码,后端进⾏校验密码是否正确
如果不正确,前端进行用户告知
如果正确,跳转到首页.首页显示当前登录用户
后续再访问首页,可以获取到登录用户信息
页面效果:
补充:异步调用
在发起异步调用后,代码不会等待该调用完成,而是会立即继续执行后续的语句,并在稍后的某个时间点处理异步操作的结果。
约定前后端交互接口:
用户登录
url:/user/login
参数:userName用户名,password密码
返回结果: true false 密码正确还是失败
获取当前登录用户
url:/user/index
参数:无
返回:userName 当前登录用户
前端代码:
用户登录
<!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({//这个是个异步调用的东西
url:"/user/login",
type: "post",
data:{
userName:$("#userName").val(),
password:$("#password").val()
}, //http响应成功的话
success:function(result){
if(result == true){
//页面跳转
location.href = "index.html"
// //另一种跳转方式
// location.assign("index.html")
// //还有一种方式
// location.replace(可以了解一下三种的区别)
}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({
url: "/user/index",
type: "get",
success:function(loginName){
$("#loginUser").text(loginName)
}
})
</script>
</body>
</html>
后端代码:
package org.xiaobai.springmvc_tets.MVCFistclass;
import ch.qos.logback.core.util.StringUtil;
import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;
@RequestMapping("/user")
@RestController
public class UserController {
//用户登录
@RequestMapping("/login")
public Boolean login(String userName, String password, HttpSession session) {
//参数校验
// if(userName == null || userName.length() == 0
// || password == null || password.length() == 0){
// return false;
// }
//另一种判断方式
if(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){
return false;
}
//判断密码是否正确
//上面进行了判空处理userName不为null,但是如果我们没有判断的话就会报空指针,因此我们是admin.eq而不是password.eq
//后面开发的时候我们都把常量字符串写在前面,变量写在后面
if("admin".equals(userName) && "admin".equals(password)) {
//设置session
session.setAttribute("userName",userName);
return true;
}else {
return false;
}
}
//获取当前登录用户
@RequestMapping("/index")
// public String getUserName(HttpSession session){
public String getUserName(@SessionAttribute("userName") String userName){
//从session里面去拿,首先我们要先去设置session里面的内容
return userName;
}
}
注意: StringUtils.hasLength,这个是判断字符串是不是一个空的对象的或者长度为0.
结果:
代码之间的关系:
3. 表白墙
需求分析:
1. 输入留言信息,点击提交.后端收到前端的信息,并且存储起来
2. 前端页面显示输入的表白墙的信息
定义接口:
1. 发布留言(把信息从前端传到后端)
url:/message/publish
param:from,to,say
返回结果: return: 成功/失败 ture/false {ok:1}
2. 查询留言(在前端页面显示所有的留言信息)
url:/message/getList
param:无
返回结果: 返回json[{},{},{}]
引入的工具或者包: lombok
lombok: 它是⼀个Java⼯具库,通过添加注解的⽅式,在编译时期自动帮我们生成代码
步骤:
1. 安装插件EditStart(可以快速把依赖搞到pom里面)
但是注意,不是所有的依赖都可以通过这个插件添加.如果插件没有,那么就自己去手动添加
2. 添加lombok
用法演示:
@Data=@Getter+@Setter+@ToString+@EqualsAndHashCode+@RequiredArgsConstructor+@NoArgsConstructor. 因此@Data是一个复合注解
这个是其他注解的一些解释和作用
接口1的前端后端代码:
后端接受到的消息实体:
主要代码解析:
接口2的前后端代码:
整体的联系:
运行结果:
解决问题常用的办法:
alt+shift+f格式化(idea)
出现问题:
(写完后端,就测后端,写完前端就测前端)
1.定位:是前端还是后端问题
打日志,看后端接收前端数据部分的代码有没有效果
如果没有进入到后端就说明前端有问题,去前端也看看
前端打断点:
然后去前端加日志,看提交数据部分的代码生效不
如果前后端交互都没有拿到值: 去fidde抓包,看请求的参数和postman里面请求参数是不是一样
处理的方法:
1. 后端问题: 打日志,debug
这个是看表达式的值
2. 前端问题: 打日志,抓包
3. 考虑缓存问题刷新(ctrl+f5强制刷新或者清除缓存ctrl+Shift+delet),后端缓存:maven的循环按钮)
好用的小工具: 在线比较代码diff
图书管理系统:
前端工具介绍:
简介 · Bootstrap v4 中文文档 v4.6 | Bootstrap 中文网
用法:
1. 引入css
2. 喜欢哪个构建就copy什么
3. 关于如何修改前端代码
比如在模板上想改颜色,遵循就近原则,我们就去f12,找到它的css样式(就近原则)
应用层分层
分层的概念:
在进入正式的图书管理系统的编写之前,我们需要知道什么是应用层分层
比如,一开始的MVC模式,view是涉及前端的,后面我们实现了前后端分离,现在MVC基本上都是把后端进行功能的拆分,再也不涉及前端.后面后端又进行了进一步的划分.
那么我们理解了什么是分层的操作,什么是应用层分层呢?
应⽤分层是⼀种软件开发设计思想,它将应⽤程序分成N个层次,这N个层次分别负责各自的职责,多个层次之间协同提供完整的功能.根据项⽬的复杂度,把项⽬分成三层,四层或者更多层.
常⻅的MVC设计模式,就是应⽤分层的⼀种具体体现.
为什么分层?
在最开始的时候,为了让项⽬快速上线,我们通常是不考虑分层的.但是随着业务越来越复杂,⼤量的代码混在⼀起,会出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动⼀处就牵⼀发⽽动全⾝等问题.所以学习对项目进⾏分层就是我们程序员的必修课了.简而言之就是更好的管理.
怎么进行分层?
刚刚提到的MVC,就是把整体的系统分成了Model(模型),View(视图)和Controller(控制器)三个层次,也就是将用户视图和业务处理隔离开,并且通过控制器连接起来,很好地实现
了表现和逻辑的解耦,是⼀种标准的软件分层架构。
三层架构:
⽬前现在更主流的开发⽅式是"前后端分离"的⽅式,后端开发⼯程师不再需要关注前端的实现,所以对于Java后端开发者,⼜有了⼀种新的分层架构:把整体架构分为表现层、业务逻辑层和数据层.这种分层⽅式也称之为"三层架构".
1. 表现层:就是展示数据结果和接受用户指令的,是最靠近用户的⼀层;
2. 业务逻辑层:负责处理业务逻辑,里面有复杂业务的具体实现;
3. 数据层:负责存储和管理与应⽤程序相关的数据
简单来理解:
应用层分层(相当于文件管理)->把代码包的好看一些,调理清晰一些
它是一种软件开发思想,把后端代码进行分层
三层架构:
1. 表现层: 接受请求,结果响应(接受参数)
2. 业务逻辑层: 根据请求,对数据进行加工处理
3. 数据层: 数据相关的处理,比如mysql等获取数据
包的分类类型:
Controller:控制层。接收前端发送的请求,对请求进⾏处理,并响应数据。
Service:业务逻辑层。处理具体的业务逻辑。
Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查Model: 放实体类.(比如刚刚表白墙的MessageInf和接下来的BookInf)
几个例子:
重点看下面俩张图
按照上⾯的层次划分,SpringMVC站在后端开发⼈员的⻆度上,也进⾏了⽀持,把上⾯的代码划分为三个部分:
请求处理、响应数据:负责,接收⻚⾯的请求,给⻚⾯响应数据.(表现层,Controller)
逻辑处理:负责业务逻辑处理的代码.(业务逻辑层,Servce)
数据访问:负责业务数据的维护操作,包括增、删、改、查等操作.(数据层,Dao)
MVC和三层架构之间的关系(面试题)
MVC架构模式由三部分组成,分别是:模型(Model),视图(View)和控制器(Controller).
三层架构将业务应⽤划分为:表现层,业务逻辑层,数据访问层.
MVC模式强调数据和视图分离,将数据展⽰和数据处理分开,通过控制器对两者进⾏组合.
三层架构强调不同维度数据处理的⾼内聚和低耦合(一个模块种的各个元素的紧密程度越高越好,不同模块之间的紧密程度越低越好),将交互界⾯,业务处理和数据库操作的逻辑分开.
MVC强调的是数据和视图的分离,三层架构主要是对数据进行了分层,但是⼆者的⽬的是相同的,都是解耦,分层,代码复⽤
关系:
MVC的视图+控制器相当于三层架构种的表现层(接受请求返回响应)
三层架构的业务逻辑层+数据层+实体类=MVC的模型(业务处理)
应用分层的好处:
1. 降低层与层之间的依赖,实现高内聚低耦合
2. 开发人员在修改某一层的代码的时候可以只关注这一层,不必要管其他层,降低了代码的维护成本
3. 有利于标准化
命名规则:
几种书写形式
大驼峰:UserController
小驼峰: userController
蛇形: user_controller
串行: user-controller
大部分企业规范:
类名采用大驼峰: UserController
局部变量,方法名,参数名,成员变量采用小驼峰:userController
常量采用蛇形:DEFAULT_VALUES
css里面采用串行: margin-top
需求分析:
1. 用户登录: 判断用户密码和账号是否正确,完成登录功能
2. 图书列表: 显示所有的图书信息
接口定义:
1. 用户登录
url: /user/login
参数: userName,password
返回: 成功/失败 String(成功: ""进入图书管理系统的页面,失败:返回失败原因
2. 图书列表
url: /book/getBookList
参数:无
返回结果: 图书列表(图书对象).[{},{},{}]
1前后端代码
这里后端代码判断是否密码和账号正确的方式需要解释一下
2前后端代码
注意:
value
可以用来区分多个具有相同名称的复选框
运行结果:
此处图书管理系统只完成了登录和显示图书的功能,后续把功能完善之后我再把代码放上来