spring-cloud-feign实战笔记

news/2024/7/24 10:05:33 标签: java, spring, spring-cloud, feign

feign__0">feign 配置

  1. 针对单个feign接口进行配置
    feign:
      client:
        config:
          # feignName 注意这里与contextId一致,不能写成name(FeignClientFactoryBean#configureFeign)
          # 不能写成 client-b (微服务名称),否则不生效
          helloFeignClient: # contextId
            connectTimeout: 50000 # 连接超时时间
            readTimeout: 50000 # 读超时时间
            loggerLevel: full #配置Feign的日志级别
          #default:
            # 其他默认配置
    
  2. feign 全局默认配置
    feign:
      client:
        config:
          default:
            connectTimeout: 50000 # 连接超时时间
            readTimeout: 50000 # 读超时时间
            loggerLevel: full #配置Feign的日志级别
    
  3. feign开启gzip支持
    feign:
      compression:
        request:
          enabled: true
          mime-types: "text/xml, application/xml, application/json"
          min-request-size: 2048
        response:
          enabled: true # 配置相应GZIP压缩
    

开启gzip支持后接口调用处理方式一

  1. feign接口使用ResponseEntity<byte []>接收数据
    java">@FeignClient(contextId = "testFeignClient", 
            name = "client-a", configuration = FeignConfig.class)
    public interface TestFeignClient {
        @GetMapping(value = "/userInfo")
        ResponseEntity<byte []> userInfoCompress(
                @RequestParam("username") String username, @RequestParam("address") String address) ;
    }
    
  2. 编写单元测试(注意需要对byte[] 数组使用Gzip解压)
    java">@Slf4j
    public class TestFeignClientTest extends BaseJunitTest {
        @Autowired
        private TestFeignClient testFeignClient ;
        @Test
        public void userInfoCompress() throws IOException {
            String username = "张三" ;
            String address = "北京" ;
            ResponseEntity<byte[]> responseEntity = testFeignClient.userInfoCompress(username, address);
            byte[] compressed = responseEntity.getBody();
            String decompressValue = GzipUtils.decompress(compressed);
            log.info("value : {}", decompressValue);
        }
    }
    
  3. 编写gzip解压缩工具类
    java">public final class GzipUtils {
        public static String decompress(byte [] compressed) throws IOException {
            final StringBuilder output = new StringBuilder() ;
            try(GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(compressed));
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(gis, StandardCharsets.UTF_8))){
                String line ;
                while ((line = bufferedReader.readLine()) != null){
                    output.append(line) ;
                }
                return output.toString() ;
            }
        }
    }
    

开启gzip支持后接口调用处理方式二

  1. 编写Decoder (内部使用方式一的Gzip解压缩工具类GzipUtils)
    java">public class FeignResponseDecoder implements Decoder {
        private final Decoder delegate;
        public FeignResponseDecoder(Decoder delegate) {
            Objects.requireNonNull(delegate, "Decoder must not be null. ");
            this.delegate = delegate;
        }
        @Override
        public Object decode(Response response, Type type) throws IOException {
            Collection<String> values = response.headers().get(HttpEncoding.CONTENT_ENCODING_HEADER);
            if (Objects.nonNull(values) && !values.isEmpty() && values.contains(HttpEncoding.GZIP_ENCODING)) {
                byte[] compressed = Util.toByteArray(response.body().asInputStream());
                if ((compressed == null) || (compressed.length == 0)) {
                    return delegate.decode(response, type);
                }
                //decompression part
                //after decompress we are delegating the decompressed response to default
                //decoder
                if (isCompressed(compressed)) {
                    String decompressValue = GzipUtils.decompress(compressed);
                    Response decompressedResponse = response.toBuilder().body(decompressValue.getBytes()).build();
                    return delegate.decode(decompressedResponse, type);
                } else {
                    return delegate.decode(response, type);
                }
            } else {
                return delegate.decode(response, type);
            }
        }
        private static boolean isCompressed(final byte[] compressed) {
            return (compressed[0] == (byte) (GZIPInputStream.GZIP_MAGIC)) && (compressed[1] == (byte) (GZIPInputStream.GZIP_MAGIC >> 8));
        }
    }
    
  2. 将Decoder加入到Spring容器管理
    java">@Configuration
    public class AppConfig{
       @Bean
       public Decoder GZIPResponseDecoder(ObjectFactory<HttpMessageConverters> messageConverters) {
          Decoder decoder = new FeignResponseDecoder(new SpringDecoder(messageConverters));
          return decoder;
       }
    }
    
  3. feign接口使用普通java对象接收数据
    java">@FeignClient(contextId = "testFeignClient", 
            name = "client-a", configuration = FeignConfig.class)
    public interface TestFeignClient {
        @GetMapping("/userInfo")
        UserInfoVO userInfo(@RequestParam("username") String username, @RequestParam("address") String address) ;
    }
    
  4. 编写单元测试
    java">@Slf4j
    public class TestFeignClientTest extends BaseJunitTest {
        @Autowired
        private TestFeignClient testFeignClient ;
        
        @Test
        public void userInfo(){
            String username = "张三" ;
            String address = "北京" ;
            UserInfoVO userInfo = testFeignClient.userInfo(username, address);
            log.info("user info : {}", userInfo);
        }
    }
    

