欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot統(tǒng)一返回處理出現(xiàn)cannot?be?cast?to?java.lang.String異常解決

 更新時間:2023年09月01日 10:35:49   作者:伏加特遇上西柚  
這篇文章主要給大家介紹了關(guān)于SpringBoot統(tǒng)一返回處理出現(xiàn)cannot?be?cast?to?java.lang.String異常解決的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下

一 問題出現(xiàn)背景:

在使用 @RestControllerAdvice 和實現(xiàn) ResponseBodyAdvice controller 層統(tǒng)一返回封裝時。當(dāng)返回字符串時會報 “cannot be cast to java.lang.String” 異常,返回其他類型就無任何問題。

二 解決方案

如果返回的是字符串直接手動封裝返回對象轉(zhuǎn)成json字符串返回即可。

完整代碼

@RestControllerAdvice
public class ResponseResult implements ResponseBodyAdvice<Object> {
    /**
     * 支持注解@ResponseNotIntercept,使某些方法無需使用Result封裝
     *
     * @param returnType 返回類型
     * @param converterType  選擇的轉(zhuǎn)換器類型
     * @return true 時會執(zhí)行beforeBodyWrite方法,false時直接返回給前端
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        if (returnType.getDeclaringClass().isAnnotationPresent(ResponseNotIntercept.class)) {
            //若在類中加了@ResponseNotIntercept 則該類中的方法不用做統(tǒng)一的攔截
            return false;
        }
        if (returnType.getMethod().isAnnotationPresent(ResponseNotIntercept.class)) {
            //若方法上加了@ResponseNotIntercept 則該方法不用做統(tǒng)一的攔截
            return false;
        }
        return true;
    }
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof Result) {
            // 提供一定的靈活度,如果body已經(jīng)被包裝了,就不進(jìn)行包裝
            return body;
        }
        if (body instanceof String) {
            //解決返回值為字符串時,不能正常包裝
            return JSON.toJSONString(Result.success(body));
        }
        return Result.success(body);
    }
}

三 異常原因分析

原因:

SpringMVC 默認(rèn)會注冊一些自帶的 HttpMessageConvertor (從先后順序排列分別為ByteArrayHttpMessageConverter、StringHttpMessageConverter、ResourceHttpMessageConverter,SourceHttpMessageConverter、AllEncompassingFormHttpMessageConverter) ,后端服務(wù)使用Restful API的形式,前后端得規(guī)范一般是json格式, SpringMVC 自帶 MappingJackson2HttpMessageConverter ,在依賴中引入 jackson 包后,容器會把 MappingJackson2HttpMessageConverter 自動注冊到 messageConverters 鏈的末尾

當(dāng)返回的數(shù)據(jù)是非字符串時使用的 MappingJackson2HttpMessageConverter 寫入返回對象。當(dāng)返回的數(shù)據(jù)是字符串時,此處得方法是要去循環(huán)遍歷 HttpMessageConverter 集,因為 StringHttpMessageConverter 會先被遍歷到,這時會認(rèn)為 StringHttpMessageConverter 可以使用,在返回 Result 是使用 ((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage) ;此方法是父類方法 body 參數(shù)類型為 Object ,實際調(diào)用的為 StringHttpMessageConverter 中的 addDefaultHeaders(HttpHeaders headers, String s, @Nullable MediaType type) 方法,使用 String 類型的 s 來接收 Result 類型的 body ,類型不匹配則出現(xiàn) Result cannot be cast to java.lang.String 異常。

源碼詳細(xì)分析:

正常返回:

步驟一:遍歷 messageConverters 去判斷到 MappingJackson2HttpMessageConverter GenericHttpMessageConverter 類型的 converter ;

步驟二:進(jìn)一步判斷到 MappingJackson2HttpMessageConverter 可以寫入對象類型的數(shù)據(jù)。

步驟三:調(diào)用 beforeBodyWriter 方法將原有的 TestVO 對象數(shù)據(jù)封裝到 Result 對象中。

步驟四:調(diào)用 MappingJackson2HttpMessageConverter 中的 wirte 方法(代碼中用接口類型接收的)

步驟五:通過 MappingJackson2HttpMessageConverter 繼承關(guān)系發(fā)現(xiàn)其write方法在父類 AbstractHttpMessageConverter 中,在 write 方法中調(diào)用本類中addDefaultHeaders 方法向輸出消息添加默認(rèn)報頭。(此處應(yīng)注意)

步驟六:將封裝好的Result對象返回給前端

返回為字符串異常

步驟一:遍歷 messageConverters 去判斷到 StringHttpMessageConverter 是null;

步驟二:進(jìn)一步判斷到 StringHttpMessageConverter 可以寫入String類型的數(shù)據(jù)。

步驟三:調(diào)用 beforeBodyWriter 方法將原有的 String 類型數(shù)據(jù)封裝到 Result 對象中。

步驟四:調(diào)用 StringHttpMessageConverter 中的 wirte 方法(代碼中用接口類型接收的)

步驟五

調(diào)用父類 AbstractHttpMessageConverter 中的 write 方法,由于 StringHttpMessageConverter 重寫了 addDefaultHeaders 方法,故 write 中調(diào)用子類中的 addDefaultHeaders 。由于父類中參數(shù)t為對象類型,對應(yīng)子類中接收的s為String類型故會出現(xiàn)類型轉(zhuǎn)換異常 Result cannot be cast to java.lang.String (此處應(yīng)注意)

總結(jié) 

到此這篇關(guān)于SpringBoot統(tǒng)一返回處理出現(xiàn)cannot be cast to java.lang.String異常解決的文章就介紹到這了,更多相關(guān)cannot be cast to java.lang.String異常內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Jmeter安裝及配置教程詳解

    Jmeter安裝及配置教程詳解

    很多朋友私信小編Jmeter安裝及配置教程能出一期教程嗎?正巧趕上疫情,不是太忙,下面小編把Jmeter安裝及配置教程分享到腳本之家平臺,感興趣的朋友跟隨小編一起看看吧
    2021-12-12
  • Java實例精煉掌握語法

    Java實例精煉掌握語法

    本章節(jié)我們將為大家介紹?Java?實現(xiàn)幾大基礎(chǔ)問題,通過實例學(xué)習(xí)我們可以更快的掌握?Java?的應(yīng)用,感興趣的朋友來看看吧
    2022-04-04
  • jsp+servlet實現(xiàn)簡單登錄頁面功能(附demo)

    jsp+servlet實現(xiàn)簡單登錄頁面功能(附demo)

    本文主要介紹了jsp+servlet實現(xiàn)簡單登錄頁面功能登錄成功跳轉(zhuǎn)新頁面,登錄失敗在原登錄界面提示登錄失敗信息,對初學(xué)者有一定的幫助,感興趣的可以了解一下
    2021-07-07
  • Java8?Stream?流常用方法合集

    Java8?Stream?流常用方法合集

    這篇文章主要介紹了?Java8?Stream?流常用方法合集,Stream?是?Java8?中處理集合的關(guān)鍵抽象概念,它可以指定你希望對集合進(jìn)行的操作,可以執(zhí)行非常復(fù)雜的查找、過濾和映射數(shù)據(jù)等操作,下文相關(guān)資料,需要的朋友可以參考一下
    2022-04-04
  • Java用棧實現(xiàn)綜合計算器

    Java用棧實現(xiàn)綜合計算器

    棧(stack)又名堆棧,它是一種運算受限的線性表,下面看一下如何在Java中,利用數(shù)組實現(xiàn)模擬一個棧,感興趣的朋友跟隨小編一起看看吧
    2022-06-06
  • Spring?MVC中@Controller和@RequestMapping注解使用

    Spring?MVC中@Controller和@RequestMapping注解使用

    這篇文章主要介紹了Spring?MVC中@Controller和@RequestMapping注解使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java  Vector和ArrayList的分析及比較

    java Vector和ArrayList的分析及比較

    這篇文章主要介紹了java Vector和ArrayList的分析及比較的相關(guān)資料,Vector是多線程安全的,而ArrayList不是,本文主要做對比對這兩個方法,需要的朋友可以參考下
    2016-11-11
  • IDEA整合SSM框架實現(xiàn)網(wǎng)頁上顯示數(shù)據(jù)

    IDEA整合SSM框架實現(xiàn)網(wǎng)頁上顯示數(shù)據(jù)

    最近做了個小項目,該項目包在intellij idea中實現(xiàn)了ssm框架的整合以及實現(xiàn)訪問,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • Java枚舉(enum) 詳解7種常見的用法

    Java枚舉(enum) 詳解7種常見的用法

    這篇文章主要介紹了Java枚舉(enum) 詳解7種常見的用法,具有一定的參考價值,有需要的可以了解一下。
    2016-11-11
  • Java數(shù)組實例練習(xí)題整理

    Java數(shù)組實例練習(xí)題整理

    在本篇文章中小編給各位分享的是關(guān)于Java數(shù)組實例練習(xí)題以及相關(guān)代碼整理,有需要的朋友們跟著學(xué)習(xí)下。
    2019-07-07

最新評論