Spring-cloud-openfeign解码器Decoder接口(后置拦截器)

使用feign调用第三方的http服务,对方返回response,之后这个Decoder接口会将对方的返回值,序列化成我们的返回值,例如下面的代码中,为什么我们能拿到User类型,而不是一个String类型,这就是Decoder来处理的

@FeignClient(name = "xxx", url = "xxx")
public interface UserAPI {// 即使对方返回一个符合json格式的String类型,feign也能将这个String转换成User,这就是Decoder接口做的事情@GetMapping(value = "/xxx/xxx")User getUser(@RequestParam("userId") Integer userId);}

下面的代码自定义了一个Decoder,由于Decoder是用来解析对方返回值,所以我这里使用Decoder来打印日志,这样省的每个接口自己打印对方返回值了

步骤1:自定义一个解码器

package 你的包名import feign.Response;
import feign.codec.Decoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
/*** <p>这个类本质上是个第三方Http Response的解码器,本类主要目的是在解码的同时打印日志** @author shiwentian* @since 1.7.2024**/
public class OpenFeignPostInterceptor implements Decoder {private static final Logger log = LoggerFactory.getLogger(OpenFeignPostInterceptor.class);private final Decoder delegate;public OpenFeignPostInterceptor(Decoder delegate) {this.delegate = delegate;}@Overridepublic Object decode(Response response, Type type) throws IOException {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = response.body().asInputStream().read(buffer)) != -1) {byteArrayOutputStream.write(buffer, 0, bytesRead);}byte[] body = byteArrayOutputStream.toByteArray();String bodyStr = new String(body, StandardCharsets.UTF_8);log.info("调用第三方接口返回:{}", bodyStr);return delegate.decode(response.toBuilder().body(bodyStr, StandardCharsets.UTF_8).build(), type);}
}

步骤2:将上面自定义的解码器通过lite的注入方式,注入到spring容器

package 你的包名;import feign.codec.Decoder;
import feign.optionals.OptionalDecoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
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;/*** 本类用于注册自定义的解码器** @author shiwentian* @since 1.7.2024**/
@Configuration
public class DecoderConfig {// 这个地方需要注意,不能使用@Resource,涉及到泛型问题,如果没有泛型,那么使用@Resource是可以的@Autowiredprivate ObjectFactory<HttpMessageConverters> messageConverters;@Beanpublic Decoder decode() {return new OpenFeignPostInterceptor(new OptionalDecoder(new ResponseEntityDecoder(new SpringDecoder(this.messageConverters))));}
}

好了,现在启动复用,通过feign调用第三方服务,会发现对方每次返回,都会打印对方的返回值

注意:我没有测试对方服务失败的情况,或者一些其他失败的情况,所以本文中的response.body().asInputStream()这段代码可能会出现不健壮的情况,需要你自己对失败的情况进行处理

源代码参考:Spring Cloud Open Feign 2.2.9版本org.springframework.cloud.openfeign.FeignClientsConfiguration类的public Decoder feignDecoder() 方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/39104.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

科普文:一文搞懂jvm实战(一)Runtime实时监控jvm

概叙 Java Runtime 类是 Java 标准库中的关键类之一。它提供了对当前Java虚拟机&#xff08;JVM&#xff09;实例的访问和控制&#xff0c;允许程序动态地修改和管理运行时环境。 Java Runtime 是Java虚拟机&#xff08;JVM&#xff09;的一个实例&#xff0c;代表了正在执行Ja…

Kafka 进阶指南

Kafka 进阶指南 引言 在掌握了 Kafka 的基本概念和操作后&#xff0c;我们可以进一步探索 Kafka 的高级特性和使用技巧&#xff0c;以提高其性能、可扩展性和可靠性。本指南将介绍 Kafka 的进阶主题&#xff0c;包括性能调优、扩展策略、数据复制、日志压缩、流处理和安全性。…

nrm工具——npm源管理器

nrm 是一个 npm 源管理器&#xff0c;允许你快速地在 npm源间切换。 一开始觉得这个工具没用&#xff0c;一般使用npm config set registry XXXXX命令就可以切换源地址 但是突然发现&#xff01;&#xff01;&#xff01;&#xff01; 淘宝镜像地址改了&#xff01;&#xf…

Spring Boot 实现 AOP 动态热插拔功能并附DEMO源码

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

python中的包和模块

目录 一、包与模块 二、第三方包的安装 2.1 pip install 2.2使用 curl 管道 2.3其他安装方法 三、导入单元的构成 3.1pip的使用 四、模块的缓存 一、包与模块 Python 中除了函数库以外&#xff0c;还有非常多且优秀的第三方库、包、模块。 模块Module&#xff1a;以…

【linux网络(七)】数据链路层详解

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; Linux网络 1. 前言2. 认识MAC…

