Рубрики
Без рубрики

Изменение тела ответа в фильтре Zuul

Узнайте о фильтре сообщений Netflix Zuul.

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы рассмотрим фильтр сообщений Netflix Zuul.

Netflix Zuul – это пограничный поставщик услуг, который находится между клиентом API и множеством микросервисов.

Постфильтр запускается перед отправкой окончательных ответов клиенту API. Это дает нам возможность действовать на необработанном теле ответа и делать такие вещи, как ведение журнала и другие преобразования данных, которые мы хотим.

2. Зависимости

Мы будем работать с Zuul в весенней облачной среде. Итак, давайте добавим следующее в раздел управления зависимостями вашего pom.xml:


    
        
            org.springframework.cloud
            spring-cloud-dependencies
            2020.0.0
            pom
            import
        
    



    
        org.springframework.cloud
        spring-cloud-starter-netflix-zuul
        2.2.2.RELEASE
    

Последнюю версию зависимостей Spring Cloud и spring-cloud-starter-netflix-zuul можно найти на Maven Central.

3. Создание фильтра записей

Фильтр post – это обычный класс, который расширяет абстрактный класс ZuulFilter и имеет тип фильтра post :

public class ResponseLogFilter extends ZuulFilter {
    
    @Override
    public String filterType() {
        return POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        return null;
    }
}

Обратите внимание, что мы вернули POST_TYPE в методе filter Type () . Это то, что на самом деле отличает этот фильтр от других типов.

Еще одним важным методом, на который следует обратить внимание, является метод should Filter () . Мы возвращаем true здесь, так как мы хотим, чтобы фильтр был запущен в цепочке фильтров.

В готовом к производству приложении мы можем экстернализировать эту конфигурацию для большей гибкости.

Давайте подробнее рассмотрим run () , который вызывается всякий раз, когда работает наш фильтр.

4. Изменение тела ответа

Как уже говорилось ранее, Zuul находится между микросервисами и их клиентами. Следовательно, он может получить доступ к телу ответа и при необходимости изменить его перед передачей.

Например, мы можем прочитать тело ответа и зарегистрировать его содержимое:

@Override
public Object run() throws ZuulException {

    RequestContext context = RequestContext.getCurrentContext();
    try (final InputStream responseDataStream = context.getResponseDataStream()) {

        if(responseDataStream == null) {
            logger.info("BODY: {}", "");
            return null;
        }

        String responseData = CharStreams.toString(new InputStreamReader(responseDataStream, "UTF-8"));
        logger.info("BODY: {}", responseData);

        context.setResponseBody(responseData);
    }
    catch (Exception e) {
        throw new ZuulException(e, INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    return null;
}

Приведенный выше фрагмент показывает полную реализацию метода run() в фильтре журнала ответов , который мы создали ранее. Во-первых, мы получили экземпляр RequestContext . И из этого контекста мы смогли получить данные ответа InputStream в попытке построить resources.

Обратите внимание, что входной поток ответа может быть null, поэтому мы проверяем его. Это может быть связано с таймаутом обслуживания или другими неожиданными исключениями в микросервисе. В нашем случае мы просто регистрируем пустое тело ответа, когда это происходит.

В дальнейшем мы считываем входной поток в строку |, которую затем можем зарегистрировать.

Очень важно, что мы добавляем тело ответа обратно в контекст для обработки с помощью context.setResponseBody(responseData). Если мы пропустим этот шаг, мы получим IOException в следующих строках: java.io.IOException: Попытка чтения в закрытом потоке .

5. Заключение

В заключение, фильтры сообщений в Zuul предоставляют разработчикам возможность что-то сделать с ответом службы, прежде чем отправлять его клиенту.

Однако мы должны быть осторожны, чтобы случайно не раскрыть конфиденциальную информацию, которая может привести к нарушению.

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

Как обычно, исходный код доступен на GitHub .