日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

baseresponse响应类_SpringBoot统一响应体解决方案

發布時間:2023/12/14 javascript 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 baseresponse响应类_SpringBoot统一响应体解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

最近在優化自己之前基于Spring AOP的統一響應體的實現方案。

什么是統一響應體呢?在目前的前后端分離架構下,后端主要是一個RESTful API的數據接口。

但是HTTP的狀態碼數量有限,而隨著業務的增長,HTTP狀態碼無法很好地表示業務中遇到的異常情況。

那么可以通過修改響應返回的JSON數據,讓其帶上一些固有的字段,例如以下這樣的

{

"code": 10000,

"msg": "success",

"data": {

"id": 2,

"name": "test"

}

}

其中關鍵屬性的用途如下:

code為返回結果的狀態碼

msg為返回結果的消息

data為返回的業務數據

這3個屬性為固有屬性,每次響應結果都會有帶有它們。

需求

希望實現一個能夠代替基于AOP的實現方案,需要滿足以下幾點:

原有的基于AOP的實現方案需要Controller的返回類型為Object,需要新方案不限制返回類型

原有的基于AOP的實現方案需要通過切面表達式+注解控制切點的Controller(注解的包名修改會導致切面表達式的修改,即需要修改兩處地方),需要新方案能夠基于注解,而不需要修改切面表達式

方案思路

基于上述的需求,選擇使用Spring的Controller增強機制,其中關鍵的類為以下3個:

@ControllerAdvice:類注解,用于指定Controller增強處理器類。

ResponseBodyAdvice:接口,實現后beforeBodyWrite()方法后可以對響應的body進行修改,需要結合@ControllerAdvice使用。

@ExceptionHandler:方法注解,用于指定異常處理方法,需要結合@ControllerAdvice和@ResponseBody使用。

示例關鍵代碼

本示例使用的Spring Boot版本為2.1.6.RELEASE,同時需要開發工具安裝lombok插件

引入依賴

org.springframework.boot

spring-boot-starter-web

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-test

test

統一響應體

Controller增強后統一響應體對應的對象

import lombok.AllArgsConstructor;

import lombok.Data;

import java.io.Serializable;

/**

* 統一的公共響應體

* @author NULL

* @date 2019-07-16

*/

@Data

@AllArgsConstructor

public class ResponseResult implements Serializable {

/**

* 返回狀態碼

*/

private Integer code;

/**

* 返回信息

*/

private String msg;

/**

* 數據

*/

private Object data;

}

統一響應注解

統一響應注解是一個標記是否開啟統一響應增強的注解

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* 統一響應注解

* 添加注解后,統一響應體才能生效

* @author NULL

* @date 2019-07-16

*/

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.METHOD, ElementType.TYPE})

public @interface BaseResponse {

}

狀態碼枚舉

統一響應體中返回的狀態碼code和狀態信息msg對應的枚舉類

/**

* 返回狀態碼

*

* @author NULL

* @date 2019-07-16

*/

public enum ResponseCode {

/**

* 成功返回的狀態碼

*/

SUCCESS(10000, "success"),

/**

* 資源不存在的狀態碼

*/

RESOURCES_NOT_EXIST(10001, "資源不存在"),

/**

* 所有無法識別的異常默認的返回狀態碼

*/

SERVICE_ERROR(50000, "服務器異常");

/**

* 狀態碼

*/

private int code;

/**

* 返回信息

*/

private String msg;

ResponseCode(int code, String msg) {

this.code = code;

this.msg = msg;

}

public int getCode() {

return code;

}

public String getMsg() {

return msg;

}

}

業務異常類

業務異常類是用于識別業務相關的異常,需要注意這個異常類強制需要以ResponseCode作為構造方法入參,這樣可以通過捕獲異常獲得返回的狀態碼信息

import com.rjh.web.response.ResponseCode;

import lombok.Data;

import lombok.EqualsAndHashCode;

/**

* 業務異常類,繼承運行時異常,確保事務正常回滾

*

* @author NULL

* @since 2019-07-16

*/

@Data

@EqualsAndHashCode(callSuper = false)

public class BaseException extends RuntimeException{

private ResponseCode code;

public BaseException(ResponseCode code) {

this.code = code;

}

public BaseException(Throwable cause, ResponseCode code) {

super(cause);

this.code = code;

}

}

異常處理類

用于處理Controller運行時未捕獲的異常的處理類。

import com.rjh.web.exception.BaseException;

import lombok.extern.slf4j.Slf4j;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.bind.annotation.ResponseBody;

/**

* 異常處理器

*

* @author NULL

* @since 2019-07-16

*/

@ControllerAdvice(annotations = BaseResponse.class)

