SpringBoot 接口返回响应体修改

在开发中,有时候会遇到一些统一修改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;
    }
}

 

posted @ 2023-06-16 15:48  山阴路的秋天  阅读(849)  评论(0)    收藏  举报