SpringBoot?@RestControllerAdvice注解對(duì)返回值統(tǒng)一封裝的處理方法
一. 需求場(chǎng)景
如下圖所示,后臺(tái)向前臺(tái)響應(yīng)數(shù)據(jù)的時(shí)候,所有的數(shù)據(jù)都需要放入自定義的封裝Entity才返回給前臺(tái)。現(xiàn)在想要每個(gè)Controller中的方法將原數(shù)據(jù)直接返回,然后通過(guò)某種方法統(tǒng)一封裝處理。
二. 前期準(zhǔn)備
?獲取狀態(tài)碼的接口
public interface IStatusCode { int getCode(); String getMsg(); }
?響應(yīng)狀態(tài)碼的枚舉類
import lombok.AllArgsConstructor; import lombok.Getter; @Getter @AllArgsConstructor public enum ResultCodeEnum implements IStatusCode { SUCCESS(1000, "請(qǐng)求成功"), FAILED(1001, "請(qǐng)求失敗"), VALIDATE_ERROR(1002, "參數(shù)校驗(yàn)失敗"), RESPONSE_PACK_ERROR(1003, "response返回包裝失敗"); private int code; private String msg; }
?業(yè)務(wù)狀態(tài)碼的枚舉類
import lombok.AllArgsConstructor; import lombok.Getter; @Getter @AllArgsConstructor public enum BusinessCodeEnum implements IStatusCode { APP_ERROR(2000, "業(yè)務(wù)異常"), PRICE_ERROR(2001, "價(jià)格異常"); private int code; private String msg; }
?自定義業(yè)務(wù)異常類
import lombok.Getter; @Getter public class BusinessException extends RuntimeException { private int code; private String msg; // 手動(dòng)設(shè)置異常 public BusinessException(IStatusCode codeEnum, String message) { // message用于用戶設(shè)置拋出錯(cuò)誤詳情 super(message); // 狀態(tài)碼 this.code = codeEnum.getCode(); // 狀態(tài)碼配套的msg this.msg = codeEnum.getMsg(); } // 默認(rèn)異常使用APP_ERROR狀態(tài)碼 public BusinessException(String message) { super(message); this.code = BusinessCodeEnum.APP_ERROR.getCode(); this.msg = BusinessCodeEnum.APP_ERROR.getMsg(); } }
?自定義注解,標(biāo)記該注解的方法不進(jìn)行響應(yīng)增強(qiáng)
讓我們的方法更加靈活,可以選擇增強(qiáng)封裝或者不增強(qiáng)。
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對(duì)響應(yīng)進(jìn)行增強(qiáng)
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; // 對(duì)指定包下面的Controller進(jìn)行增強(qiáng) @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( // ?判斷相應(yīng)的類型是否為ResultVo類型 methodParameter.getParameterType().isAssignableFrom(ResultVo.class), // ?判斷響應(yīng)的方法上是否包含 NotControllerResponseAdvice 注解 methodParameter.hasMethodAnnotation(NotControllerResponseAdvice.class) ); // 若包含其中一項(xiàng),則不進(jìn)行封裝 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串進(jìn)行返回 return objectMapper.writeValueAsString(ResultVo.build(body)); } catch (JsonProcessingException e) { // 拋出自定義的業(yè)務(wù)異常 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被包裝之后返回給前臺(tái)
4.2 標(biāo)記NotControllerResponseAdvice注解后返回List
?List
未被包裝,直接返回?cái)?shù)據(jù)給前臺(tái)
4.3 直接返回字符串
4.4 直接返回ResultVo類型數(shù)據(jù)
?返回的就是ResultVo類型,無(wú)需包裝,直接返回?cái)?shù)據(jù)給前臺(tái)
參考資料:
正規(guī)軍springboot如何處理:參數(shù)校驗(yàn)、統(tǒng)一異常、統(tǒng)一響應(yīng)
到此這篇關(guān)于SpringBoot @RestControllerAdvice注解對(duì)返回值統(tǒng)一封裝的文章就介紹到這了,更多相關(guān)SpringBoot返回值統(tǒng)一封裝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot使用@RestController處理GET和POST請(qǐng)求的代碼詳解
- SpringBoot中@RestControllerAdvice @ExceptionHandler異常統(tǒng)一處理類失效原因分析
- SpringBoot中@RestControllerAdvice注解的使用
- SpringBoot的@RestControllerAdvice作用詳解
- SpringBoot中@RestControllerAdvice注解實(shí)現(xiàn)全局異常處理類
- SpringBoot常用注解@RestControllerAdvice詳解
- SpringBoot中的@RestControllerAdvice注解詳解
- springboot @Controller和@RestController的區(qū)別及應(yīng)用詳解
- SpringBoot http請(qǐng)求注解@RestController原理解析
- springboot中@RestController注解實(shí)現(xiàn)
相關(guān)文章
HttpServletRequest對(duì)象常用功能_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了HttpServletRequest對(duì)象常用功能的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07Java.SE數(shù)組的一些常見(jiàn)練習(xí)題
數(shù)組可以看成是相同類型元素的一個(gè)集合,在內(nèi)存中是一段連續(xù)的空間,這篇文章主要給大家介紹了關(guān)于Java.SE數(shù)組的一些常見(jiàn)練習(xí)題,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02springboot整合xxl-job實(shí)現(xiàn)分布式定時(shí)任務(wù)的過(guò)程
XXL-JOB是一個(gè)分布式任務(wù)調(diào)度平臺(tái),其核心設(shè)計(jì)目標(biāo)是開發(fā)迅速、學(xué)習(xí)簡(jiǎn)單、輕量級(jí)、易擴(kuò)展,這篇文章主要介紹了springboot整合xxl-job分布式定時(shí)任務(wù),需要的朋友可以參考下2022-08-0818個(gè)Java8日期處理的實(shí)踐(太有用了)
這篇文章主要介紹了18個(gè)Java8日期處理的實(shí)踐(太有用了),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01Java使用ByteArrayOutputStream 和 ByteArrayInputStream 避免重復(fù)讀取配置文
這篇文章主要介紹了Java使用ByteArrayOutputStream 和 ByteArrayInputStream 避免重復(fù)讀取配置文件的方法,需要的朋友可以參考下2015-12-12使用SpringBoot代碼詳細(xì)解釋<List>的用法
List是Java集合框架中的一種數(shù)據(jù)結(jié)構(gòu),用于存儲(chǔ)一組有序的元素,使用List可以方便地向其中添加、刪除或者修改元素,也可以通過(guò)下標(biāo)或者迭代器遍歷其中的元素,這篇文章主要介紹了用SpringBoot代碼詳細(xì)解釋<List>的用法,需要的朋友可以參考下2023-09-09