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/n/131389.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
FUVZFUVZ
上一篇 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

发表回复

登录后才能评论