1、架構設計與分層
2、API結構設計_RESTFul API
什麼是REST?
REST,即Representational State Transfer的縮寫,中文是"表現層狀態轉化"。
它是一種互聯網應用程序的API設計理念:可以用URL定位資源,用HTTP動詞(GET,POST,DELETE,DETC)描述操作來解釋什麼是REST。
其實全稱是 Resource Representational State Transfer:通俗來講就是:資源在網絡中以某種表現形式進行狀態轉移。(再通俗來說,就是通過HTTP請求服務器上的某資源,使該資源copy了一份到服務請求方那去了(get動作)。個人這麼理解)
我們分解開來進行解釋:
Resource:資源,即數據它可以是一段文本、一張圖片、一首歌曲等;
Representational:某種表現形式,比如用JSON,XML,JPEG等;HTTP請求的頭信息中用Accept和Content-Type字段指定,這兩個字段纔是對"表現形式"的描述。
State Transfer:狀態變化。通過HTTP動詞實現。
注:互聯網通信協議HTTP協議,是一個無狀態協議。**這意味着,所有的狀態都保存在服務器端。**因此,如果客戶端想要操作服務器,必須通過某種手段,讓服務器端發生"狀態轉化"(State Transfer)。HTTP協議裏面,四個表示操作方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操作:GET用來獲取資源,POST用來新建資源(也可以用於更新資源),PUT用來更新資源,DELETE用來刪除資源。
什麼是REST ful API ?
基於REST構建的API就是Restful風格。
3、API結構設計_標準制定
爲了滿足實際需求,自己封裝API格式,代碼如下:
package com.houseSearch.base; /** * API格式封裝 * Created by 小劭. */ public class ApiResponse { private int code;//自定義請求狀態碼 private String message;//自定義請求相應信息描述 private Object data;//請求目標數據 private boolean more; public ApiResponse(int code, String message, Object data) { this.code = code; this.message = message; this.data = data; } public ApiResponse() { this.code = Status.SUCCESS.getCode(); this.message = Status.SUCCESS.getStandardMessage(); } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public boolean isMore() { return more; } public void setMore(boolean more) { this.more = more; } public static ApiResponse ofMessage(int code, String message) { return new ApiResponse(code, message, null); } public static ApiResponse ofSuccess(Object data) { return new ApiResponse(Status.SUCCESS.getCode(), Status.SUCCESS.getStandardMessage(), data); } public static ApiResponse ofStatus(Status status) { return new ApiResponse(status.getCode(), status.getStandardMessage(), null); } public enum Status { SUCCESS(200, "OK"), BAD_REQUEST(400, "Bad Request"), NOT_FOUND(404, "Not Found"), INTERNAL_SERVER_ERROR(500, "Unknown Internal Error"), NOT_VALID_PARAM(40005, "Not valid Params"), NOT_SUPPORTED_OPERATION(40006, "Operation not supported"), NOT_LOGIN(50000, "Not Login"); private int code; private String standardMessage; Status(int code, String standardMessage) { this.code = code; this.standardMessage = standardMessage; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getStandardMessage() { return standardMessage; } public void setStandardMessage(String standardMessage) { this.standardMessage = standardMessage; } } }
然後在HomeController文件添加如下代碼以及運行結果如下:
4、API結構設計_異常攔截器
項目運行過程中,有很多未知的情況,比如:頁面或者接口的異常、用戶訪問的頁面不存在、用戶的權限不足等等。所以這裏設計一個異常攔截器,主要體現着兩個方面:
1、頁面異常攔截器
2、API異常攔截器
如下,未知的請求,會顯示springboot默認的 “Whitelabel Error Page”頁面信息。所以要在application.properties配置文件中加上
server.error.whitelabel.enabled=false表示關閉springBoot默認的錯誤頁面顯示。
實現步驟:編寫AppErrorController web錯誤 全局配置類,然後添加相應403、404、500等錯誤頁面,這裏不展示頁面相關代碼。
package com.houseSearch.base; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.web.ErrorAttributes; import org.springframework.boot.autoconfigure.web.ErrorController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; /** * web錯誤 全局配置 * Created by 小劭. */ @Controller public class AppErrorController implements ErrorController { private static final String ERROR_PATH = "/error"; private ErrorAttributes errorAttributes; @Override public String getErrorPath() { return ERROR_PATH; } @Autowired public AppErrorController(ErrorAttributes errorAttributes) { this.errorAttributes = errorAttributes; } /** * Web頁面錯誤處理 */ @RequestMapping(value = ERROR_PATH, produces = "text/html") public String errorPageHandler(HttpServletRequest request, HttpServletResponse response) { int status = response.getStatus(); switch (status) { case 403: return "403"; case 404: return "404"; case 500: return "500"; } return "index"; } /** * 除Web頁面外的錯誤處理,比如Json/XML等 */ @RequestMapping(value = ERROR_PATH) @ResponseBody public ApiResponse errorApiHandler(HttpServletRequest request) { RequestAttributes requestAttributes = new ServletRequestAttributes(request); Map<String, Object> attr = this.errorAttributes.getErrorAttributes(requestAttributes, false); int status = getStatus(request); return ApiResponse.ofMessage(status, String.valueOf(attr.getOrDefault("message", "error"))); } private int getStatus(HttpServletRequest request) { Integer status = (Integer) request.getAttribute("javax.servlet.error.status_code"); if (status != null) { return status; } return 500; } }