最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot統(tǒng)一返回體的踩坑記錄

 更新時間:2021年05月10日 14:13:05   作者:碼農(nóng)小胖哥  
這篇文章主要給大家介紹了關于Spring Boot統(tǒng)一返回體踩坑的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

在Spring Boot項目中我們可以通過RestControllerAdvice配合實現(xiàn)ResponseBodyAdvice<T>接口來保證Spring MVC接口具有統(tǒng)一的返回格式,以保證前端同學能夠封裝統(tǒng)一的數(shù)據(jù)接收工具。但是很多網(wǎng)上的文章并沒有對實際開發(fā)中的細節(jié)作出更多的講解。今天胖哥就來分享一下我的采坑經(jīng)歷,也算作一個總結。

控制作用范圍

我記得在前面關于Swagger3的文章中提過,如果我們不指定范圍將導致Swagger無法識別接口的元信息。因此如果你使用了Swagger必須指定其范圍,這里你可以通過指定掃描包來指定其作用域:

@RestControllerAdvice("cn.felord.controller")

如果你的Spring MVC控制器有統(tǒng)一的父類控制器的話,

@RestController
@RequestMapping("/foo")
public class FooController extends BaseController {
 //todo 省略
}    

也可以這樣:

@RestControllerAdvice(assignableTypes = BaseController.class)

白名單

有些接口可能根據(jù)業(yè)務需要或者協(xié)議需要不能使用統(tǒng)一返回體,例如支付的通知應答。這就需要一個類似白名單的機制來繞過統(tǒng)一返回體控制器通知類。我們可以借助于ResponseBodyAdvice<T>的下列方法實現(xiàn):

boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);

這個方法如果返回false就表示不執(zhí)行統(tǒng)一返回體的封裝邏輯。這里我推薦注解實現(xiàn)。定義一個標記注解,可以定義在類上或者方法上:

@Documented
@Inherited
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreRestBody {
}

然后上面的supports方法這樣實現(xiàn):

@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
    return !returnType.hasMethodAnnotation(IgnoreRestBody.class);
}

如果某個Controller下所有的方法都繞過,就把這個注解標記在控制器類上;如果只想忽略某個方法上就把它標記在該方法上即可。

返回獨立字符串的問題

有些接口我們會返回一個字符串:

@GetMapping("/get")
public String getStr(){
    //返回了一個字符串
    return "felord.cn";
}

我們希望這個字符串被統(tǒng)一返回體處理,類似這樣:

{
    code: 200,
    data: "felord.cn",
    msg: "返回成字符串",
}

但是你會發(fā)現(xiàn)并沒有達到期望的效果,會拋出類型轉(zhuǎn)換異常。這是因為當我們的Spring MVC接口返回數(shù)據(jù)時,會根據(jù)Content-Type來選擇一個HttpMessageConverter來處理,而字符串在不聲明Content-Type的情況下優(yōu)先使用StringHttpMessageConverter ,就導致了轉(zhuǎn)換異常,需要設定成MappingJackson2HttpMessageConverter用Jackson來處理,Spring MVC的對應配置如下:

@Configuration(proxyBeanMethods = false)
public class SpringMvcConfiguration implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 解決 String 統(tǒng)一封裝RestBody的問題
        converters.add(0, new MappingJackson2HttpMessageConverter());
    }
}

嗯,這樣就起效了!你以為這樣就完了?你會發(fā)現(xiàn)你的JSON序列化不按照你設置的策略執(zhí)行了。因為你new了一個而不是采用系統(tǒng)初始化的那個。解決方法為,將Spring IoC中的ObjectMapper注入到MappingJackson2HttpMessageConverter中去?;蛘吣闶褂肈ebug調(diào)試出系統(tǒng)默認的MappingJackson2HttpMessageConverter的位置,比如我的索引為7,就可以這樣配置:

@Configuration(proxyBeanMethods = false)
public class SpringMvcConfiguration implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 解決 String 統(tǒng)一封裝RestBody的問題
        HttpMessageConverter<?> httpMessageConverter = converters.get(7);
        if (!(httpMessageConverter instanceof MappingJackson2HttpMessageConverter)) {
            // 確保正確,如果有改動就重新debug
            throw new RuntimeException("MappingJackson2HttpMessageConverter is not here");
        }
        converters.add(0, httpMessageConverter);
    }
}

Data的類型問題

曾經(jīng)一個安卓開發(fā)同學說,你這統(tǒng)一結構中的data如果是數(shù)組:

{
    code: 200,
    data: ['a','b'],
    msg: "返回成字符串",
}

后續(xù)如果data添加其它與數(shù)組沒有關系的屬性就不兼容了,你應該保證這個data是個Map。是的,這也是問題,實際中發(fā)現(xiàn)不僅僅是數(shù)組,如果是int、long等原始類型或者String類型都面臨這種情況,需要加一個額外的判斷body是不是可能改變data類型的類型:

