目录
- 综合练习
- 加法计算器
- 1. 准备工作
- 2. 约定前后端交互接口
- 3. 服务器代码
- 用户登录
- 1. 准备工作
- 2. 约定前后端交互接口
- 3. 服务器代码
- 4. 调整前端页面代码
综合练习
- 理解前后端交互过程
- 接⼝传参, 数据返回, 以及⻚⾯展⽰
加法计算器
需求: 输⼊两个整数, 点击"点击相加"按钮, 显⽰计算结果
1. 准备工作
创建 SpringBoot 项⽬: 引⼊Spring Web依赖, 把前端⻚⾯放在项⽬中
前端方面:添加访问url和请求⽅式<form action="calc/sum" method="post">
calc.html
<!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>
Servlet是放在webapp下面,Spring是放在static下面
2. 约定前后端交互接口
概念介绍
约定 “前后端交互接⼝” 是进⾏ Web 开发中的关键环节.
接⼝⼜叫 API(Application Programming Interface), 我们⼀般讲到接⼝或者 API,指的都是同⼀个东西.
是指应⽤程序对外提供的服务的描述, ⽤于交换信息和执⾏任务(与JavaSE阶段学习的[类和接⼝]中的接⼝是两回事)
简单来说, 就是允许客⼾端给服务器发送哪些 HTTP 请求, 并且每种请求预期获取什么样的 HTTP 响应.
现在"前后端分离"模式开发, 前端和后端代码通常由不同的团队负责开发. 双⽅团队在开发之前, 会提前约定好交互的⽅式. 客⼾端发起请求, 服务器提供对应的服务. 服务器提供的服务种类有很多, 客⼾端按照双⽅约定指定选择哪⼀个服务.
接⼝, 其实也就是我们前⾯⽹络模块讲的的"应⽤层协议". 把约定的内容写在⽂档上, 就是"接⼝⽂档" ,接⼝⽂档也可以理解为是 应⽤程序的"操作说明书".
在项⽬开发前, 根据需求先约定好前后端交互接⼝, 双⽅按照接⼝⽂档进⾏开发
接⼝⽂档通常由服务提供⽅来写, 交由服务使⽤⽅确认,也就是客⼾端.
接⼝⽂档⼀旦写好, 尽量不要轻易改变.
如若需要改变, 必须要通知另⼀⽅知晓.
需求分析
加法计算器功能, 对两个整数进⾏相加, 需要客⼾端提供参与计算的两个数, 服务端返回这两个整数计算的结果
基于以上分析, 我们来定义接⼝
请求路径:calc/sum
请求⽅式:GET/POST
接⼝描述:计算两个整数相加
请求参数:
参数名 | 类型 | 是否必须 | 备注 |
---|---|---|---|
num1 | Integer | 是 | 参与计算的第一个数 |
num2 | Integer | 是 | 参与计算的第二个数 |
⽰例: num1=5&num2=3
响应数据:
Content-Type: text/html
响应内容: 计算机计算结果: 8
服务器给浏览器返回计算的结果
3. 服务器代码
@RestController
@RequestMapping("/calc")
public class CalcController {
@RequestMapping("/sum")
public String sum(Integer num1,Integer num2){
Integer sum=num1+num2;
return "计算结果:"+sum;
}
}
开发中程序报错如何定位问题?
先定位前端还是后端
通过日志
- 前端:按
F12
看控制台- 后端:接口,看控制台日志
看请求是否到达后端,没到后端就是前端问题
我们可以在后端接口处加个打印日志,通常打印在第一行,避免发生错误导致执行不到打印语句
@RequestMapping("/sum") public String sum(Integer num1,Integer num2){ System.out.println("=======sum======="); Integer sum=num1+num2; return "计算结果:"+sum; }
如果后端没有打印,那就是前端问题,就按
F12
看看控制台,如果也没有报错,那就得看代码了如果此时也是发现不了问题,那就测试接口
直接输入
127.0.0.1/calc/sum?num1=5&num2=3
测试,这是我们后端响应的URL,如果这里OK那问题一定在前端
如果重启项目后,有些页面仍无法加载的话怎么办?
这是缓存的问题,我们可以清理缓存
双击后
target
就消失了
注意:浏览器缓存可能也是要清理的
用户登录
需求: ⽤⼾输⼊账号和密码, 后端进⾏校验密码是否正确
- 如果不正确, 前端进⾏⽤⼾告知
- 如果正确, 跳转到⾸⻚. ⾸⻚显⽰当前登录⽤⼾
- 后续再访问⾸⻚, 可以获取到登录⽤⼾信息
1. 准备工作
把前端⻚⾯放在项⽬中
login.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() {
}
</script>
</body>
</html>
index.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>
</script>
</body>
</html>
2. 约定前后端交互接口
需求分析
对于后端开发⼈员⽽⾔, 不涉及前端⻚⾯的展⽰, 只需要提供两个功能
- 登录⻚⾯: 通过账号和密码, 校验输⼊的账号密码是否正确, 并告知前端
- ⾸⻚: 告知前端当前登录⽤⼾. 如果当前已有⽤⼾登录, 返回登录的账号, 如果没有, 返回空
接口定义
- 校验接⼝
请求路径:/user/login
请求⽅式:POST
接⼝描述:校验账号密码是否正确
请求参数
参数名 | 类型 | 是否必须 | 备注 |
---|---|---|---|
userName | String | 是 | 校验的账号 |
password | String | 是 | 校验的密码 |
响应数据
Content-Type: text/html
响应内容:
true //账号密码验证成功
false//账号密码验证失败
- 查询登录⽤⼾接⼝
请求路径:/user/getLoginUser
请求⽅式:GET
接⼝描述:查询当前登录的⽤⼾
请求参数
无
响应数据
Content-Type: text/html
响应内容:
zhangsan
返回当前登录的⽤⼾
3. 服务器代码
@RestController
@RequestMapping("/user")
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;
}
//进行用户名密码校验
if("admin".equals(username)&&"admin".equals(password)){
//设置session
session.setAttribute("username","admin");
return true;
}
return false;
}
@RequestMapping("/getUserInfo")
public String getUserInfo(HttpServletRequest request){
//从session中获取登录用户
HttpSession session=request.getSession(false);
String username=null;
if(session!=null) username= (String) session.getAttribute("username");
return username;
}
}
直接输入http://127.0.0.1:8080/user/login?username=admin&password=admin
测试后端接口,这样不需要前端页面
如果是输入http://127.0.0.1:8080/user/login
则显示false
4. 调整前端页面代码
- 调整登录⻚⾯
login.html
对于前端⽽⾔, 当点击登录按钮时, 需要把⽤⼾输⼊的信息传递到后端进⾏校验, 后端校验成功, 则跳转到⾸⻚:index.html
, 后端校验失败, 则直接弹窗
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
function login() {
console.log("登录...")
$.ajax({
url:"/user/login",
type:"post",
data:{
"userName":$("#userName").val(),
"password":$("#password").val()
},
success:function(result){
if(result){
location.href="/index.html";
//location.assign();
}else{
alert("密码错误")
}
}
});
}
</script>
⻚⾯跳转的三种⽅式:
- window.location.href = “book_list.html”;
- window.location.assign(“book_list.html”);
- window.location.replace(“book_list.html”);
以上写法, 通常把"window." 省略, ⽐如
window.location.href = "book_list.html"
; 写成location.href = "book_list.html";
三者区别参考:https://developer.aliyun.com/article/330720
- 调整首页代码
⾸⻚代码⽐较简单, 只显⽰当前登录⽤⼾即可.
当前登录⽤⼾需要从后端获取, 并显⽰到前端
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
console.log("登录人...")
//页面加载时,就去调用后端请求
$.ajax({
url:"/user/getUserInfo",
type:"get",
success:function(username){
$("#loginUser").text(username);
}
});
</script>
调试
多次刷新 http://127.0.0.1:8080/index.html
发现依然可以获取到登录⽤⼾
如果重启服务器, 则登录⼈显⽰: 空
Session 存在内存中, 如果不做任何处理, 默认服务器重启, Session数据就丢失了
项目如何debug?
如果不想打日志,也可以用断点的方式
在自己的代码上打的断点运行前是红点,服务器运行成功后,是一个带
√
的红点