ResponseBodyAdvice的作用詳解

ResponseBodyAdvice是Spring MVC框架中的一個介面,用於全局處理Controller返回的響應數據。它提供了一個自定義處理響應體的機制,可以在響應體寫出之前或者之後,對響應體進行額外的處理或者修改,是一種典型的AOP編程方式。

一、請求響應報文詳解

在深入理解ResponseBodyAdvice之前,我們先來了解一下http請求和響應的報文格式。

http請求報文由請求行、請求頭和請求正文3部分組成,其中,請求正文是可選的。請求行包括:請求方法(GET, POST, PUT, DELETE等)、請求的URI(統一資源標識符)以及HTTP版本號,請求頭由多個鍵值對組成,如:Content-Type、Accept等等;

http響應報文也由3部分組成:狀態行、響應頭和響應正文。狀態行由協議版本號、狀態碼以及狀態描述3部分組成,響應頭也是由多個鍵值對組成,如:Content-Type、Accept等等;響應正文則是請求資源對應的數據。

        HTTP/1.1 200 OK
        Content-Type: text/plain;charset=UTF-8
        Content-Length: 30
         
        Hello Spring Mvc ResponseBody
        BodyAdvice Works!
 

二、ResponseBodyAdvice的使用方式

ResponseBodyAdvice的作用在於,將Controller返回的響應數據進行統一處理。對於返回類型為String、Object類型的數據,我們可以對其進行包裝或者加密;對於返回類型為void、HttpServletResponse類型的響應數據,我們可以在響應報文頭部加上一些自定義參數實現統一的格式處理。

在Spring MVC框架中,我們通過實現ResponseBodyAdvice介面的方法,對返回的響應進行統一處理,代碼示例如下:

public class MyResponseBodyAdvice 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 body;
    }
}

三、ResponseBodyAdvice在實際應用中的使用場景

ResponseBodyAdvice在實際應用中有很多使用場景,例如:

1.包裝返回對象

我們可以利用ResponseBodyAdvice對Controller的返回對象進行加工處理,讓其符合我們的業務實際需求,例如封裝一個統一響應體,方便客戶端對響應數據進行統一處理。

public class ResponseBodyWrapperAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        //包裝返回對象,返回統一格式的響應數據
        return new ResponseEntity(ResultUtils.success(body), HttpStatus.OK);
    }
}

2.加密返回內容

在一些需要保護敏感信息的場景下,我們需要對返回的數據進行加密處理,用於保護數據的安全性。

public class ResponseBodyEncryptAdvice implements ResponseBodyAdvice{
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter> converterType) {
        //對返回類型為String類型的數據進行加密處理
        return returnType.getParameterType().equals(String.class);
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        try {
            //加密返回內容
            body = RsaUtils.encryptByPublicKey(body.toString(), "RSA公鑰", "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return body;
    }
}

3.設置響應頭參數

我們可以利用ResponseBodyAdvice在響應頭增加額外的參數,例如:響應時間、版本信息等等。這些參數在實際開發過程中,對於客戶端調用、緩存等方面有很大的作用。

public class ResponseHeaderAdvice implements ResponseBodyAdvice{
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter> converterType) {
        //對所有返回類型的數據都執行操作
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        HttpHeaders headers = response.getHeaders();
        headers.add("Access-Control-Allow-Origin", "*");
        headers.add("Access-Control-Allow-Headers", "Authorization,Origin, X-Requested-With, Content-Type, Accept");
        headers.add("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE,PUT");
        headers.add("Access-Control-Max-Age","3600");
        headers.add("Access-Control-Allow-Credentials", "true");
        headers.add("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
        headers.add("Content-Type", "application/json;charset=UTF-8");
        headers.add("Server-Version", "v1.0");
        headers.add("Response-Time", new Date().toString());
        return body;
    }
}

四、ResponseBodyAdvice的實現流程

1.當請求處理完成後,DispatcherServlet會調用RequestResponseBodyMethodProcessor的handleReturnValue方法處理Controller返回的響應數據;

2.默認情況下,RequestResponseBodyMethodProcessor會使用AbstractMessageConverterMethodProcessor中的writeWithMessageConverters方法,將Controller返回的數據轉為響應報文;

3.在響應體寫出之前或之後,Spring MVC會判斷請求中是否有關聯了ResponseBodyAdvice實現類,如果有,則會調用其beforeBodyWrite方法,對響應體進行最後加工處理;

4.最終將加工處理後的響應體寫入到響應報文中。

五、Conclusion

ResponseBodyAdvice提供了一個全局處理響應數據的機制,可以讓我們對Controller返回的響應數據進行統一處理或加工,對於提高代碼重用性和系統擴展性都有非常積極的作用。在實際開發應用中,我們可以根據實際情況選擇不同的場景,靈活應用ResponseBodyAdvice。

原創文章,作者:FUVZ,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/131389.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
FUVZ的頭像FUVZ
上一篇 2024-10-03 23:45
下一篇 2024-10-03 23:45

相關推薦

  • Python中set函數的作用

    Python中set函數是一個有用的數據類型,可以被用於許多編程場景中。在這篇文章中,我們將學習Python中set函數的多個方面,從而深入了解這個函數在Python中的用途。 一…

    編程 2025-04-29
  • Python中init方法的作用及使用方法

    Python中的init方法是一個類的構造函數,在創建對象時被調用。在本篇文章中,我們將從多個方面詳細討論init方法的作用,使用方法以及注意點。 一、定義init方法 在Pyth…

    編程 2025-04-29
  • @scope("prototype")的作用及應用

    本文將從以下幾個方面進行詳細闡述@scope(“prototype”)在編程開發中的作用和應用。 一、代碼復用 在開發中,往往會有很多地方需要復用同一個類的…

    編程 2025-04-28
  • Python中import sys的作用

    Python是一種非常強大的編程語言,它的標準庫提供了許多有用的模塊和函數。sys模塊是Python標準庫中的一個重要模塊,用於與Python解釋器和操作系統進行交互。它允許開發者…

    編程 2025-04-28
  • Python配置環境變數的作用

    Python配置環境變數是為了讓計算機能夠更方便地找到Python語言及其相關工具的位置,使其可以在任意目錄下使用Python命令。當您安裝Python後,您需要進行環境變數設置,…

    編程 2025-04-28
  • Python的意義和作用

    Python是一種高級語言,它的簡潔易讀和豐富的庫使得它成為了廣泛使用的編程語言之一。Python可以完成諸如數據科學、機器學習、網路編程等各種任務,因此被很多開發人員和研究人員視…

    編程 2025-04-27
  • Python定義空列表及其作用

    Python是一種廣泛使用的強類型解釋型編程語言。在Python中,我們可以使用列表來存儲一系列不同類型的元素。列表是Python內置的一種高效數據結構,可以在其中存儲任意數量的元…

    編程 2025-04-27
  • 理解Python __init__的作用

    對__init__的作用進行詳細的闡述,並給出對應代碼示例。 一、對象實例化與構造函數 在面向對象編程中,我們經常需要創建對象,而對象的創建和初始化需要先定義一個類,然後通過在類中…

    編程 2025-04-27
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁碟中。在執行sync之前,所有的文件系統更新將不會立即寫入磁碟,而是先緩存在內存…

    編程 2025-04-25
  • 神經網路代碼詳解

    神經網路作為一種人工智慧技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網路的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網路模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25

發表回復

登錄後才能評論