文章目录
- 前后端分离设计
- 接口设计思路
- 项目问题解决思路
- 计算器
- 需求分析
- 接口定义
- 前端页面代码
- 服务器代码
- 用户登录
- 需求分析
- 接口定义
- 用户登录校验接口
- 查询登录用户接口
- 前端页面代码
- 用户登录校验
- 查询登录用户
- 服务器代码
- 前后端交互
- 留言版
- 需求分析
- 接口定义
- 获取全部留言
- 发布留言
- 前端页面代码
- 服务器代码
前后端分离设计
前后端分析需要设计接口,接口通常由服务端定义,服务端定义之后,客户端(前端) 进行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;}
}