Spring Boot 統(tǒng)一數(shù)據(jù)返回格式的解決方案
實現(xiàn)統(tǒng)一數(shù)據(jù)格式
統(tǒng)?的數(shù)據(jù)返回格式使? @ControllerAdvice 和 ResponseBodyAdvice 的?式實現(xiàn);
@ControllerAdvice : 表?控制器通知類.
比如:添加類 ResponseAdvice , 實現(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要進?處理, 其他的不進?處理.
beforeBodyWrite?法:對response?法進?具體操作處理.
測試
寫一些不同的返回結(jié)果,看看哪些會出現(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)部錯誤.
控制臺查看日志:
3.返回結(jié)果為Boolean,可以正常響應(yīng).
4.返回結(jié)果為BookInfo對象,可以正常響應(yīng).
5.返回結(jié)果為Result,發(fā)現(xiàn)又進行了一次封裝.
問題:1.返回結(jié)果為String,不能正常進行處理了;2.返回結(jié)果為Result,又多進行了一次封裝.
原因分析
這時候就會非常納悶了,為什么就處理String的時候會出錯呢?就不得不去看源碼分析了.
SpringMVC (也就是在初始化時) 默認會注冊?些?帶的 HttpMessageConverter (轉(zhuǎn)換器) (從先后順序排列分別為 ByteArrayHttpMessageConverter , StringHttpMessageConverter , SourceHttpMessageConverter , SourceHttpMessageConverter , AllEncompassingFormHttpMessageConverter )
這些轉(zhuǎn)換器是有先后順序的,是用ArrayList存儲的.會根據(jù)我們的返回結(jié)果挨個判斷使用哪個轉(zhuǎn)換器??!!
此時,就會發(fā)現(xiàn)問題就出現(xiàn)在 StringHttpMessageConverter.
處理的內(nèi)容主要是在AbstractMessageConverterMethodProcessor 中 會有一個writeWithMessageConverters()方法.
通過getAdvice()拿到了beforBodyWrite 就會對body進行處理,處理完之后并沒有結(jié)束(body變成了Result類型),此時,也并沒有出錯。會繼續(xù)執(zhí)行((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage).
由于 StringHttpMessageConverter 重寫了addDefaultHeaders?法, 所以會執(zhí)??類的?法
然??類 StringHttpMessageConverter 的addDefaultHeaders?法定義接收參數(shù)為String, 此
時t為Result類型, 所以出現(xiàn)類型不匹配" Result cannot be cast to java.lang.String "的異常.
解決方案
1.當(dāng)返回結(jié)果為Result時,就直接返回body.
2.當(dāng)返回結(jié)果為String時,采用SpringBoot內(nèi)置提供的Jackson來實現(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類型時,就直接返回body if (body instanceof Result) { return body; } //返回結(jié)果為String類型, 使?SpringBoot內(nèi)置提供的Jackson來實現(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot統(tǒng)一數(shù)據(jù)返回格式的實現(xiàn)示例
- springboot統(tǒng)一接口返回數(shù)據(jù)的實現(xiàn)
- SpringBoot統(tǒng)一返回處理出現(xiàn)cannot?be?cast?to?java.lang.String異常解決
- SpringBoot全局Controller返回值格式統(tǒng)一
- springboot配置Jackson返回統(tǒng)一默認值的實現(xiàn)示例
- 詳解SpringBoot如何統(tǒng)一后端返回格式
- Spring?Boot如何實現(xiàn)統(tǒng)一數(shù)據(jù)返回
相關(guān)文章
UrlDecoder和UrlEncoder使用詳解_動力節(jié)點Java學(xué)院整理
這篇文章主要為大家詳細介紹了UrlDecoder和UrlEncoder使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07QTabWidget標(biāo)簽實現(xiàn)雙擊關(guān)閉的方法(推薦)
這篇文章主要介紹了QTabWidget標(biāo)簽實現(xiàn)雙擊關(guān)閉的方法(推薦)的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-06-06淺談Spring Cloud Netflix-Ribbon灰度方案之Zuul網(wǎng)關(guān)灰度
這篇文章主要介紹了淺談Spring Cloud Netflix-Ribbon灰度方案之Zuul網(wǎng)關(guān)灰度,想了解Ribbon灰度的同學(xué)可以參考下2021-04-04