前後端對接及接口管理平臺淺析

關與作者更多博客請訪問雲裏雲外開源社區

每一個完整的項目都是不是一個人的功勞,是一個團隊的心血!那麼在這個項目從無到有的過程中,一個團隊是如何凝聚呢?如何共享信息呢?會議及活動是如何開展呢?前端和後端又是如何對接的呢?

在剛剛收到項目時,我有很多問號?其中最大的一個就是接口是個什麼鬼,我相信大家也或多或少有這個想法。隨着學習的逐漸深入,它神祕的面紗似乎也在一層層的揭開,我們開始接觸到了postman等接口測試工具,但這還是不夠直觀。其實最好的理解在於實踐,再多的文字介紹也不如真實和前端小姐姐對接一下的效果好!(但文字還是要有的)

爲什麼需要分離呢?

隨着技術的不斷進步,對前端後端的要求也不斷升級。前端的展示業務、要求、質量、交互體驗越來越靈活、炫麗,響應體驗也要求越來越高,工作量越來越繁重!而後端責着重提供各種服務以及高併發、高可用、高性能、高擴展等。

由此導致了前後端分離。各自專注於自己負責的模塊。詳情參考

一、接口是什麼(附帶簡易案例)

由於目前項目採用SpringMVC架構,後臺接口就是servlet,我們事實上可以將接口理解爲servlet(不知道還有沒有其他類型的,如果還有其他請積極指正)。那麼servlet又是什麼呢?

servlet

簡單的說servlet就是跑在web服務器中的小Java程序,是Java中的類,用來接受和相應網頁傳過來的東西,主要是http。

這裏暫時不介紹servlet的詳細用法,有需求的同學可以參考這篇https://blog.csdn.net/chachapaofan/article/details/82631841,這裏用一個簡單的案例來說明(因爲技術原因,只能jsp來演示調用接口,需要用到ajax詳細介紹,前端的調用本質上類似)如果是要用axios,請參考靳紫瀾同學博客

還是先介紹概念: XMLHttpRequest 對象的三個重要的屬性:

屬性 描述
onreadystatechange 存儲函數(或函數名),每當 readyState 屬性改變時,就會調用該函數。
readyState 存有 XMLHttpRequest 的狀態。從 0 到 4 發生變化。 0: 請求未初始化 1: 服務器連接已建立 2: 請求已接收 3: 請求處理中 4: 請求已完成,且響應已就緒
status 200: “OK” 404: 未找到頁面

在 onreadystatechange 事件中,我們規定當服務器響應已做好被處理的準備時所執行的任務。

方法 描述
open(method,url,async) 規定請求的類型、URL 以及是否異步處理請求。 method:請求的類型;GET 或 POST url:文件在服務器上的位置 async:true(異步)或 false(同步)
send(string) 將請求發送到服務器。 string:僅用於 POST 請求
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">

    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
    <script>
        // 在頁面的 head 部分添加一個 <script> 標籤。該標籤中包含了這個 TestAjax() 函數
        function TestAjax(){
            //var 是創建變量
            var xmlHttp;
            // 所有現代瀏覽器均支持 XMLHttpRequest 對象(IE5 和 IE6 使用 ActiveXObject)。
            // XMLHttpRequest 用於在後臺與服務器交換數據。這意味着可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。
            // 如果支持,則創建 XMLHttpRequest 對象。如果不支持,則創建 ActiveXObject :
            if (window.XMLHttpRequest) {
                //  IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行代碼
                xmlHttp = new XMLHttpRequest();

            } else {
                // IE6, IE5 瀏覽器執行代碼
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlHttp.onreadystatechange = function(){
                //當 readyState 等於 4 且狀態爲 200 時,表示響應已就緒:readyState是XMLHttpRequest的一個屬性
                if (xmlHttp.readyState==4 && xmlHttp.status==200) {
                    document.getElementById("sp").innerHTML = xmlHttp.responseText;
                }
            }
//這個地方在地址後設置了一個屬性name=LiGuorui,在servlet中會用到
            xmlHttp.open("GET", "/servlet2/TestAjax?name=LiGuorui", true);
            xmlHttp.send();
        }
    </script>
</head>

<body>
<%--當按鈕被點擊時,它負責調用名爲 TestAjax() 的函數--%>
<button onclick="TestAjax()">利用Ajax獲取數據</button> <br>
<span id = "sp"></span>

</body>
</html>

servlet

@WebServlet(name = "TestAjax",urlPatterns = "/servlet2/TestAjax")
    public class TestAjax extends HttpServlet {
        private static final long serialVersionUID = 1L;

        /**
         * @see HttpServlet#HttpServlet()
         */
        public TestAjax() {
            super();
            // TODO Auto-generated constructor stub
        }

        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();
            out.println("Hello " + request.getParameter("name"));
            out.flush();
        }

        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
}

