首页 > 其他分享 >SpringBoot 接口返回响应体修改

SpringBoot 接口返回响应体修改

时间:2023-06-16 15:56:28浏览次数:41  
标签:body Wrapper SpringBoot wrapper annotation 响应 接口 public ret

在开发中,有时候会遇到一些统一修改http接口响应体内容的场景,比如返回体Wrapper统一增加一些数据包装处理。

解决思路 :通过自定义注解 + 切面  或者 自定义注解 + ResponseBodyAdvice 处理接口返回体

1、创建自定义注解 

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface WrapperNested {
}

 

2、创建切面处理标注了自定义注解的类或者接口

注意: 切点pointcut  @within 作用在类上 @annotation作用在方法上

@Component
@Aspect
@Slf4j
public class WrapperNestedAspect {
    // @within 作用在类上 @annotation作用在方法上
    @Pointcut("@within(com.**.WrapperNested)")
    public void pointCut() {
    }

    @AfterReturning(returning = "ret", pointcut = "pointCut()")
    public void doAfterReturning(Object ret) {
        log.debug("ret:{}", JSON.toJSONString(ret));
        Wrapper wrapper = (Wrapper) ret;
        WrapperRes outerWrapper = JSON.parseObject(JSON.toJSONString(ret), WrapperRes.class);
        if (ObjectUtils.isNotEmpty(wrapper) && ObjectUtils.isNotEmpty(outerWrapper)) {
            WrapperRes innerWrapper = new WrapperRes();
            BeanUtils.copyProperties(outerWrapper, innerWrapper);
            outerWrapper.setResult(innerWrapper);
            BeanUtils.copyProperties(outerWrapper, wrapper);
        }
        log.debug("ret1:{}", JSON.toJSONString(ret));
    }
}

 

3、或者通过ResponseBodyAdvice  来实现,ResponseBodyAdvice  中定义了两个接口方法:

supports方法用于判断beforeBodyWrite方法的执行与否,返回值为布尔类型,返回true即执行beforeBodyWrite方法;可以在实现类中编写实现逻辑,来根据MethodParameter以及HttpMessageConverter类型判断是否需要改写http响应体。

beforeBodyWrite方法提供了用于修改http响应体的能力,该方法中提供了Controller方法的返回body,MethodParameter,MediaType, Class ,ServerHttpRequest 、ServerHttpResponse 对象,我们拿到这些对象,根据需要来编写修改逻辑。

@Slf4j
@ControllerAdvice
public class WrapperNestedResponseBodyAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        Class targetClass = returnType.getMethod().getDeclaringClass();
        return ObjectUtils.isNotEmpty(targetClass.getAnnotation(WrapperNested.class)) || returnType.hasMethodAnnotation(WrapperNested.class);
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        log.debug("beforeBodyWrite data={}", JSON.toJSONString(body));
        if (ObjectUtils.isNotEmpty(body) && body instanceof Wrapper) {
            Wrapper wrapper = (Wrapper) body;return WrapMapper.wrap(wrapper.getCode(), wrapper.getMessage(), WrapMapper.wrap(wrapper.getCode(), wrapper.getMessage(), wrapper.getResult()));
        }
        return body;
    }
}

 

标签:body,Wrapper,SpringBoot,wrapper,annotation,响应,接口,public,ret
From: https://www.cnblogs.com/wlong-blog/p/17485751.html

相关文章

  • springboot-Quartz定时任务并持久化
    新建项目,添加依赖新建一个springboot项目,勾选下springboot,以及quartz依赖 或者我们可以直接在pom.xml文件中直接添加依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId>......
  • springboot防重复提交
    springboot防重复提交1、场景网页卡顿的时候,用户点击会造成重复操作如果前端不做防重复操作。会导致重复提交,重复下单等意外操作。而且对于系统资源来说也是一种浪费常规的解决方法是让前端把点击后的按钮设置为不可点击,这样基本上能就能解决了。99.999999%能解决。前端这么弄......
  • springboot整合cache缓存
    第一步:在pom.xml文件中导入对应坐标<!--cache--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency>第二步:启用缓存在启动......
  • springboot 解决跨域问题
    什么是跨域指从一个域名网页去请求另一域名页面的资源,比如baidu.com请求google.com中的资源,但是这种情况是不允许的,因为由浏览器的同源策略,使浏览器对js增加安全限制,即就是阻止不同域下的js进行交互。判断域是否相同是通过判断协议、域名、端口中有任何一个不同,则为不同的域......
  • springboot整合redis
    1、添加依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>2、配置redis通过spring.redis.xxx来配置redis的信息spring.redis.hos......
  • springboot整合持久层
    springboot整合持久层1、整合mybatis这里以多数据源为例第一步创建springboot时,选上mybatis依赖在添加数据库驱动依赖:<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23<......
  • springboot整合mongodb
    springboot整合mongodb整合mongodb其实与整合redis相差不大1、依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency&......
  • springboot 中使用 redis 处理接口的幂等性
    什么是接口幂等性?数学中:在一次元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同;在二次元运算为幂等时,自己重复运算的结果等于它自己的元素。计算机学中:幂等指多次操作产生的影响只会跟一次执行的结果相同,通俗的说:某个行为重复的执行,最终获取的结果是相同的,不会因......
  • SpringBoot快速整合RabbitMq小案例
    对于一个直接创建的springBoot项目工程来说,可以按照以下步骤使用rabbitmq添加依赖:添加rabbitMQ的依赖。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>配置连接:在配置文件中配置虚拟主......
  • springboot项目启动
    报错:Couldnotresolveplaceholder'config.info'invalue"${config.info}"项目的bootstrap.yml配置文件的file-extension:yaml#这里我们获取的yaml格式的配置需要跟nacos配置列表的DataId结尾保持一致 ......