@ResponseBody

@Slf4j

public class ExceptionHandlerAdvice {

/**

* 處理未捕獲的Exception

* @param e 異常

* @return 統一響應體

*/

@ExceptionHandler(Exception.class)

public ResponseResult handleException(Exception e){

log.error(e.getMessage(),e);

return new ResponseResult(ResponseCode.SERVICE_ERROR.getCode(),ResponseCode.SERVICE_ERROR.getMsg(),null);

}

/**

* 處理未捕獲的RuntimeException

* @param e 運行時異常

* @return 統一響應體

*/

@ExceptionHandler(RuntimeException.class)

public ResponseResult handleRuntimeException(RuntimeException e){

log.error(e.getMessage(),e);

return new ResponseResult(ResponseCode.SERVICE_ERROR.getCode(),ResponseCode.SERVICE_ERROR.getMsg(),null);

}

/**

* 處理業務異常BaseException

* @param e 業務異常

* @return 統一響應體

*/

@ExceptionHandler(BaseException.class)

public ResponseResult handleBaseException(BaseException e){

log.error(e.getMessage(),e);

ResponseCode code=e.getCode();

return new ResponseResult(code.getCode(),code.getMsg(),null);

}

}

響應增強類

Conrtoller增強的統一響應體處理類,需要注意異常處理類已經進行了增強,所以需要判斷一下返回的對象是否為統一響應體對象。

import lombok.extern.slf4j.Slf4j;

import org.springframework.core.MethodParameter;

import org.springframework.http.MediaType;

import org.springframework.http.server.ServerHttpRequest;

import org.springframework.http.server.ServerHttpResponse;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**

* 統一響應體處理器

* @author NULL

* @date 2019-07-16

*/

@ControllerAdvice(annotations = BaseResponse.class)

@Slf4j

public class ResponseResultHandlerAdvice implements ResponseBodyAdvice {

@Override

public boolean supports(MethodParameter returnType, Class converterType) {

log.info("returnType:"+returnType);

log.info("converterType:"+converterType);

return true;

}

@Override

public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {

if(MediaType.APPLICATION_JSON.equals(selectedContentType) || MediaType.APPLICATION_JSON_UTF8.equals(selectedContentType)){ // 判斷響應的Content-Type為JSON格式的body

if(body instanceof ResponseResult){ // 如果響應返回的對象為統一響應體,則直接返回body

return body;

}else{

// 只有正常返回的結果才會進入這個判斷流程,所以返回正常成功的狀態碼

ResponseResult responseResult =new ResponseResult(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMsg(),body);

return responseResult;

}

}

// 非JSON格式body直接返回即可

return body;

}

}

使用示例

首先準備一個User對象

import lombok.Data;

import lombok.EqualsAndHashCode;

import java.io.Serializable;

/**

* 用戶類

* @author NULL

* @date 2019-07-16

*/

@Data

@EqualsAndHashCode

public class User implements Serializable {

private Integer id;

private String name;

}

然后是準備一個簡單的UserController即可

import com.rjh.web.entity.User;

import com.rjh.web.exception.BaseException;

import com.rjh.web.response.BaseResponse;

import com.rjh.web.response.ResponseCode;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**

* 測試用的Controller

*

* @author NULL

* @date 2019-07-16

*/

@BaseResponse

@RestController

@RequestMapping("users")

public class UserController {

@GetMapping("/{userId}")

public User getUserById(@PathVariable Integer userId){

if(userId.equals(0)){

throw new BaseException(ResponseCode.RESOURCES_NOT_EXIST);

}

if(userId.equals(1)){

throw new RuntimeException();

}

User user=new User();

user.setId(userId);

user.setName("test");

return user;

}

}

運行結果

在瀏覽器直接訪問http://127.0.0.1:8080/users/0,則返回結果如下(結果經過格式化處理):

{

"code": 10001,

"msg": "資源不存在",

"data": null

}

在瀏覽器直接訪問http://127.0.0.1:8080/users/1,則返回結果如下(結果經過格式化處理):

{

"code": 50000,

"msg": "服務器異常",

"data": null

}

在瀏覽器直接訪問http://127.0.0.1:8080/users/2,則返回結果如下(結果經過格式化處理):

{

"code": 10000,

"msg": "success",

"data": {

"id": 2,

"name": "test"

}

}

由運行結果可以得知統一響應增強其實已經生效了,而且能夠很好的處理異常。

示例代碼地址

下面是這個示例的代碼地址,如果覺得不錯或者幫助到你,希望大家給個Star:

https://github.com/spring-bas...

參考資料

總結

以上是生活随笔為你收集整理的baseresponse响应类_SpringBoot统一响应体解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。