Spring Boot 統(tǒng)一數(shù)據(jù)返回格式的解決方案
實(shí)現(xiàn)統(tǒng)一數(shù)據(jù)格式
統(tǒng)?的數(shù)據(jù)返回格式使? @ControllerAdvice 和 ResponseBodyAdvice 的?式實(shí)現(xiàn);
@ControllerAdvice : 表?控制器通知類.
比如:添加類 ResponseAdvice , 實(shí)現(xiàn) ResponseBodyAdvice 接?, 并在類上添加
@ControllerAdvice 注解.
import com.example.demo.model.Result; 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; @ControllerAdvice public class ResponseAdvice implements ResponseBodyAdvice { @Override public boolean supports(MethodParameter returnType, Class converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { return Result.success(body); //返回 Result 類型的數(shù)據(jù) } }
supports?法: 判斷是否要執(zhí)?beforeBodyWrite?法. true為執(zhí)?, false不執(zhí)?. 通過該?法可以 選擇哪些類或哪些?法的response要進(jìn)?處理, 其他的不進(jìn)?處理.
beforeBodyWrite?法:對(duì)response?法進(jìn)?具體操作處理.
測(cè)試
寫一些不同的返回結(jié)果,看看哪些會(huì)出現(xiàn)問題!
import com.example.demo.model.BookInfo; import com.example.demo.model.Result; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/test") public class TestController { @RequestMapping("/t1") public Integer t1() { return 12334; } @RequestMapping("/t2") public String t2() { return "hello"; } @RequestMapping("/t3") public Boolean t3() { return true; } @RequestMapping("/t4") public BookInfo t4() { return new BookInfo(); } @RequestMapping("/t5") public Result t5() { return Result.success("success"); } }
1.返回結(jié)果為Integer,可以正確響應(yīng).
2.返回結(jié)果為String,結(jié)果顯示內(nèi)部錯(cuò)誤.
控制臺(tái)查看日志:
3.返回結(jié)果為Boolean,可以正常響應(yīng).
4.返回結(jié)果為BookInfo對(duì)象,可以正常響應(yīng).
5.返回結(jié)果為Result,發(fā)現(xiàn)又進(jìn)行了一次封裝.
問題:1.返回結(jié)果為String,不能正常進(jìn)行處理了;2.返回結(jié)果為Result,又多進(jìn)行了一次封裝.
原因分析
這時(shí)候就會(huì)非常納悶了,為什么就處理String的時(shí)候會(huì)出錯(cuò)呢?就不得不去看源碼分析了.
SpringMVC (也就是在初始化時(shí)) 默認(rèn)會(huì)注冊(cè)?些?帶的 HttpMessageConverter (轉(zhuǎn)換器) (從先后順序排列分別為 ByteArrayHttpMessageConverter , StringHttpMessageConverter , SourceHttpMessageConverter , SourceHttpMessageConverter , AllEncompassingFormHttpMessageConverter )
這些轉(zhuǎn)換器是有先后順序的,是用ArrayList存儲(chǔ)的.會(huì)根據(jù)我們的返回結(jié)果挨個(gè)判斷使用哪個(gè)轉(zhuǎn)換器??!!
此時(shí),就會(huì)發(fā)現(xiàn)問題就出現(xiàn)在 StringHttpMessageConverter.
處理的內(nèi)容主要是在AbstractMessageConverterMethodProcessor 中 會(huì)有一個(gè)writeWithMessageConverters()方法.
通過getAdvice()拿到了beforBodyWrite 就會(huì)對(duì)body進(jìn)行處理,處理完之后并沒有結(jié)束(body變成了Result類型),此時(shí),也并沒有出錯(cuò)。會(huì)繼續(xù)執(zhí)行((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage).
由于 StringHttpMessageConverter 重寫了addDefaultHeaders?法, 所以會(huì)執(zhí)??類的?法
然??類 StringHttpMessageConverter 的addDefaultHeaders?法定義接收參數(shù)為String, 此
時(shí)t為Result類型, 所以出現(xiàn)類型不匹配" Result cannot be cast to java.lang.String "的異常.
解決方案
1.當(dāng)返回結(jié)果為Result時(shí),就直接返回body.
2.當(dāng)返回結(jié)果為String時(shí),采用SpringBoot內(nèi)置提供的Jackson來實(shí)現(xiàn)信息的序列化
@ControllerAdvice public class ResponseAdvice implements ResponseBodyAdvice { @Autowired private ObjectMapper objectMapper; @Override public boolean supports(MethodParameter returnType, Class converterType) { return true; } @SneakyThrows @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { //body 是返回的結(jié)果 //當(dāng)返回結(jié)果為Result類型時(shí),就直接返回body if (body instanceof Result) { return body; } //返回結(jié)果為String類型, 使?SpringBoot內(nèi)置提供的Jackson來實(shí)現(xiàn)信息的序列化 if (body instanceof String) { return objectMapper.writeValueAsString(Result.success(body)); } return Result.success(body); //返回 Result 類型的數(shù)據(jù) } }
到此這篇關(guān)于Spring Boot 統(tǒng)一數(shù)據(jù)返回格式 分析 和 處理的文章就介紹到這了,更多相關(guān)Spring Boot 統(tǒng)一數(shù)據(jù)返回格式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot統(tǒng)一數(shù)據(jù)返回格式的實(shí)現(xiàn)示例
- springboot統(tǒng)一接口返回?cái)?shù)據(jù)的實(shí)現(xiàn)
- SpringBoot統(tǒng)一返回處理出現(xiàn)cannot?be?cast?to?java.lang.String異常解決
- SpringBoot全局Controller返回值格式統(tǒng)一
- springboot配置Jackson返回統(tǒng)一默認(rèn)值的實(shí)現(xiàn)示例
- 詳解SpringBoot如何統(tǒng)一后端返回格式
- Spring?Boot如何實(shí)現(xiàn)統(tǒng)一數(shù)據(jù)返回
相關(guān)文章
UrlDecoder和UrlEncoder使用詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了UrlDecoder和UrlEncoder使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07QTabWidget標(biāo)簽實(shí)現(xiàn)雙擊關(guān)閉的方法(推薦)
這篇文章主要介紹了QTabWidget標(biāo)簽實(shí)現(xiàn)雙擊關(guān)閉的方法(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06Mybatis 自動(dòng)映射(使用需謹(jǐn)慎)
這篇文章主要介紹了Mybatis 自動(dòng)映射(使用需謹(jǐn)慎),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10淺談Spring Cloud Netflix-Ribbon灰度方案之Zuul網(wǎng)關(guān)灰度
這篇文章主要介紹了淺談Spring Cloud Netflix-Ribbon灰度方案之Zuul網(wǎng)關(guān)灰度,想了解Ribbon灰度的同學(xué)可以參考下2021-04-04