OpenFeign如何从通用的响应体中解构出业务对象

在实际Restful项目中,通常都会定义一个通用的响应体对象,该对象内包括了本次调用的结果码,异常信息,业务数据对象等。对于一般的Controller接口的响应,我们都会自定义一个RestControllerAdvice,并实现ResponseBodyAdvice接口,来将Controller接口返回的业务对象统一封装成CommonResponse对象,并返回给客户端。所以为了简化Feign接口的响应的处理,我们可以自定义OpenFeign的Decoder来统一地从CommonResp中解构出业务对象。

实现思路:
1、 自定义Decoder:
1.1、 自定义Decoder,并且持有一个原先Decoder的引用;
1.2、 在decode时,首先先把decode处理委派给原来的Decoder(装饰器模式),并获取到decode后的结果对象;
1.3、 判断1.2步得出的结果对象是否是CommonResp,如果是,则从CommonResp取出业务数据对象并返回;
2、将该Decoder通过配置类注册到IOC容器中,并将该配置类设置为Feign的默认配置类;

示例代码如下:

package com.ljc.conf;

import com.ljc.common.CommonResp;
import com.ljc.util.JsonUtil;
import feign.FeignException;
import feign.RequestInterceptor;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import feign.optionals.OptionalDecoder;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.cloud.openfeign.support.HttpMessageConverterCustomizer;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;

import java.io.IOException;
import java.lang.reflect.Type;

@Configuration
@EnableFeignClients(basePackages = "com.ljc" ,defaultConfiguration = CommonFeignConfig.class)   // 设置EnableFeignClients的defaultConfiguration,将该配置类设置为Feign的默认配置类,这样FeignClient用的Decoder就是该配置类注入的Decoder
@Import(FeignClientsConfiguration.class)    // 把原先的配置类的配置内容引入到该配置类中
public class CommonFeignConfig {

    @Resource
    private Decoder originalDecoder;    // 获取原先的Decoder

    @Bean
    public RequestInterceptor commonRequestInterceptor() {
        return new MyHeaderInterceptor();
    }

    @Bean
    public Decoder customDecoder() {
        return new CommonDecoder(originalDecoder);
    }

    private static class CommonDecoder implements Decoder {

        private Decoder delegate;

        public CommonDecoder(Decoder delegate) {
            this.delegate = delegate;
        }

        @Override
        public Object decode(Response response, Type type) throws IOException, FeignException {
            Object decode = delegate.decode(response, type);

            if (decode instanceof String) {
                CommonResp<?> resp = (CommonResp<?>) JsonUtil.toObject((String) decode, CommonResp.class);
                return resp == null ? decode : resp.getData();
            }
            return (decode instanceof CommonResp ? ((CommonResp<?>) decode).getData() : decode);
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值