網站首頁 編程語言 正文
背景
本篇內容相對比較簡單,不涉及具體的物聯網技術,是作為后端工程師的基本操作,算是對基礎框架的封裝工作,我們使用 SpringBoot
的 RestControllerAdvice
與 ExceptionHandler
等注解實現對客戶端請求響應的統一封裝以及異常信息攔截封裝。
為了保證我們前端在對接服務接口時采用統一的規范,業界主流的做法便是將所有請求的結果進行封裝,當然在遇到異常信息時也進行一層封裝,這樣可以使所有接口的響應結構是一致的,響應體的內容包括狀態碼與數據,當出現錯誤時還包含錯誤信息,一般地,響應體如下:
- 正常響應
{
"code": 200,
"msg": "success",
"data": "hello everyone."
}
- 異常響應
{
"code": 500,
"msg": "/ by zero"
}
后續內容將在上一篇文章中 IDEA
項目的基礎上,添加一個 common
包(具體的文件位置可以從下圖中左側項目結構獲得)。
統一響應封裝
通過 RestControllerAdvice
注解,實現對請求的攔截,統一封裝結果為 Result
。
@RestControllerAdvice(basePackages = "com.heartsuit.common.controller")
public class ResultAdvice implements ResponseBodyAdvice<Object> {
@Autowired
private ObjectMapper objectMapper;
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@SneakyThrows
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if (o instanceof String) {
return objectMapper.writeValueAsString(Result.success(o));
}
if (o instanceof Result) {
return o;
}
return Result.success(o);
}
}
- Result.java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {
/** 結果狀態 ,正常響應200,其他狀態碼都為失敗*/
private int code;
private String msg;
private T data;
// Static methods
/**
* 成功時候的調用
*/
public static <T> Result<T> success(T data) {
return new Result<T>(data, CodeMsg.SUCCESS);
}
public static <T> Result<T> success() {
return new Result<T>(CodeMsg.SUCCESS);
}
/**
* 失敗時候的調用
*/
public static <T> Result<T> error(Integer code, String msg) {
return new Result<T>(code, msg);
}
public static <T> Result<T> error(CodeMsg codeMsg) {
return new Result<T>(codeMsg);
}
public static <T> Result<T> error(String msg) {
CodeMsg codeMsg = new CodeMsg(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg);
return new Result<T>(codeMsg);
}
// Constructor
private Result(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
private Result(T data, CodeMsg codeMsg) {
this.data = data;
if (codeMsg != null) {
this.code = codeMsg.getCode();
this.msg = codeMsg.getMsg();
}
}
private Result(CodeMsg codeMsg) {
if (codeMsg != null) {
this.code = codeMsg.getCode();
this.msg = codeMsg.getMsg();
}
}
}
- CodeMsg.java
@Getter
public class CodeMsg {
private int code;
private String msg;
// 通用的錯誤碼
public static final CodeMsg SUCCESS =new CodeMsg(HttpStatus.OK.value(), "success");
public static final CodeMsg BAD_REQUEST = new CodeMsg(HttpStatus.BAD_REQUEST.value(), "請求無效");
public static final CodeMsg SERVER_ERROR = new CodeMsg(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服務端異常");
public static final CodeMsg NO_HANDLER_FOUND = new CodeMsg(HttpStatus.NOT_FOUND.value(), "未找到對應資源");
public static final CodeMsg UNAUTHORIZED = new CodeMsg(HttpStatus.UNAUTHORIZED.value(), "未認證或登錄狀態過期");
public static final CodeMsg FORBIDDEN = new CodeMsg(HttpStatus.FORBIDDEN.value(), "未授權");
// 自定義錯誤碼
public static final CodeMsg PARAMETER_ERROR = new CodeMsg(4000, "參數不正確!");
/*用戶相關:驗證碼*/
public static final CodeMsg CAPTCHA_EXPIRED = new CodeMsg(4001, "驗證碼不存在或已過期");
public static final CodeMsg CAPTCHA_INVALID = new CodeMsg(4002, "驗證碼錯誤");
/*用戶相關:認證授權*/
public static final CodeMsg BAD_CREDENTIAL = new CodeMsg(4003, "用戶名或密碼錯誤");
public static final CodeMsg ACCOUNT_NOT_FOUND = new CodeMsg(4004, "賬號不存在");
public static final CodeMsg ACCOUNT_NOT_ACTIVATED = new CodeMsg(4005, "賬號未激活");
// 限流
public static final CodeMsg RATE_LIMIT = new CodeMsg(4006,"達到閾值啦!");
// 熔斷
public static final CodeMsg DEGRADE = new CodeMsg(4007,"熔斷啦!");
public static CodeMsg error(String msg){
return new CodeMsg(HttpStatus.BAD_REQUEST.value(),msg);
}
public CodeMsg(int code, String msg) {
this.code = code;
this.msg = msg;
}
}
全局異常攔截
默認攔截所有異常(也可自定義異常進行封裝),同樣通過 RestControllerAdvice
注解,實現對異常響應的統一封裝。
- RestExceptionHandler.java
@Slf4j
@RestControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Result<String> exception(Exception e) {
log.error("Global exception: {}", null == e.getMessage() ? e.toString() : e.getMessage(), e);
return Result.error(CodeMsg.SERVER_ERROR.getCode(), null == e.getMessage() ? e.toString() : e.getMessage());
}
}
用于測試的Controller
@RestController
@RequestMapping("demo")
public class HelloController {
@GetMapping("hello")
public String hello() {
return "hello everyone.";
}
@GetMapping("error")
public Result error() {
int value = 8 / 0;
return Result.success(value);
}
}
小總結
至此,我們在基于 SpringBoot
的后端服務中完成了響應封裝、異常攔截。下一篇我們的主角 TDengine
將閃亮登場: TDengine
集成 SpringBoot
, MyBatisPlus
實現 ORM
與 基礎的 CRUD
功能。
If you have any questions or any bugs are found, please feel free to contact me.
Your comments and suggestions are welcome!
原文鏈接:https://blog.csdn.net/u013810234/article/details/124787685
- 上一篇:解決使用maven打jar包缺失依賴包問題
- 下一篇:IDEA使用Tomcat
相關推薦
- 2022-05-20 Spring Boot 整合流程引擎 Flowable,so easy
- 2022-12-09 React文件分段上傳實現方法詳解_React
- 2022-07-11 Jenkins修改端口號, jenkins容器修改默認端口號
- 2023-03-30 一鍵移除ButterKnife并替換為ViewBinding的舊項目拯救_Android
- 2022-08-20 Python簡明講解filter函數的用法_python
- 2024-02-26 openJDK awt 字體支持
- 2022-10-05 python?matplotlib自定義colorbar顏色條及內置色條詳解_python
- 2022-05-12 centos7.6升級glibcln: relocation error: /lib64/libc
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支