Как сделать фильтр пост-соответствия в webflux? - PullRequest
0 голосов
/ 28 мая 2018

Как мы знаем, в Джерси у нас есть фильтр предварительного сопоставления и фильтр после сопоставления.

Мне интересно, как я могу получить подобное поведение с WebFilter в приложении webflux.

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

Мой фильтр подобен этому (скопирован из фильтра метрик в приводе пружины):

@Component
@Order(100)
public class AppFilter1 implements WebFilter {

@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

    return chain.filter(exchange).compose((call) -> filter(exchange, call));
}

private Publisher<Void> filter(ServerWebExchange exchange, Mono<Void> call) {

    System.out.println("Start AppFilter1 in thread:" + Thread.currentThread().getId() + "..........");
    ServerHttpResponse response = exchange.getResponse();
    return call.doOnSuccess((done) -> success(exchange)).doOnError((cause) -> {
        if (response.isCommitted()) {
            error(exchange, cause);
        } else {
            response.beforeCommit(() -> {
                error(exchange, cause);
                return Mono.empty();
            });
        }
    });
}

private void success(ServerWebExchange exchange) {

    System.out.println("End AppFilter1 in thread:" + Thread.currentThread().getId() + "..............");

}

private void error(ServerWebExchange exchange, Throwable cause) {
    System.out.println("End AppFilter1 with Error in thread:" + Thread.currentThread().getId() + "...............");
}

}

Добавить мой контроллер, как:

@RestController
public class ExampleController {

@GetMapping("/example")
public String example() {
    System.out.println("Example in thread:" + Thread.currentThread().getId());
    return "Example";
}
}

Что я вижу, так это то, что фильтр будет выполняться точно, независимо от того, получаю ли я доступ к / примеру или / notexist

На самом деле я бы хотел, чтобы мой фильтр выполнял пост-сопоставление, выполняемый только для /example.

Чтобы быть более точным, я бы хотел видеть вывод консоли для / example:

Start AppFilter1 in thread:....
Example in thread:.....
End AppFilter1 in thread:....

и для несоответствующего ресурса, такого как / notexist, консольный вывод вообще отсутствует.

Спасибо

Леон

1 Ответ

0 голосов
/ 29 мая 2018

Класс Spring WebFlux WebFilter не работает на том же уровне, что и фильтры предварительного / последующего сопоставления в Джерси.На самом деле он ближе к сервлет-фильтру.

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

Поскольку вы находитесь здесь на уровне HTTP, вы можете просто проверить путь запроса и проверить, не является ли статус ответа «404 Not Found».

Поскольку ваш вопрос не дает достаточной информации о том, что выздесь мы пытаемся достичь (бизнес-логика? аутентификация? регистрация? трассировка? любая операция, связанная с вводом-выводом?), я не могу сказать больше о выборе оператора Reactor.

Если бы выподобно фильтру, который работает только с ресурсами (как в ресурсах Джерси), WebFilter не является правильным выбором, поскольку он работает на более низком уровне (все обмены HTTP).Я не думаю, что есть инфраструктура для этого в Spring Framework.Не стесняйтесь открывать запрос на улучшение в Spring Framework (на этот раз предоставив достаточно подробную информацию о вашем сценарии использования).

...