文章目录
前后端分离设计
前后端分析需要设计接口,接口通常由服务端定义,服务端定义之后,客户端(前端) 进行review,双方并行开发。
接口定义之后,不轻易改变,如果需要改变,必须要通知到每一个调用方,同步修改接口文档接口定义,以接口文档来呈现。
如果修改的比较少,或者之前的文档没有体现到这点,不想修改文档时,可以通过聊天工具去说一下。
接口设计思路
- 接收什么(看后端完成这个功能需要什么)
- 返回什么(1.后端能提供什么,2,前端页面展示需要什么)
项目问题解决思路
- 先测试后端接口,通过postman测试后端接口没有问题,暂时排除后端问题
- 看日志,可以借助Debug
- 如果觉得代码没问题,优先考虑缓存问题,前端缓存 ctrl+F5 强制刷新,或者清除浏览器缓存后端缓存(maven->clean)
计算器
需求分析
加法计算器功能,对两个整数进⾏相加,需要客户端提供参与计算的两个数,服务端返回这两个整数计算的结果
接口定义
- 请求路径:/calc/sum
- 请求方式:GET/POST
- 接口描述:计算两个整数相加
- 返回:sum
- 参数:num1、num2
参数名 | 类型 | 是否必须 | 备注 |
---|---|---|---|
num1 | Integer | 是 | 参与计算的第⼀个数 |
num2 | Integer | 是 | 参与计算的第二个数 |
前端页面代码
<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>
服务器代码
@RequestMapping("/calc")
@RestController
public class CalcController {
@RequestMapping("/sum")
public String sum(Integer num1, Integer num2) {
return String.valueOf(num1 + num2);
}
}
用户登录
需求分析
用户输⼊账号和密码,后端进⾏校验密码是否正确
- 如果不正确,前端进行用户告知
- 如果正确,跳转到首页,首页显示当前登录用户
- 后续再访问首页,可以获取到登录用户信息
对于后端开发⼈员,不涉及前端页面的展示,只需要提供两个功能
- 登录页面:通过账号和密码,校验输⼊的账号密码是否正确,并告知前端
- 首页:告知前端当前登录用户,如果当前已有用户登录,返回登录的账号,如果没有,返回空
接口定义
用户登录校验接口
- 请求路径:/user/login
- 请求方式:GET/POST
- 接口描述:校验账号密码是否正确
- 返回:
true //账号密码验证成功
false//账号密码验证失败 - 参数:username、password
参数名 | 类型 | 是否必须 | 备注 |
---|---|---|---|
username | String | 是 | 校验的账号 |
password | String | 是 | 校验的密码 |
查询登录用户接口
- 请求路径:/user/indexs
- 请求方式:GET/POST
- 接口描述:查询当前登录的用户
- 返回:
当前登录的用户–username - 参数:无
前端页面代码
用户登录校验
<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");
}else{
alert("密码错误");
}
}
})
}
</script>
查询登录用户
登录人: <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>
服务器代码
@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;
// }
//Spring提供的参数校验的简化版本
if (!StringUtils.hasText(username) || !StringUtils.hasText(password)) {
return false;
}
//判断密码是否正确
//写equlas()方法时,最好将常量放在前面
if ("admin".equals(username) && "admin".equals(password)) {
//设置session信息
session.setAttribute("username", username);
return true;
}
return false;
}
@RequestMapping("/index")
public String getUsername(@SessionAttribute("username") String username) {
return username;
}
}
前后端交互
通过ajax中的参数实现前后的交互,部分位置中的前后端参数的名称必须对应。
包括设置的session,在寻找对应的username时,也必须保持一致。
留言版
需求分析
- 输入留言信息,点击提交,后端把数据存储起来。
- 页面展示输入的留言板的信息
后端需要提供两个服务
- 提交留言:用户输入留⾔信息之后,后端需要把留言信息保存起来。
- 展示留言:页面展示时,需要从后端获取到所有的留⾔信息。
接口定义
获取全部留言
全部留言信息,⽤List来表示,可以用JSON来描述这个List数据,这里简化描述。
- url:/message/getList
- param:无
- return:[{},{},{}]
发布留言
- url:/message/publish
- param:from, to, say
- return:true/false
前端页面代码
<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({
url: "/message/getList",
type: "get",
success: function (messageInfos) {
console.log("成功获取消息列表:", messageInfos);
var finalHtml = "";
for (var message of messageInfos) {
finalHtml += '<div>' + message.from + ' 对 ' + message.to + ' 说: ' + message.say + '</div>';
}
$(".container").append(finalHtml)
}
});
function submit() {
//1. 获取留言的内容
var fromQian = $('#from').val();
var toQian = $('#to').val();
var sayQian = $('#say').val();
if (fromQian == '' || toQian == '' || sayQian == '') {
return;
}
//发送ajax请求,这里为了更好地看清楚前后端的交互过程
$.ajax({
url: "/message/publish",
type: "post",
data: {
from: fromQian,
to: toQian,
say: sayQian
},
success: function (result) {
if (result) {
//2. 构造节点
var divE = "<div>" + fromQian + "对" + toQian + "说:" + sayQian + "</div>";
//3. 把节点添加到页面上
$(".container").append(divE);
//4. 清空输入框的值
$('#from').val("");
$('#to').val("");
$('#say').val("");
}else{
alert("输入不合法")
}
}
});
}
</script>
</body>
服务器代码
@RequestMapping("message")
@RestController
public class MessageController {
private List<MessageInfo> messageInfos = new ArrayList<>();
@RequestMapping("publish")
public Boolean publish(MessageInfo messageInfo) {
//1.参数校验
if (!StringUtils.hasLength(messageInfo.getFrom()) || !StringUtils.hasLength(messageInfo.getTo()) || !StringUtils.hasLength(messageInfo.getSay())) {
return false;
}
//2.存储数据,暂时存在内存中
messageInfos.add(messageInfo);
return true;
}
/** 获取留言信息 */
@RequestMapping("getList")
public List<MessageInfo> getList(){
return messageInfos;
}
}