文章目錄
- 前后端分離設計
- 接口設計思路
- 項目問題解決思路
- 計算器
- 需求分析
- 接口定義
- 前端頁面代碼
- 服務器代碼
- 用戶登錄
- 需求分析
- 接口定義
- 用戶登錄校驗接口
- 查詢登錄用戶接口
- 前端頁面代碼
- 用戶登錄校驗
- 查詢登錄用戶
- 服務器代碼
- 前后端交互
- 留言版
- 需求分析
- 接口定義
- 獲取全部留言
- 發布留言
- 前端頁面代碼
- 服務器代碼
前后端分離設計
前后端分析需要設計接口,接口通常由服務端定義,服務端定義之后,客戶端(前端) 進行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;}
}