private boolean checkPrimitive(Object body) {
    Class<?> clazz = body.getClass();
    return clazz.isPrimitive()
            || clazz.isArray()
            || Collection.class.isAssignableFrom(clazz)
            || body instanceof Number
            || body instanceof Boolean
            || body instanceof Character
            || body instanceof String;
}

然后我們在ResponseBodyAdvice<T>實現(xiàn)中增加一個判斷:

      // 增強擴展性
        if (checkPrimitive(body)) {
            return RestBody.okData(Collections.singletonMap("result", body));
        }

就解決問題了。

總結

今天對Spring Boot中統(tǒng)一返回體的一些細節(jié)問題進行了分享,希望能夠幫助你解決一些實際開發(fā)中遇到的同樣問題。

到此這篇關于Spring Boot統(tǒng)一返回體踩坑記錄的文章就介紹到這了,更多相關Spring Boot統(tǒng)一返回體內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解spring cloud分布式整合zipkin的鏈路跟蹤

    詳解spring cloud分布式整合zipkin的鏈路跟蹤

    這篇文章主要介紹了詳解spring cloud分布式整合zipkin的鏈路跟蹤,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • SpringBoot動態(tài)定時功能實現(xiàn)方案詳解

    SpringBoot動態(tài)定時功能實現(xiàn)方案詳解

    在SpringBoot項目中簡單使用定時任務,不過由于要借助cron表達式且都提前定義好放在配置文件里,不能在項目運行中動態(tài)修改任務執(zhí)行時間,實在不太靈活?,F(xiàn)在我們就來實現(xiàn)可以動態(tài)修改cron表達式的定時任務,感興趣的可以了解一下
    2022-11-11
  • spring boot jar部署控制臺日志亂碼的解決

    spring boot jar部署控制臺日志亂碼的解決

    這篇文章主要介紹了spring boot jar部署控制臺日志亂碼的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Mybatis返回Map數(shù)據(jù)方式示例

    Mybatis返回Map數(shù)據(jù)方式示例

    這篇文章主要為大家介紹了Mybatis返回Map數(shù)據(jù)方式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Java實現(xiàn)簡單控制臺版ATM系統(tǒng)

    Java實現(xiàn)簡單控制臺版ATM系統(tǒng)

    這篇文章主要為大家詳細介紹了Java實現(xiàn)簡單控制臺版ATM系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • SpringBoot利用ThreadPoolTaskExecutor批量插入百萬級數(shù)據(jù)的具體實現(xiàn)

    SpringBoot利用ThreadPoolTaskExecutor批量插入百萬級數(shù)據(jù)的具體實現(xiàn)

    ThreadPoolTaskExecutor是Spring提供的任務執(zhí)行器實現(xiàn)之一,允許開發(fā)者配置線程池參數(shù)以適應不同的應用場景,創(chuàng)建 ThreadPoolTaskExecutor 實例并設置核心和最大線程數(shù)等屬性可以優(yōu)化性能,本文介紹了SpringBoot利用ThreadPoolTaskExecutor批量插入百萬級數(shù)據(jù)的具體實現(xiàn)
    2024-12-12
  • IDEA如何切換JDK版本

    IDEA如何切換JDK版本

    本文主要介紹了IDEA如何切換JDK版本,JDK版本之間的關系是一個向后兼容的關系,所以我們需要切換JDK的版本號,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • SpringBoot?如何使用sharding?jdbc進行分庫分表

    SpringBoot?如何使用sharding?jdbc進行分庫分表

    這篇文章主要介紹了SpringBoot?如何使用sharding?jdbc進行分庫分表,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • spring中Mapstruct屬性映射的實現(xiàn)

    spring中Mapstruct屬性映射的實現(xiàn)

    本文主要介紹了spring中Mapstruct屬性映射的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-12-12
  • Java設計模式中的裝飾器模式簡析

    Java設計模式中的裝飾器模式簡析

    這篇文章主要介紹了Java設計模式中的裝飾器模式簡析,裝飾模式能夠?qū)崿F(xiàn)動態(tài)的為對象添加功能,是從一個對象外部來給對象添加功能,通常給對象添加功能,要么直接修改對象添加相應的功能,要么派生對應的子類來擴展,抑或是使用對象組合的方式,需要的朋友可以參考下
    2023-12-12

最新評論

泰顺县| 西盟| 清苑县| 荔波县| 莆田市| 额济纳旗| 永年县| 南宫市| 靖州| 息烽县| 江永县| 涟源市| 徐州市| 文成县| 板桥市| 长武县| 海盐县| 岗巴县| 平果县| 唐河县| 灌云县| 西吉县| 普定县| 汤阴县| 虹口区| 兴海县| 额济纳旗| 万源市| 浮梁县| 安多县| 定陶县| 珲春市| 扎囊县| 达尔| 肇东市| 加查县| 五家渠市| 偏关县| 武冈市| 崇礼县| 呼和浩特市|