gateway调用feign

这篇具有很好参考价值的文章主要介绍了gateway调用feign。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

        在搭建项目的时候,需要网关去校验请求的合法性。这里通过gateway的filter中通过调用feign接口去验证token的方式实现。

gateway简介及与springboot的区别

todo文章来源地址https://www.toymoban.com/news/detail-690041.html

项目配置

微服务配置

接口配置

在微服务中,只展示controller的代码,其他的自己实现就可以。

  @ApiOperationSupport(order = 90, author = "alex")
    @ApiOperation(value = "根据token校验用户权限", notes = "根据token校验用户权限", response = Result.class)
    @GetMapping(value = "/authToken")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "token", name = "token")}
    )
    public Result<Boolean> authToken(@RequestParam(value = "token") String token) {
        return Result.success(true) ;
    }

feign接口

在这里根据spring.profiles.active动态去配置服务名,方便区分测试环境和正式环境。

@Component
@FeignClient(name = "alex-user-${spring.profiles.active:dev}", fallback = UserFallbackFactory.class, configuration = FeignConfig.class)
public interface UserApi {

    @GetMapping(value = "/api/v1/user/authToken")
    Result<Boolean> authToken(@RequestParam("token") String token);
}

feign异常处理类。

@Component
@Slf4j
public class UserFallbackFactory implements FallbackFactory<UserApi> {

    @Override
    public UserApi create(Throwable cause) {
        throw new SystemException(ResultEnum.SYSTEM_NO_AVAILABLE, "user");
    }
}

配置feign配置

@Configuration
public class FeignConfig implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            //添加token
            requestTemplate.header("Authorization", request.getHeader("Authorization"));
        }
    }

    @Bean
    public Logger.Level level() {
        //仅记录请求方法、URL、响应状态代码以及执行时间,生成一般用这个
        return Logger.Level.BASIC;
    }

    @Bean
    public RequestContextListener requestContextListener(){
        return new RequestContextListener();
    }
}

gateway配置

在GatewayApplication中配置EnableFeignClients调用feign。

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableDiscoveryClient
@ComponentScan(basePackages = {"com.alex.gateway", "com.alex.common", "com.alex.api.user"})
@EnableFeignClients(basePackages = {"com.alex.api.user"})
public class GatewayApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(GatewayApplication.class, args);
        AutowiredBean.setApplicationContext(run);
    }
}
@Component
@Slf4j
@RequiredArgsConstructor
public class GatewayFilter implements GlobalFilter, Ordered {

    private final GatewayAudience audience;

    private static final PathMatcher antPathMatcher = new AntPathMatcher();

    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getPath().toString();
        //白名单校验路径
        if (audience.getWhiteList() != null && !audience.getWhiteList().isEmpty()) {
            for (String white : audience.getWhiteList()) {
                if (antPathMatcher.match(white, path)) {
                    return chain.filter(exchange);
                }
            }
        }
        log.info("当前请求地址:{}", path);
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        Map<String, Object> attributes1 = exchange.getAttributes();
        //得到请求头信息authorization信息
        String token = Optional.ofNullable(request)
                .map(re -> re.getHeaders())
                .map(header -> header.getFirst(audience.getTokenHeader()))
                .orElse(null);
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        UserApi userApi = AutowiredBean.getBean(UserApi.class);
        CompletableFuture<Result<Boolean>> completableFuture = CompletableFuture.supplyAsync(() -> {
                    // 复制主线程的 线程共享数据
                    RequestContextHolder.setRequestAttributes(attributes);
                    Result<Boolean> res = userApi.authToken(token);
                    return res;
                }
        );
        Boolean result = Optional.ofNullable(completableFuture).map(item -> {
            try {
                return item.get().getData();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
        }).get();
        if (result) {
            return chain.filter(exchange);
        }
        return out(response);
    }

    /**
     * @description: 拦截器的优先级,数字越小优先级越高
     * @author: majf
     * @return: int
     */
    @Override
    public int getOrder() {
        return 0;
    }

    private Mono<Void> out(ServerHttpResponse response) {
        JsonObject message = new JsonObject();
        message.addProperty("success", false);
        message.addProperty("code", 403);
        message.addProperty("data", "请先登录!");
        byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        //response.setStatusCode(HttpStatus.UNAUTHORIZED);
        //指定编码,否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
}
public class AutowiredBean {

    private static ApplicationContext applicationContext;

