Java spring cloud gateway GlobalFilter通过feign调用其他服务

摘要:
需求描述:分析调用网关服务中其他服务的接口问题:1.在GlobalFilter筛选器类中获取外部服务类时,如果使用@Autowired注释获取该类,则会报告错误。这与servlet和过滤器的加载顺序有关。因此,使用了Autowired Bean类。其原理是从spring上下文中获取foreign的自定义bean,然后正常调用接口。2.在过滤器类中正常调用外部服务接口时。lan将被抛出

需求说明:在gateway服务里面需要调用其他服务的接口

问题分析:1.在GlobalFilter过滤类中获取feign服务类时,用@Autowired注解获取会报错,这和servlet, filter的加载顺序有关,所以使用AutowiredBean类,原理是从spring上下文中获取feign的自定义Bean,然后在正常调用接口

2.在过滤类中正常调用feign服务接口时,会抛出一个java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-2,意思是线程堵塞,使用CompletableFuture.supplyAsync异步调用解决

Java spring cloud gateway GlobalFilter通过feign调用其他服务第1张

3.FeignConfig类解决异步调用 feign 的错误,不加这个类会抛一个异常java.util.concurrent.ExecutionException: feign.codec.DecodeException: No qualifying bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

 Java spring cloud gateway GlobalFilter通过feign调用其他服务第2张

1.GlobalFilter过滤类

 1 @Component
 2 public class InnerFilter implements GlobalFilter, Ordered {
 3 
 4     @SneakyThrows
 5     @Override
 6     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
 7         SysLog sysLog = new SysLog();
 8         sysLog.setLoginName("lsz");
 9 
10         //获取的关键看这里,在用的时候在获取bean  
11         SysLogClient sysLogClient = AutowiredBean.getBean(SysLogClient.class);
12      //异步调用feign服务接口   
13         CompletableFuture<HttpResult> f = CompletableFuture.supplyAsync(()->{
14             return sysLogClient.getSysLogListWithPage(0, 10, "ad");
15         });
16 
17         HttpResult result = f.get();
18         // TODO 这里未来还可以限制一些格式
19         return chain.filter(exchange.mutate().request(exchange.getRequest()).build());
20     }
21     
22     /**
23      * 优先级默认设置为最高
24      *
25      * @return
26      */
27     @Override
28     public int getOrder() {
29         return -800;
30     }
31 }

2.获取feign服务类AutowiredBean

 1  2 
 3 import org.springframework.beans.BeansException;
 4 import org.springframework.context.ApplicationContext;
 5 
 6 public class AutowiredBean{
 7 
 8     private static ApplicationContext applicationContext;
 9 
10     public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
11         if (AutowiredBean.applicationContext == null) {
12             AutowiredBean.applicationContext = applicationContext;
13         }
14     }
15 
16     public static ApplicationContext getApplicationContext() {
17         return applicationContext;
18     }
19 
20     public static Object getBean(String name) {
21         return getApplicationContext().getBean(name);
22     }
23 
24     public static <T> T getBean(Class<T> clazz) {
25         return getApplicationContext().getBean(clazz);
26     }
27 
28     public static <T> T getBean(String name, Class<T> clazz) {
29         return getApplicationContext().getBean(name, clazz);
30     }
31 
32 }

3. Feign配置类,解决异步调用 feign 的错误

package com.hnlt.cloud.gateway.config;

import feign.Logger;
import feign.codec.Decoder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectFactory;
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;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.ArrayList;
import java.util.List;

/**
 * Feign 配置
 * @author: lsz
 * @time: 2021/10/15
 */
@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLevel() {
        //这里记录所有
        return Logger.Level.FULL;
    }

    @Bean
    public Decoder feignDecoder() {
        return new ResponseEntityDecoder(new SpringDecoder(feignHttpMessageConverter()));
    }

    public ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
        final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(new PhpMappingJackson2HttpMessageConverter());
        return new ObjectFactory<HttpMessageConverters>() {
            @Override
            public HttpMessageConverters getObject() throws BeansException {
                return httpMessageConverters;
            }
        };
    }

    public class PhpMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
        PhpMappingJackson2HttpMessageConverter(){
            List<MediaType> mediaTypes = new ArrayList<>();
            mediaTypes.add(MediaType.valueOf(MediaType.TEXT_HTML_VALUE + ";charset=UTF-8"));
            setSupportedMediaTypes(mediaTypes);
        }
    }
}

 

免责声明:文章转载自《Java spring cloud gateway GlobalFilter通过feign调用其他服务》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【Java】分割字符串并实现去重(重复的分割字符)STM32CubeIDE+FreeRTOS消息队列实验下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Spring使用@Async注解

    本文讲述@Async注解,在Spring体系中的应用。本文仅说明@Async注解的应用规则,对于原理,调用逻辑,源码分析,暂不介绍。对于异步方法调用,从Spring3开始提供了@Async注解,该注解可以被标注在方法上,以便异步地调用该方法。调用者将在调用时立即返回,方法的实际执行将提交给Spring TaskExecutor的任务中,由指定的线程...

将Kafka收到的数据传入到redis中

首先得配置GateWay中的config.properties 然后再看一下TBox中的properties main方法中  Test中的config.properties  Test中 先启动网管(GateWay),再启动终端(TBox),然后再运行KafkaTest 启动TBox   在启动Test 可以看到 接收到数据了  然...

Spring强制使用CGLIB代理事务

 Spring强制使用CGLIB代理事务   springaopjdkreferenceclasspath Spring1.2: 将事务代理工厂[TransactionProxyFactoryBean] 或 自动代理拦截器[BeanNameAutoProxyCreator] 的 proxyTargetClass 属性,设置为true,则使用CG...

Linux shell脚本,按顺序批量启动多个jar包,批量启动spring cloud的jar包

Linux shell脚本,按顺序批量启动多个jar包,批量启动spring cloud的jar包 一. 手动一个一个启动的方式: nohup java -jar eurekaserver.jar > ../logs/eurekaserver.log 2>&1 & nohup java -jar configserver.jar...

支付网关集成(转自Best Payment Gateways)

如果你要在你的电子商务网站上接受信用卡付款,你需要一个支付网关.本篇文章解释了做支付网关集成需要你做什么,如何找一个程序员去做这件事,还介绍了当下流行的支付网关. 如果你打算做电子商务,首要的事情就是你需要一个支付网关.支付网关是一个应用程序,在上面你可以通过互联网处理你的交易.如果你要在因特网上买一些商品或者一些服务,你需要支付网关帮助你与你的客户和金融...

SpringBoot启动过程解析(简化)

springBoot web方式启动过程 在这个启动过程中会有各种SpringBoot对外提供的扩展接口来对不同启动阶段进行自定义操作。 了解启动过程也是为了让我们更好理解SpringBoot提供的扩展接口使用   jar包启动或者外置war包启动都是调用SpringApplication.run()方法进行项目启动 tomcat会查询context上下文...