二、Tomcat的Servlet

img

由上圖可以看出Tomcat最頂層的容器是Server,代表整個服務器。一個Server可以包含至少一個Service,用於提供服務。

Service主要有兩大核心組件,Connector和Container。Connector主要負責對外交流,而container則是處理內部事務。一個Service可以有多個Connector,但只能有一個Container。

多個 Connector 和一個 Container 就形成了一個 Service,有了 Service 就可以對外提供服務了,再加上生存環境Server。整個 Tomcat 的生命週期由 Server 控制。

三、json

Java中並沒有內置JSON的解析,因此使用JSON需要藉助第三方類庫。

下面是幾個常用的 JSON 解析類庫:

  • Gson: 谷歌開發的 JSON 庫,功能十分全面。

  • FastJson: 阿里巴巴開發的 JSON 庫,性能十分優秀。

  • Jackson: 社區十分活躍且更新速度很快。

  • 1.1:JSON對象

    我們先來看以下數據:

    {
    	"ID": 1001,
    	"name": "張三",
    	"age": 24
    }
    

    第一個數據就是一個Json對象,觀察它的數據形式,可以得出以下語法:

    1:數據在花括號中

    2:數據以"鍵:值"對的形式出現(其中鍵多以字符串形式出現,值可取字符串,數值,甚至其他json對象)

    3:每兩個"鍵:值"對以逗號分隔(最後一個"鍵:值"對省略逗號)

    遵守上面3點,便可以形成一個json對象。
    1.2:JSON對象數組

    接下來我們再看第二個數據,觀察它的數據形式,可以得出以下語法:

    [
    	{"ID": 1001, "name": "張三", "age": 24},
    	{"ID": 1002, "name": "李四", "age": 25},
    	{"ID": 1003, "name": "王五", "age": 22}
    ]
    

    1:數據在方括號中(可理解爲數組)

    2:方括號中每個數據以json對象形式出現

    3:每兩個數據以逗號分隔(最後一個無需逗號)

    遵守上面3點,便可形成一個json對象數組(及一個數組中,存儲了多個json對象)

    理解了上面兩種基本的形式,我們就可以得出其他的數據形式,例如下面這個:

    {
    	"部門名稱":"研發部",
    	"部門成員":[
    	{"ID": 1001, "name": "張三", "age": 24},
    	{"ID": 1002, "name": "李四", "age": 25},
    	{"ID": 1003, "name": "王五", "age": 22}],
    	"部門位置":"xx樓21號"
    }
    

    這是上面兩個基本形式結合出來的一種變形,通過這種變形,使得數據的封裝具有很大的靈活性,能讓開發者自由的發揮想象力。

    1.3:JSON字符串

    Json字符串應滿足以下條件:

    1. 1它必須是一個字符串,支持字符串的各種操作
    2. 裏面的數據格式應該要滿足其中一個格式,可以是json對象,也可以是json對象數組或者是兩種基本形式的組合變形。

    總結:json可以簡單的分爲基本形式:json對象,json對象數組。兩種基本格式組合變形出其他的形式,但其本質還是json對象或者json對象數組中的一種。json對象或對象數組可以轉化爲json字符串,使用於不同的場合。

    Fastjson

    在fastjson包中主要有3個類,JSON,JSONArray,JSONObject

    三者之間的關係如下,JSONObject和JSONArray繼承JSON,JSONObject代表json對象,JSONArray代表json對象數組,JSON代表JSONObject和JSONArray的轉化。

    這裏主要介紹兩種轉化方法

    JSON類之toJSONString()方法,實現json對象轉化爲json字符串和javabean對象轉化爲json 字符串
    
    JSON類之JSONArray()方法,實現json字符串轉化爲json對象數組或List<T>
    
    public class Changing {
        /**
        將集合轉換爲json格式的數據
         */
        public String toJson(List list){
            String str = JSON.toJSONString(list);
            return  str;
        }
        /**
        將json格式的數據轉化爲泛型爲Notes類的集合
         */
        public List<Notes> JsonChange(String str){
            List<Notes> notes = JSON.parseArray(str,Notes.class);
            return notes;
        }
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            Changing changing = new Changing();
            List<Notes> notes = changing.JsonChange(sc.next());
            for(int i=0;i<notes.size();i++){
                System.out.println(notes.get(i).toString());
            }
            List<Notes> notes1 = new ArrayList<Notes>();
            Notes notes2 = new Notes(1,"測試","hhh","yes","moren");
            notes1.add(0,notes2);
            System.out.println(changing.toJson(notes1));
           //[{"category":"moren","content":"hhh","hasOpen":"yes","noteId":1,"title":"測試"},{"category":"moren","content":"hhh","hasOpen":"yes","noteId":1,"title":"測試"}]
        }
    }
    
    /*輸入
    [{"category":"moren","content":"hhh","hasOpen":"yes","noteId":1,"title":"測試"},  {"category":"moren","content":"hhh","hasOpen":"yes","noteId":1,"title":"測試"}]*/
    /*輸出的
    Notes{noteId=1, title='測試', content='hhh', hasOpen='yes', category='moren', creatTime='null', source='null'}
    Notes{noteId=1, title='測試', content='hhh', hasOpen='yes', category='moren', creatTime='null', source='null'}
    [{"category":"moren","content":"hhh","hasOpen":"yes","noteId":1,"title":"測試"}]*/
    