【计算机毕业设计】061互助学习微信小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

北京网站建设怎么开始做

北京作为中国的首都&#xff0c;拥有众多的企业和机构&#xff0c;网站建设不仅是一种宣传和推广的手段&#xff0c;更是企业发展的必备工具。但是对于很多企业来说&#xff0c;网站建设是一个相对陌生的领域&#xff0c;不知道从哪里开始。今天我们就来谈一谈北京网站建设的步…

Dockerhub无法拉取镜像配置阿里镜像加速器

打开阿里镜像加速地址&#xff1a; https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 根据平台类型按照对应方式进行配置&#xff1a;Dokcer Desktop是在右上角点开配置 找到Docker Engine 进行设置JSON结构&#xff1a; 记得要重启Docker服务才会生效&#xff01…

深度学习笔记: 最详尽解释预测系统的分类指标(精确率、召回率和 F1 值)

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家&#xff01; 预测系统的分类指标(精确率、召回率和 F1 值) 简介 让我们来谈谈预测系统的分类指标以及对精确率、召回…

Spring MVC的高级功能——异常处理(一)简单异常处理器

一、HandlerExceptionResolver接口 如果希望对Spring MVC中所有异常进行统一处理&#xff0c;可以使用Spring MVC提供的异常处理器HandlerExceptionResolver接口。Spring MVC内部提供了HandlerExceptionResolver的实现类SimpleMappingExceptionResolver。它实现了简单的异常处理…

对于复杂的网页布局,如多列布局和网格布局,CSS 有哪些最佳实践和技巧?

对于复杂的网页布局&#xff0c;如多列布局和网格布局&#xff0c;以下是一些CSS的最佳实践和技巧&#xff1a; 使用Flexbox或CSS Grid布局&#xff1a;Flexbox和CSS Grid是两个强大的CSS布局模型&#xff0c;可用于实现复杂的网页布局。Flexbox适用于单行或单列布局&#xff0…

SpringSecurity6 | 基于数据库实现登录认证

SpringSecurity6 | 基于数据库认证 ✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringSecurity6 ✨特色专栏: MySQL学习 🥭本文内容: SpringSecurity6 | 基于数据库实现登…

数据资产的价值变现及管理规划(AMT企源)

从数据资源到数据资产之数据资产的价值变现及管理规划 题记 本文旨在探讨数据资产发展途径、数据产权及价值变现的服务流程和路径&#xff0c;并对数据资产管理平台框架、数据资产管理实施规划做出初步解读&#xff0c;以期为数据资产管理提供有益的思路和方案。 本次推出《从…

09 - Python图形用户界面和游戏开发

图形用户界面和游戏开发 基于tkinter模块的GUI GUI是图形用户界面的缩写&#xff0c;图形化的用户界面对使用过计算机的人来说应该都不陌生&#xff0c;在此也无需进行赘述。Python默认的GUI开发模块是tkinter&#xff08;在Python 3以前的版本中名为Tkinter&#xff09;&…

【linux】虚拟机安装 BCLinux-R8-U4-Server-x86_64

目录 一、概述 1.1移动云Linux系统订阅服务 CLS 1.2 大云天元操作系统BC-Linux 二、安装 一、概述 1.1移动云Linux系统订阅服务 CLS 移动云Linux系统订阅服务 CLS &#xff08;Cloud Linux Service&#xff09;为使用BC-Linux操作系统的用户提供标准维保服务以及高级技术支…

62、Flink自定义 SimpleAccumulator 代码示例

1、概述 需要实现 SimpleAccumulator 接口&#xff0c;并重写 add&#xff0c;getLocalValue&#xff0c;resetLocal&#xff0c;merge&#xff0c;clone 等方法。 2、代码示例 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; im…

mysql-5.6.26-winx64免安装版本

mysql为什么要使用免安装 MySQL 提供免安装版本主要有以下几个原因和优势&#xff1a; 便捷性&#xff1a;用户无需经历安装过程&#xff0c;直接解压即可使用。这对于需要快速部署环境或者在不支持安装权限的系统上使用MySQL非常有用。灵活性&#xff1a;免安装版允许用户将…

actual combat 32 —— RabbitMQ

1. 五种模式 RabbitMQ有五种工作模式&#xff0c;分别是简单模式、工作模式、发布订阅模式、路由模式和主题模式 简单模式&#xff08;Simple Mode&#xff09;&#xff1a;这种模式包含一个生产者和一个消费者。生产者将消息发送到队列&#xff0c;消费者从队列中获取消息。…

Optional类方法

Optional类 简介方法empty()方法of(T value)ofNullable(T value)filter(Predicate<? super T> predicate)get()ifPresent(Consumer<? super T> consumer)isPresent()map(Function<? super T,? extends U> mapper)orElse(T other)orElseGet(Supplier<?…