- 分布式系統架構:技術棧詳解與快速進階
- 張程
- 1189字
- 2020-08-13 13:45:30
2.1.1 傳統交互模式
傳統交互模式主要由JSP做動態網頁與服務器端MVC模式進行交互,如圖2-1所示。

圖2-1 瀏覽器和服務器端交互
注意,前后端耦合在一起,靜態資源(JS、Img、CSS)等同業務程序在同一個工程中,JSP頁面會引入JS、CSS、Img等資源。JSP本身可配置標簽,用于動態獲取數據展示。兩者間的交互方式如下。
1)通過標簽。如常用Form表單,通過HTTP傳輸方式,指定服務器端URL進行傳輸,服務器端通過處理,返回數據,JSP頁面通過標簽獲取到數據展示。
2)通過引入JS。通過Ajax異步請求方式,頁面端Ajax可以和服務器端約定好數據體格式,對頁面參數組裝后,通過HTTP傳輸方式,指定服務器端URL進行傳輸,服務器端通過處理,返回數據,Ajax接收到數據后進行解析并最終展示。
最開始使用第一種方式,頁面本身支持,無須引入其他組件。因為頁面需要定期展示新的數據而需要刷新,用戶體驗較差。為了解決頁面無刷新動態獲取數據,提高用戶體驗,誕生了第二種方式——Ajax異步請求方式。特點是用戶無感知,動態獲取服務器端數據,提高用戶體驗。
服務端采用MVC模式,即Model(模型)、View(視圖)、Controller(控制器),這種模式主要體現在模型和視圖分離,讓一個程序有多種展示形式。
在網頁中視圖層指用戶能夠看到并與其交互的界面。MVC可以提供多種視圖模型,視圖中不展示用戶數據,它只是一種輸出數據并允許用戶操作的方式。模型層指業務規則,可以處理不同業務的任務,模型和數據格式無關,同樣一個模型可以為多個視圖提供數據。控制器層指接收用戶的輸入并會調用模型層和視圖層去完成業務功能,控制器本身不輸出任何數據和格式,控制器主要接收請求并決定它會調用哪個模型去構造并處理請求,以及最后會選擇哪個視圖來顯示數據。
前后端交互工程結構如圖2-2所示。

圖2-2 前后端交互工程結構示意圖
下面介紹如何用JSP引入靜態資源代碼,具體如代碼清單2-1所示。
代碼清單2-1 用JSP引入靜態資源代碼
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link href="${pageContext.request.contextPath}/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.11.0.min.js"></script> <title>demo</title> </head> <body> <form action="${pageContext.request.contextPath}/demo/query" method="POST"> 標題: <input type="text" id=”title” /> 查詢:<input type="submit" id=”query”/> </form> </body> </html>
通過JS內置傳統Ajax異步獲取服務器端數據,具體如代碼清單2-2所示。
代碼清單2-2 JS內置傳統Ajax異步獲取數據代碼
query.onclick = function(){ var data= document.getElementById("title"); var request = createXHR(); request.onreadystatechange = function(){ if(request.readyState === 4){ if(request.status === 200){ createResult.innerHTML = request.responseText; }else{ alert("發生錯誤"+request.status); } } }; request.open("POST", contextPath+"/demo/query",false); request.send(data); }
在jQuery中通過Ajax異步獲取服務器端數據,如代碼清單2-3所示。
代碼清單2-3 jQuery封裝Ajax異步獲取數據代碼
$.ajax({ type:"POST", url: contextPath+"/demo/query", dataType:"json", data:{ title:$("#title").val() }, success:function(data){ if(data.success){ $("#createResult").html(data.msg); }else{ $("#createResult").html("出現錯誤:"+data.msg); } }, error: function(jqXHR){ alert("發生錯誤:"+jqXHR.status); } });
在服務器端通過MVC模式處理數據,如代碼清單2-4所示。
代碼清單2-4 服務器端MVC模式代碼
public class GoodsServlet extends HttpServlet{ private static final long serialVersionUID = -5352453280392723315L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("html/text;charse=utf-8"); /** * 獲取查詢條件 */ String title = request.getParameter("title"); /** * 控制器層調用模型層 * 實例化service * 獲取數據返回信息 */ GoodsInfoService goodsService = new GoodsServiceImpl(); Goods goods = goodsService.query(title); // 存儲頁面展示數據,控制器層調用視圖層 request.getSession().setAttribute("goods", goods); response.sendRedirect("demo.jsp"); } }
傳統交互模式存在如下問題。
1)靜態資源頁面和服務器端代碼屬于同一工程,耦合性較強。
2)部署在同一個服務器,影響面較廣。
3)JSP頁面獲取數據后需要編譯,性能較差。
4)頁面渲染速度較差,影響用戶體驗。
5)橫向擴展復雜,分攤壓力能力差。