其他知识点补充

  1. SpringBoot服务提供者开启gizp压缩
    server:
      port: 7070
      compression:
        enabled: true
    

http://www.niftyadmin.cn/n/143704.html

相关文章

【读书笔记】《深入浅出数据分析》第十、十一章 回归、合理误差

目录一&#xff0c;回归分析1&#xff0c;概述2、分类3&#xff0c;相关分析与回归分析联系二&#xff0c;标准差、方差、协方差、残差、均方误差、标准误差&#xff08;一&#xff09;区别关系1&#xff0c;方差(Variance)1.1 总体方差1.2 样本方差2&#xff0c;标准差(Standa…

unity 有关协程脚本的停止

最近总结了一个协程使用的文章&#xff0c;实现了一个利用协程使物体自带材质闪烁的脚本&#xff0c;然后在使用过程中遇到了如下情况&#xff1a;取消勾选&#xff08;或者禁用脚本&#xff09;协程不会停止&#xff0c;闪烁效果依然存在&#xff0c;即协程没有被终止 using …

JMeter性能测试框架从0到1使用入门

jmeter介绍 JMeter是Apache组织开发的开源项目&#xff0c;设计之初是用于做性能测试的&#xff0c;同时它在实现对各种接口的调用方面 做的比较成熟&#xff0c;因此&#xff0c;常被用做接口功能测试和性能测试。 有如下特点&#xff1a; 开源免费&#xff0c;基于Java编写…

ZSet的底层实现原理

文章目录1、zset底层数据结构&#xff1f;简单说说跳表底层数据结构&#xff1f;2、什么时候采用压缩列表、什么时候采用跳表&#xff1f;3、跳表的时间复杂度&#xff1f;4、简单描述一下跳表如何查找某个元素5、zset为什么用跳表而不用二叉树或者红黑树&#xff1f;6、zset的…

10分钟搞懂,Python接口自动化测试-接口依赖-实战教程

今天主要和大家介绍如何提取token、将token作为类属性全局调用及充值接口如何携带token进行请求。话不多说&#xff0c;我们往下看&#xff01; 接口自动化测试接口依赖视频地址&#xff1a;https://www.bilibili.com/video/BV1914y1F7Bv 目录&#xff1a;导读 一、场景说明 …

研报精选230312

目录 【行业230312中航证券】军工行业周报&#xff1a;成交回暖、关注提升【行业230312山西证券】煤炭行业周报&#xff1a;年报业绩快报密集披露&#xff0c;关注超预期个股【行业230312中航证券】航天产业月报&#xff1a;卫星产业迎来高光时刻&#xff0c;关注业绩兑现持续性…

JVM—本地方法接口

本地方法接口 在讲Java虚拟机运行时数据区中本地方法栈之前&#xff0c;我们先来说说运行时数据区之外的一个叫本地方法接口的东西简称JNI&#xff08;Java Native Interface&#xff09; 简单来讲&#xff0c;一个Native Method就是一个java调用非java代码的接口&#xff0c;…

【C++ | 基础语法】

C基础语法1.函数的重载2.引用引用的用法1.引用做参数2.引用返回1.函数的重载 在C中&#xff0c;函数是支持重载的。什么是重载呢&#xff1f; 重载的意思就是函数名相同&#xff0c;但是参数的个数、类型不同。 例如&#xff1a; void func() {cout << "func()&…