springboot项目处理响应结果方案ResponseBodyAdvice

场景:

在项目中我们有统一的返回结果定义。我们自己定义内容

{
    "code": 200,
    "message": "success",
    "data": {
        "id": 507361327216709,
        "pid": 507361220950085,
        "title": "流程",
        "parentTitle": null,
        "sort": 2,
        "createBy": 278787367246725,
        "createTime": "2024-01-23 17:58:34",
        "updateBy": 386208547649353,
        "updateTime": "2024-01-26 17:33:31"
    },
    "timestamp": 1708396596121
}

这个在我们自己项目都是这种返回结构,但是在对接其他公司的系统的时候,有的公司规定的返回结果结构跟我们的不一样。他们的是这样的

{
    "result": {
        "access_token": "d527138ca51",
        "expire_at": "20240220224436"
    },
    "success": true,
    "message": null,
    "desc": null
}

这和我们项目中的是不一样的。字段名和含义都不一样。需要在不改变我们项目结构的同时满足这种返回结果。我们在controller层可以自己定义一个返回结果对象,但是项目中抛出异常,就会走我们定义的第一种响应结构

解决方案:

        1. 使用aop,或者过滤器WEBfilter. 这种处理方式,还不能解决这个问题。controller一旦抛出异常,就不会走这2个类了。会走到异常处理类。返回的就是我们项目定义的响应结构了。

        2.  使用ResponseBodyAdvice解决

        这种方案是,在响应之后,可以处理响应内容,具体代码如下:

package com.openapi.filter;

import com.common.response.YGGCBaseResponseVO;
import com.common.response.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.web.util.WebUtils.ERROR_REQUEST_URI_ATTRIBUTE;

/**
 * 返回值处理
 *
 * @author
 * @since 2024/1/26 15:04
 */
//@Order(Ordered.HIGHEST_PRECEDENCE)
@Slf4j
@RestControllerAdvice
public class ResponseBodyHandler implements ResponseBodyAdvice<Object> {

    private static final String PREFIX_YGGC = "/yggc";

    @SuppressWarnings("all")
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @SuppressWarnings("all")
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        // 获取HttpServletRequest
        HttpServletRequest sr = ((ServletServerHttpRequest) request).getServletRequest();
        // 获取异常路径
        String errorUri = (String) sr.getAttribute(ERROR_REQUEST_URI_ATTRIBUTE);
        // 获取请求uri
        String uri = sr.getRequestURI();

        // 把R转成YGGCBaseResponseVO
        if (StringUtils.isNotBlank(uri) && body instanceof R
                && (uri.startsWith(PREFIX_YGGC) || (StringUtils.isNotBlank(errorUri) && errorUri.startsWith(PREFIX_YGGC)))) {
            

            if (body instanceof YGGCBaseResponseVO) {
                return body;
            }

            R r = (R) body;
            return new YGGCBaseResponseVO<>(r.getData(), 200 == r.getCode(), r.getMessage());
        }

        return body;
    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值