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


需求说明:在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异步调用解决

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)}

 

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); } } }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM