Spring Cloud Gateway: как передать параметры в пользовательский фильтр - PullRequest
0 голосов
/ 25 ноября 2018

У меня есть пользовательский фильтр, определенный в моем application.yml.Мне нужно взять еще несколько параметров из этого определения фильтра в YAML, чтобы я мог выполнять логику внутри своего пользовательского фильтра.У меня есть несколько таких маршрутов, в которых параметры фильтра отличаются.Проблема, с которой я сталкиваюсь, заключается в том, что я не могу прочитать значения, указанные в файле YAML.

application.yml ---

spring:
  cloud:
    gateway:
      routes:
      - id: test_route
        uri: https://api.rangon.pi
        predicates:
        - Path=/api/staticdata/rattlefeed*
        filters:
        - AddRequestHeader=X-Y-Host, rangon
        - TestGatewayFilter=admin, XY8382, basic

// Есть ли способ получить "admin, XY8382, basic" в моем классе пользовательских фильтров

Мой класс фильтра

@Component
public class TestGatewayFilter implements 
   GatewayFilterFactory<TestGatewayFilter.Config> {

     @Override
     public GatewayFilter apply(Config config) {
         // grab configuration from Config object

         return (exchange, chain) -> {
             Route r = (Route) exchange.getAttributes().get(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);

             Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
            // ServerWebExchange route =
            // exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
            // List<GatewayFilter> list = r.getFilters();

            GatewayFilter gwf = r.getFilters().get(r.getFilters().size() - 1);

            Builder builder = exchange.getRequest().mutate();
            // use builder to manipulate the request

            return chain.filter(exchange.mutate().build());
        };
    }

    public Config newConfig() {

        Config c = new Config();
        return c;
    }

    public static class Config {
        // Put the configuration properties for your filter here

    }

} 

1 Ответ

0 голосов
/ 05 апреля 2019

Существует два способа определения параметров для ваших фильтров в application.yml

. Сначала используйте ключевое слово args:

spring:
  cloud:
    gateway:
      routes:
        - id: test_route
          uri: https://myapi.com
          filters:
            - name: TestLoggingFilter
              args:
                value: ThisIsATest

, а второе - встроенными аргументами:

spring:
  cloud:
    gateway:
      routes:
        - id: test_route
          uri: https://myapi.com
          filters:
            - TestLoggingFilter=ThisIsATest

Если вы хотите использовать встроенные аргументы, обязательно переопределите метод shortcutFieldOrder в вашем фильтре массивом, содержащим имя параметров, которые вы хотите получить, этот массив также используется для определения порядкаthe params.

Ниже приведен пример простого фильтра, который работает с любым из предыдущих определений:

package com.es.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;

@Component
public class TestLoggingFilter implements GatewayFilterFactory<TestLoggingFilter.Config> {

    private static final Logger LOG = LoggerFactory.getLogger(TestLoggingFilter.class);

    private static final String VALUE = "value";

    @Override
    public Config newConfig() {
        return new Config();
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Collections.singletonList(VALUE);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            LOG.info("Filter enabled with value: " + config.value);
            return chain.filter(exchange);
        };
    }

    public static class Config {

        private String value;

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}
...