SpringBoot?@RestControllerAdvice注解對返回值統(tǒng)一封裝的處理方法
一. 需求場景
如下圖所示,后臺向前臺響應數(shù)據(jù)的時候,所有的數(shù)據(jù)都需要放入自定義的封裝Entity才返回給前臺?,F(xiàn)在想要每個Controller中的方法將原數(shù)據(jù)直接返回,然后通過某種方法統(tǒng)一封裝處理。
二. 前期準備
?獲取狀態(tài)碼的接口
public interface IStatusCode { int getCode(); String getMsg(); }
?響應狀態(tài)碼的枚舉類
import lombok.AllArgsConstructor; import lombok.Getter; @Getter @AllArgsConstructor public enum ResultCodeEnum implements IStatusCode { SUCCESS(1000, "請求成功"), FAILED(1001, "請求失敗"), VALIDATE_ERROR(1002, "參數(shù)校驗失敗"), RESPONSE_PACK_ERROR(1003, "response返回包裝失敗"); private int code; private String msg; }
?業(yè)務狀態(tài)碼的枚舉類
import lombok.AllArgsConstructor; import lombok.Getter; @Getter @AllArgsConstructor public enum BusinessCodeEnum implements IStatusCode { APP_ERROR(2000, "業(yè)務異常"), PRICE_ERROR(2001, "價格異常"); private int code; private String msg; }
?自定義業(yè)務異常類
import lombok.Getter; @Getter public class BusinessException extends RuntimeException { private int code; private String msg; // 手動設(shè)置異常 public BusinessException(IStatusCode codeEnum, String message) { // message用于用戶設(shè)置拋出錯誤詳情 super(message); // 狀態(tài)碼 this.code = codeEnum.getCode(); // 狀態(tài)碼配套的msg this.msg = codeEnum.getMsg(); } // 默認異常使用APP_ERROR狀態(tài)碼 public BusinessException(String message) { super(message); this.code = BusinessCodeEnum.APP_ERROR.getCode(); this.msg = BusinessCodeEnum.APP_ERROR.getMsg(); } }
?自定義注解,標記該注解的方法不進行響應增強
讓我們的方法更加靈活,可以選擇增強封裝或者不增強。
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface NotControllerResponseAdvice { }
三. 使用@RestControllerAdvice對響應進行增強
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import java.util.Arrays; import java.util.List; // 對指定包下面的Controller進行增強 @RestControllerAdvice(basePackages = {"com.example.jmw.controller"}) public class ControllerResponseAdvice implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) { List<Boolean> judgeResultList = Arrays.asList( // ?判斷相應的類型是否為ResultVo類型 methodParameter.getParameterType().isAssignableFrom(ResultVo.class), // ?判斷響應的方法上是否包含 NotControllerResponseAdvice 注解 methodParameter.hasMethodAnnotation(NotControllerResponseAdvice.class) ); // 若包含其中一項,則不進行封裝 return !judgeResultList.contains(true); } @Override public Object beforeBodyWrite(Object body , MethodParameter returnType , MediaType selectedContentType , Class<? extends HttpMessageConverter<?>> selectedConverterType , ServerHttpRequest request , ServerHttpResponse response ) { // String類型不能直接包裝 if (returnType.getGenericParameterType().equals(String.class)) { ObjectMapper objectMapper = new ObjectMapper(); try { // 將數(shù)據(jù)包裝在ResultVo里后轉(zhuǎn)換為json串進行返回 return objectMapper.writeValueAsString(ResultVo.build(body)); } catch (JsonProcessingException e) { // 拋出自定義的業(yè)務異常 throw new BusinessException(ResultCodeEnum.RESPONSE_PACK_ERROR, e.getMessage()); } } // 否則直接包裝成ResultVo返回 return ResultVo.build(body); } }
四. 效果
4.1 直接返回List
@Controller @RequestMapping("/test12") public class Test12Controller { @PostMapping("/test") @ResponseBody public List<String> test() { return Arrays.asList("1", "2", "3"); } }
?List被包裝之后返回給前臺
4.2 標記NotControllerResponseAdvice注解后返回List
?List
未被包裝,直接返回數(shù)據(jù)給前臺
4.3 直接返回字符串
4.4 直接返回ResultVo類型數(shù)據(jù)
?返回的就是ResultVo類型,無需包裝,直接返回數(shù)據(jù)給前臺
參考資料:
正規(guī)軍springboot如何處理:參數(shù)校驗、統(tǒng)一異常、統(tǒng)一響應
到此這篇關(guān)于SpringBoot @RestControllerAdvice注解對返回值統(tǒng)一封裝的文章就介紹到這了,更多相關(guān)SpringBoot返回值統(tǒng)一封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot中@RestControllerAdvice注解實現(xiàn)全局異常處理類
- springboot的統(tǒng)一異常處理,使用@RestControllerAdvice詳解
- SpringBoot項目中@RestControllerAdvice全局異常失效問題的解決
- SpringBoot中@RestControllerAdvice @ExceptionHandler異常統(tǒng)一處理類失效原因分析
- SpringBoot中@RestControllerAdvice注解的使用
- SpringBoot的@RestControllerAdvice作用詳解
- SpringBoot常用注解@RestControllerAdvice詳解
- SpringBoot中的@RestControllerAdvice注解詳解
- SpringBoot中@RestControllerAdvice 全局異常處理的實現(xiàn)
相關(guān)文章
Mybatis SqlSessionFactory與SqlSession詳細講解
SqlSessionFactory是MyBatis的核心類之一,其最重要的功能就是提供創(chuàng)建MyBatis的核心接口SqlSession,所以我們需要先創(chuàng)建SqlSessionFactory,為此我們需要提供配置文件和相關(guān)的參數(shù)2022-11-11詳解Mybatis攔截器安全加解密MySQL數(shù)據(jù)實戰(zhàn)
本文主要介紹了Mybatis攔截器安全加解密MySQL數(shù)據(jù)實戰(zhàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01MybatisPlus創(chuàng)建時間不想用默認值的問題
MybatisPlus通過FieldFill注解和MpMetaObjectHandler類支持自動填充字段功能,特別地,可以設(shè)置字段在插入或更新時自動填充創(chuàng)建時間和更新時間,但在特定場景下,如導入數(shù)據(jù)時,可能需要自定義創(chuàng)建時間2024-09-09SpringBoot實現(xiàn)數(shù)據(jù)源動態(tài)切換的最佳姿勢
這篇文章主要為大家詳細介紹一下SpringBoot實現(xiàn)數(shù)據(jù)源動態(tài)切換的最佳姿勢,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2025-03-03