    public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (AutowiredBean.applicationContext == null) {
            AutowiredBean.applicationContext = applicationContext;
        }
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

总结

至此在网关中调用feign接口配置完成。

源码地址

地址

Q&A

todo

到了这里,关于gateway调用feign的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringCloud实用篇2——Nacos配置管理 Feign远程调用 Gateway服务网关

    Nacos除了可以做注册中心,同样可以做配置管理来使用。 当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。 Nacos一方面可以将配置集中管理,另一方可以

    2024年02月13日
    浏览(36)
  • 【学习日记2023.6.12】之nacos配置管理_Feign远程调用_Gateway服务网关

    Nacos除了可以做注册中心,同样可以做配置管理来使用。 6.1 统一配置管理 当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。需要一种统一配置管理方案,可以集中管理所有实例的配置。 Nacos一方面可以将配置集中管理

    2024年02月09日
    浏览(50)
  • 微服务Day3——Nacos配置管理\Feign远程调用\Gateway网关

    当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。 Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。

    2024年02月16日
    浏览(35)
  • spring cloud整合spring boot,整合nacos、gateway、open-feign等组件

    想看具体详情的可以看我的github链接:codeking01/platform-parent: spring cloud整合spring boot、nacos、gateway、open feign等组件 (github.com) 由于我升级了jdk17,所以用上了spring boot 3.0.2了。 踩坑无数,一堆无用文章,写来写去,本文主要是提供给有基础的开发者再次快速搭建使用(确定版本

    2024年02月11日
    浏览(35)
  • 搭建feign远程调用环境

    在我的SpringCloud专栏中已经介绍过SpringCloud五大组件的环境搭建,各个环境的搭建都有详细的步骤讲解,之前我们说过各个服务搭建都是不依赖于之前的环境的,本节介绍的Feign服务间远程调用也是,本次也是侧重于环境搭建,Feign的作用我们之前已经介绍过了。可以查看:0

    2024年01月17日
    浏览(26)
  • 【Spring Cloud】如何使用Feign实现远程调用

    本次示例代码的文件结构如下图所示。 在 order-service 的 pom.xml 文件中导入 Feign 的依赖坐标。 在 order-service 的启动类上添加注解 @EnableFeignClients ,以开启 Feign 功能。 Feign 采用了 Spring MVC 的注解的方式发起远程调用。只需要把发 HTTP 请求的信息声明在一个接口中,并添加注解

    2024年02月13日
    浏览(36)
  • SpringCloud小项目——订单积分商城 & 使用Nacos、Open Feign、Gateway、Sentinel技术栈

    使用Nacos、Open Feign、Gateway、Sentinel技术栈实现XX公司订单、库存、积分的案例开发,以下是服务调用关系 git代码:https://gitee.com/pet365/spring-cloud-goods https://github.com/RainbowForest/e-commerce-microservices https://awesomeopensource.com/project/RainbowForest/e-commerce-microservices 使用Nacos、Open Feign、Gate

    2024年02月08日
    浏览(33)
  • 【云原生】Spring Cloud Alibaba 之 Feign 远程调用 实战

    在分布式领域中,一个系统由很多服务组成,不同的服务由各自的进程单独负责。因此,远程调用在分布式通信中尤为重要。 远程调用可分如下两类: 本地过程调用(Local Procedure Call,LPC) ,是指同一台机器上运行的不同进程之间的互相通信,即在多进程操作系统中,运行

    2023年04月09日
    浏览(29)
  • Spring Cloud Alibaba全家桶(四)——微服务调用组件Feign

    本文小新为大家带来 微服务调用组件Feign 的相关知识,具体内容包含 什么是Feign , Spring Cloud Alibaba快速整合OpenFeign , Spring Cloud Feign的自定义配置及使用 (包括: 日志配置 、 契约配置 、 自定义拦截器实现认证逻辑 、 超时时间配置 、 客户端组件配置 、 GZIP 压缩配置 )等

    2024年02月19日
    浏览(32)
  • 【Spring Cloud】基于 Feign 实现远程调用,深入探索 Feign 的自定义配置、性能优化以及最佳实践方案

    在微服务架构中,服务之间的通信是至关重要的,而远程调用则成为实现这种通信的一种常见方式。在 Java 中,使用 RestTemplate 是一种传统的远程调用方式,但它存在一些问题,如代码可读性差、编程体验不一致以及参数复杂URL难以维护等。 在本文中,我们将探讨如何通过使

    2024年02月04日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包