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