聊聊spring cloud gateway的SetStatusGatewayFilter

本文主要研究下spring cloud gateway的SetStatusGatewayFilter

GatewayAutoConfiguration

spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
@AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {
    //......
    @Bean
    public SetStatusGatewayFilterFactory setStatusGatewayFilterFactory() {
        return new SetStatusGatewayFilterFactory();
    }
    //......
}

默认创建SetStatusGatewayFilterFactory

SetStatusGatewayFilterFactory

spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/filter/factory/SetStatusGatewayFilterFactory.java

public class SetStatusGatewayFilterFactory extends AbstractGatewayFilterFactory<SetStatusGatewayFilterFactory.Config> {

    public static final String STATUS_KEY = "status";

    public SetStatusGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(STATUS_KEY);
    }

    @Override
    public GatewayFilter apply(Config config) {
        final HttpStatus status = ServerWebExchangeUtils.parse(config.status);
        final Integer intStatus;
        if (status == null) {
            intStatus = Integer.parseInt(config.status);
        } else {
            intStatus = null;
        }
        return (exchange, chain) -> {

            // option 1 (runs in filter order)
            /*exchange.getResponse().beforeCommit(() -> {
                exchange.getResponse().setStatusCode(finalStatus);
                return Mono.empty();
            });
            return chain.filter(exchange);*/

            // option 2 (runs in reverse filter order)
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // check not really needed, since it is guarded in setStatusCode,
                // but it's a good example
                if (!exchange.getResponse().isCommitted()) {
                    if (status != null) { // standard status
                        setResponseStatus(exchange, status);
                    } else if (intStatus != null && exchange.getResponse() instanceof AbstractServerHttpResponse) { //non-standard
                        ((AbstractServerHttpResponse)exchange.getResponse()).setStatusCodeValue(intStatus);
                    }
                }
            }));
        };
    }

    public static class Config {
        //TODO: relaxed HttpStatus converter
        private String status;

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }
    }

}
  • 可以看到,就是简单地根据status来设置response的status
  • 注意这里有两个option,源码注释掉了option1,改为使用option2

实例

spring:
  cloud:
    gateway:
      routes:
      - id: setstatusstring_route
        uri: http://example.org
        predicates:
        - Path=/foo/**
        filters:
        - SetStatus=BAD_REQUEST
      - id: setstatusint_route
        uri: http://example.org
        predicates:
        - Path=/name/**
        filters:
        - SetStatus=401

小结

SetStatusGatewayFilter就是简单地设置response,使用option1方式的话,是在response commit之前设置的,而且一旦设置就直接return,不再继续走filter了,因而SetStatus可以生效;使用option2的话,是逆filter顺序执行的,会先判断是否commit,未commit才设置,实际不生效。

doc

  • 112.17 SetStatus GatewayFilter Factory

原文发布于微信公众号 - 码匠的流水账(geek_luandun)

原文发表时间:2018-06-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android先生

Android 使用代码实现一个选词(拖拽)填空题

在上一篇文章《Android 使用代码实现一个填空题》中,我们学习了如何实现一个填空题,今天继续接着上一篇文章的节奏,学习一下如何实现一个选词填空题,由于本文中...

1062
来自专栏Android中高级开发

Android开发之漫漫长途 XV——RecyclerView

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索...

1702
来自专栏向治洪

listview优化(中)

1,对Imageview使用setTag()方法来解决图片错位问题,这个Tag中设置的是图片的url,然后在加载的时候取得这个url和要加载那position...

21910
来自专栏Android先生

VLayout适配器的万能封装

传统的RecyclerView高级应用,还是挺麻烦的,阿里开源了Vlayout,采用代理模式独立承担各式各样的布局,大大的减少了程序媛的工作量,...

1684
来自专栏向治洪

android之listview缓存图片(缓存优化)

网上关于这个方面的文章也不少,基本的思路是线程+缓存来解决。下面提出一些优化: 1、采用线程池 2、内存缓存+文件缓存 3、内存缓存中网上很多是采用SoftRe...

3399
来自专栏用户2442861的专栏

ListView 原理的介绍 qt也可以吧想通的Android

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/44996879

421
来自专栏everhad

ViewPager无限滑动

前言 View轮播效果在app中很常见,一想到左右滑动的效果就很容易想到使用ViewPager来实现。对于像我们常说的banner这样的效果,具备无限滑动的功能...

3617
来自专栏Android开发指南

5.AsyncHttp、post

3197
来自专栏码匠的流水账

聊聊spring cloud gateway的RedirectToGatewayFilter

本文主要研究下spring cloud gateway的RedirectToGatewayFilter

1581
来自专栏郭霖

Android ListView工作原理完全解析,带你从源码的角度彻底理解

在Android所有常用的原生控件当中,用法最复杂的应该就是ListView了,它专门用于处理那种内容元素很多,手机屏幕无法展示出所有内容的情况。ListVie...

36710

扫码关注云+社区

领取腾讯云代金券