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);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值