<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Gateway 自定義過濾器

          共 4791字,需瀏覽 10分鐘

           ·

          2020-12-13 04:25

          點(diǎn)擊上方「藍(lán)字」關(guān)注我們

          Spring Cloud Gateway雖然自帶有許多實(shí)用的GatewayFilter Factory、Gateway Filter、Global Filter,但是在很多業(yè)務(wù)情景下仍然需要自定義過濾器。實(shí)現(xiàn)一些自定義操作,滿足業(yè)務(wù)需求。所以自定義過濾器就顯得非常有必要。本文分表介紹自定義Gateway Filter、自定義Global Filter、自定義Gateway Filter Factory。


          實(shí)現(xiàn)自定義過濾器,其實(shí)可以去查看Spring Cloud Gateway自帶過濾器源碼是如何實(shí)現(xiàn)的。

          • 自定義Gateway Filter

          實(shí)現(xiàn)自定義的Gateway Filter,需要GatewayFilter、Ordered兩個接口

          /**
          ?*?此過濾器功能為計(jì)算請求完成時間
          ?*/

          public?class?MyFilter?implements?GatewayFilter,?Ordered?{

          ????private?static?final?String?ELAPSED_TIME_BEGIN?=?"elapsedTimeBegin";

          ????@Override
          ????public?Mono?filter(ServerWebExchange?exchange,?GatewayFilterChain?chain)?{
          ????????exchange.getAttributes().put(ELAPSED_TIME_BEGIN,?System.currentTimeMillis());
          ????????return?chain.filter(exchange).then(
          ????????????????Mono.fromRunnable(()?->?{
          ????????????????????Long?startTime?=?exchange.getAttribute(ELAPSED_TIME_BEGIN);
          ????????????????????if?(startTime?!=?null)?{
          ????????????????????????System.out.println(exchange.getRequest().getURI().getRawPath()?+?":?"?+?(System.currentTimeMillis()?-?startTime)?+?"ms");
          ????????????????????}
          ????????????????})
          ????????);
          ????}

          ????/*
          ????*過濾器存在優(yōu)先級,order越大,優(yōu)先級越低
          ????*/

          ????@Override
          ????public?int?getOrder()?{
          ????????return?Ordered.LOWEST_PRECEDENCE;
          ????}
          }



          定義好MyFilter以后,其需要跟Route綁定使用,不能在application.yml文件中配置使用

          @Bean
          public?RouteLocator?routeLocator(RouteLocatorBuilder?builder)?{
          ?????return?builder.routes().route(r?->
          ?????????????r.path("/aa")
          ?????????????????????//轉(zhuǎn)發(fā)路由
          ??????????????????? .uri("http://localhost:8080/provider/test")
          ?????????????????????//注冊自定義過濾器
          ?????????????????????.filters(new?MyFilter())
          ????????????????????//給定id
          ????????????????????.id("user-service"))
          ???????????????? .build();
          }

          測試結(jié)果:可以在控制臺看到請求響應(yīng)時間。

          • 自定義Gateway Filter Factory

          很多時候更希望在配置文件中配置Gateway Filter,所以可以自定義過濾器工廠實(shí)現(xiàn)。

          自定義過濾器工廠需要繼承AbstractGatewayFilterFactory

          @Component
          public?class?AuthorizeGatewayFilterFactory?extends?AbstractGatewayFilterFactory<AuthorizeGatewayFilterFactory.Config>?{

          ????private?static?final?Log?logger?=?LogFactory.getLog(AuthorizeGatewayFilterFactory.class);

          ????private?static?final?String?AUTHORIZE_TOKEN?=?"token";
          ????private?static?final?String?AUTHORIZE_UID?=?"uid";

          ????@Autowired
          ????private?StringRedisTemplate?stringRedisTemplate;

          ????public?AuthorizeGatewayFilterFactory()?{
          ????????super(Config.class);
          ????????logger.info("Loaded?GatewayFilterFactory?[Authorize]");
          ????}

          ????@Override
          ????public?List?shortcutFieldOrder()?{
          ????????return?Arrays.asList("enabled");
          ????}

          ????@Override
          ????public?GatewayFilter?apply(AuthorizeGatewayFilterFactory.Config?config)?{
          ????????return?(exchange,?chain)?->?{
          ????????????if?(!config.isEnabled())?{
          ????????????????return?chain.filter(exchange);
          ????????????}

          ????????????ServerHttpRequest?request?=?exchange.getRequest();
          ????????????HttpHeaders?headers?=?request.getHeaders();
          ????????????String?token?=?headers.getFirst(AUTHORIZE_TOKEN);
          ????????????String?uid?=?headers.getFirst(AUTHORIZE_UID);
          ????????????if?(token?==?null)?{
          ????????????????token?=?request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
          ????????????}
          ????????????if?(uid?==?null)?{
          ????????????????uid?=?request.getQueryParams().getFirst(AUTHORIZE_UID);
          ????????????}

          ????????????ServerHttpResponse?response?=?exchange.getResponse();
          ????????????if?(StringUtils.isEmpty(token)?||?StringUtils.isEmpty(uid))?{
          ????????????????response.setStatusCode(HttpStatus.UNAUTHORIZED);
          ????????????????return?response.setComplete();
          ????????????}
          ????????????String?authToken?=?stringRedisTemplate.opsForValue().get(uid);
          ????????????if?(authToken?==?null?||?!authToken.equals(token))?{
          ????????????????response.setStatusCode(HttpStatus.UNAUTHORIZED);
          ????????????????return?response.setComplete();
          ????????????}
          ????????????return?chain.filter(exchange);
          ????????};
          ????}

          ????public?static?class?Config?{
          ????????//?控制是否開啟認(rèn)證
          ????????private?boolean?enabled;

          ????????public?Config()?{ }

          ????????public?boolean?isEnabled()?{
          ????????????return?enabled;
          ????????}

          ????????public?void?setEnabled(boolean?enabled)?{
          ????????????this.enabled?=?enabled;
          ????????}
          ????}
          }

          在application.yml配置使用

          #?網(wǎng)關(guān)路由配置
          spring:
          ??cloud:
          ????gateway:
          ??????routes:
          ??????-?id:?user-center-service
          ????????uri:?http://localhost:8080/api/user/list
          ????????predicates:
          ????????-?Path=/user/list
          ????????filters:
          ????????#?關(guān)鍵在下面一句,值為true則開啟認(rèn)證,false則不開啟
          ????????#?這種配置方式和spring?cloud?gateway內(nèi)置的GatewayFilterFactory一致
          ????????-?Authorize=true
          • 自定義Global Filter

          實(shí)現(xiàn)自定義全局過濾器需要繼承GlobalFilter和Ordered

          @Component
          public?class?MyGloablFilter?implements?GlobalFilter,?Ordered?{
          ????
          @Override
          ????
          public?Mono?filter(ServerWebExchange?exchange,?GatewayFilterChain?chain)?{
          ????????System.out.println(
          "MyGloablFilter>>>");
          ????????
          return?chain.filter(exchange);
          ????}

          ????
          @Override
          ????
          public?int?getOrder()?{
          ????????
          return?0;
          ????}
          }

          使用它只需要加上@Component注解。

          掃碼二維碼

          獲取更多精彩

          Java樂園

          有用!分享+在看?
          瀏覽 45
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  a片黄色免费观看 | 欧美v日韩v亚洲 | 日韩大尺度视频 | 麻豆亚洲AV成人无码久久精品 | 俺去也成人网 |