使用feign拦截响应,打印日志

使用feign拦截响应,打印日志

1、前言

spring cloud 对feign调用对返回值做了包装处理,通过一些列Decoder来处理feign访问的返回值。
具体流程 从SynchronousMethodHandler中的decoder开始会经历如下几个decoder:

OptionalDecoder -> ResponseEntityDecoder -> SpringDecoder

可以在 FeignClientsConfiguration 看到有对上面三个decoder的定义,有兴趣的可以自行阅读源码。

feign返回值拦截 + response只能读取一次处理

feign返回值拦截只需要自定义一个coder,替换 FeignClientsConfiguration 中的 decoder定义即可,具体代码如下:
配置自定义decoder:

/**
 * feign返回值拦截
 * @author liufei
 */
public final class ResultStatusDecoder implements Decoder {
    public static final String CONTENT_KEY = "content";
    final Decoder delegate;

    public ResultStatusDecoder(Decoder delegate) {
        Objects.requireNonNull(delegate, "Decoder must not be null. ");
        this.delegate = delegate;
    }

    @Override
    public Object decode(Response response, Type type) throws IOException {
        // 判断是否返回参数是否是异常
        String resultStr = IOUtils.toString(response.body().asInputStream(), StandardCharsets.UTF_8);
        // 拿到返回值,进行自定义逻辑处理
        log.info("do business ,result msg ->{}",resultStr);
        // 回写body,因为response的流数据只能读一次,这里回写后重新生成response
        return delegate.decode(response.toBuilder().body(resultStr, StandardCharsets.UTF_8).build(), type);
    }
}

由于response中的body只能读取一次,所以最后需要把body回写,再重新生成response传递到下一个decoder

配置自定义bean:

@Configuration
public class SupportAutoConfiguration {

    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;
    
    @Bean
    public Decoder feignDecoder() {
        return new ResultStatusDecoder(new OptionalDecoder(new ResponseEntityDecoder(new SpringDecoder(this.messageConverters))));
    }
}
posted @   码出新生活!  阅读(3178)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· DeepSeek “源神”启动!「GitHub 热点速览」
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示