四、接口文檔:

在項目開發中,web項目的前後端是分離開發的。應用程序的開發,需要由前後端工程師共同定義接口,編寫接口文檔,之後大家都根據這個接口文檔進行開發,到項目結束前都要一直維護。不同的項目有自己文檔的規定,但大體上不會偏差太多,我就介紹自己的理解吧!

接口名稱 場景(接口)說明 url 請求信息 響應信息 錯誤碼
顧名思義是給前端一個最直觀的影響,這個接口是做什麼的 描述這個接口的現狀,未開始、開發中、測試中。以及接口的用法,比如發送一個什麼樣的數據響應什麼樣的數據 前端請求地址。url地址裏不允許出現大寫字母,如果是兩個單詞拼接,用/分開 信息包含請求頭,請求參數,範例展示 信息包含響應頭,響應參數,範例展示 名稱
描述
原因
解決方案

請求頭(某些請求格式不同需要設置響應的請求頭)

名稱 默認值 描述
Content-Type application/json -
Host -

請求參數

名稱 類型 描述 必須 默認值
參數名 String、Number、Object、Array四大類 這個參數的作用是什麼,可以提供一個範例 是否必須有值 按自己需求

響應信息類似

五、管理平臺

傳統的管理通過聊天平臺,前後端的接口文檔是用word或其他形式來完成,這樣的接口文檔沒有實時性,做起來費時,看起來也不方便。

所以有了對接口文檔和接口測試一體化的強烈需求,自然接口管理平臺就誕生了!

我的小組目前使用NEI接口管理平臺,所以也主要介紹一下NEI接口管理平臺。

接口管理平臺(Netease Easy Interface),簡稱 NEI

NEI 雖然叫接口管理平臺,但其實不只是管理接口,它可以管理整個產品,也具備項目腳手架的功能。

初始界面NEI可以創建項目組,在項目組中可以創建各自負責部分的分項目
在這裏插入圖片描述
最重要的是可以在線生成接口文檔
在這裏插入圖片描述
在這裏插入圖片描述
還有打印功能哦!這個平臺還附帶測試接口,測試用例,以及測試報告等一系列功能,可以說很全面了!但缺點是這個平臺上線時間不長,可能相關的教程不多,用戶也不多!

其他的接口管理工具也推薦一下!大家可以根據需要使用

  1. 阿里rap
  2. NEI
  3. Postman
  4. Thoughts
  5. Swagger

參考文章——接口概念
參考文章——Tomcat結構
參考文章——json
參考文章——接口文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章