最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

gateway網(wǎng)關(guān)接口請(qǐng)求的校驗(yàn)方式

 更新時(shí)間:2021年07月15日 11:41:37   作者:錦瑟思年華  
這篇文章主要介紹了gateway網(wǎng)關(guān)接口請(qǐng)求的校驗(yàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

gateway網(wǎng)關(guān)token的校驗(yàn)

再加入gateway網(wǎng)關(guān)之后,我們?cè)诤笈_(tái)服務(wù)的許多校驗(yàn)操作都可以移動(dòng)到gateway網(wǎng)關(guān), 今天我就來說一下怎么校驗(yàn)請(qǐng)求攜帶的token。

首先我們需要編寫一個(gè)局部過濾器

繼承AbstractGatewayFilterFactory如下

然后在apply方法中實(shí)現(xiàn)自己要校驗(yàn)的邏輯,所有的請(qǐng)求參數(shù)或者token都可以通過request獲取。 驗(yàn)證失敗我在catch捕捉異常, 然后將異常信息返回給前端請(qǐng)求,

返回信息的異常處理是這樣的

e.printStackTrace();
ServerHttpResponse response = exchange.getResponse();
JSONObject message = new JSONObject();
message.put("status", -1);
message.put("data", e.getMessage());
byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(bits);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
//指定編碼,否則在瀏覽器中會(huì)中文亂碼
response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
return response.writeWith(Mono.just(buffer));

狀態(tài)碼根據(jù)需求自己定義,異常信息就可以放回給前端請(qǐng)求。

至于校驗(yàn)通過,就直接放行即可

chain.filter(exchange);

如果還需要修改返回的路徑請(qǐng)求可以這樣

 // 修改路徑
            String newPath ="/test/" + request.getPath();
            ServerHttpRequest newRequest = request.mutate()
                    .path(newPath)
                    .build();
            exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
            //放行
            return chain.filter(exchange.mutate()
                    .request(newRequest).build());

以上就是過濾器的編寫, 然后就是路由的配置,我是在yml文件中配置

 routes:
        - id: token_routh
          uri: lb://test-service
          order: 0
          predicates:
            - Path=/test/**
          filters:
            # 去除/test
            - StripPrefix=1
            - TokenApi

filters下面的TokenApi對(duì)應(yīng)的過濾器就是剛剛編寫的過濾器,以上就完成了 對(duì)指定接口校驗(yàn)的功能。

spring cloud gateway網(wǎng)關(guān)請(qǐng)求處理過程

一、網(wǎng)關(guān)請(qǐng)求處理過程

  

客戶端向Spring Cloud Gateway發(fā)出請(qǐng)求。如果網(wǎng)關(guān)處理程序映射確定請(qǐng)求與路由匹配,則將其發(fā)送到網(wǎng)關(guān)Web處理程序。此處理程序運(yùn)行通過特定于請(qǐng)求的過濾器鏈發(fā)送請(qǐng)求。濾波器被虛線劃分的原因是濾波器可以在發(fā)送代理請(qǐng)求之前或之后執(zhí)行邏輯。執(zhí)行所有“pre”過濾器邏輯,然后進(jìn)行代理請(qǐng)求。在發(fā)出代理請(qǐng)求之后,執(zhí)行“post”過濾器邏輯。

在沒有端口的路由中定義的URI將分別為HTTP和HTTPS URI獲取默認(rèn)端口設(shè)置為80和443。

  • DispatcherHandler:所有請(qǐng)求的調(diào)度器,負(fù)載請(qǐng)求分發(fā)
  • RoutePredicateHandlerMapping:路由謂語匹配器,用于路由的查找,以及找到路由后返回對(duì)應(yīng)的WebHandler,DispatcherHandler會(huì)依次遍歷HandlerMapping集合進(jìn)行處理
  • FilteringWebHandler: 使用Filter鏈表處理請(qǐng)求的WebHandler,RoutePredicateHandlerMapping找到路由后返回對(duì)應(yīng)的FilteringWebHandler對(duì)請(qǐng)求進(jìn)行處理,F(xiàn)ilteringWebHandler負(fù)責(zé)組裝Filter鏈表并調(diào)用鏈表處理請(qǐng)求。

1.1、DispatcherHandler分發(fā)處理

在import org.springframework.web.reactive.DispatcherHandler;類中核心方法handle

public Mono<Void> handle(ServerWebExchange exchange) {
        if (logger.isDebugEnabled()) {
            ServerHttpRequest request = exchange.getRequest();
            logger.debug("Processing " + request.getMethodValue() + " request for [" + request.getURI() + "]");
        }
        //校驗(yàn)handlerMapping集合是否為空
        //依次遍歷handlerMapping集合進(jìn)行請(qǐng)求處理
        //通過mapping獲取mapping對(duì)應(yīng)的handler,調(diào)用handler處理
        return this.handlerMappings == null ? Mono.error(HANDLER_NOT_FOUND_EXCEPTION) : Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
            return mapping.getHandler(exchange);
        }).next().switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION)).flatMap((handler) -> {
            return this.invokeHandler(exchange, handler);
        }).flatMap((result) -> {
            return this.handleResult(exchange, result);
        });
    }

DispatcherHandler的handler執(zhí)行順序

  • 校驗(yàn)handlerMapping
  • 遍歷Mapping獲取mapping對(duì)應(yīng)的handler(此處會(huì)找到gateway對(duì)應(yīng)的 RoutePredicateHandlerMapping,并通過 RoutePredicateHandlerMapping獲取handler(FilteringWebHandler))
  • 通過handler對(duì)應(yīng)的HandlerAdapter對(duì)handler進(jìn)行調(diào)用(gateway使用的 SimpleHandlerAdapter) 即 FilteringWebHandler與SimpleHandlerAdapter對(duì)應(yīng)

其中SimpleHandlerAdapter中handler實(shí)現(xiàn)

    public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
        WebHandler webHandler = (WebHandler)handler;
        Mono<Void> mono = webHandler.handle(exchange);
        return mono.then(Mono.empty());
    }

1.2、RoutePredicateHandlerMapping 路由謂詞處理映射

public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
    private final FilteringWebHandler webHandler;
    private final RouteLocator routeLocator;
    public RoutePredicateHandlerMapping(FilteringWebHandler webHandler, RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties) {
        this.webHandler = webHandler;
        this.routeLocator = routeLocator;
        //設(shè)置排序字段1,此處的目的是Spring Cloud Gateway 的 GatewayWebfluxEndpoint 提供 HTTP API ,不需要經(jīng)過網(wǎng)關(guān)
        //它通過 RequestMappingHandlerMapping 進(jìn)行請(qǐng)求匹配處理。RequestMappingHandlerMapping 的 order = 0 ,
        // 需要排在 RoutePredicateHandlerMapping 前面。所有,RoutePredicateHandlerMapping 設(shè)置 order = 1 。
        this.setOrder(1);
        this.setCorsConfigurations(globalCorsProperties.getCorsConfigurations());
    }
    protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
        //設(shè)置mapping到上下文環(huán)境
        exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_HANDLER_MAPPER_ATTR, this.getClass().getSimpleName());
        // 查找路由
        return this.lookupRoute(exchange).flatMap((r) -> {
            exchange.getAttributes().remove(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Mapping [" + this.getExchangeDesc(exchange) + "] to " + r);
            }
            //將找到的路由信息設(shè)置到上下文環(huán)境中
            exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR, r);
            //返回mapping對(duì)應(yīng)的WebHandler即FilteringWebHandler
            return Mono.just(this.webHandler);
        }).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
            //當(dāng)前未找到路由時(shí)返回空,并移除GATEWAY_PREDICATE_ROUTE_ATTR
            exchange.getAttributes().remove(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("No RouteDefinition found for [" + this.getExchangeDesc(exchange) + "]");
            }
        })));
    }
    protected CorsConfiguration getCorsConfiguration(Object handler, ServerWebExchange exchange) {
        return super.getCorsConfiguration(handler, exchange);
    }
    private String getExchangeDesc(ServerWebExchange exchange) {
        StringBuilder out = new StringBuilder();
        out.append("Exchange: ");
        out.append(exchange.getRequest().getMethod());
        out.append(" ");
        out.append(exchange.getRequest().getURI());
        return out.toString();
    }
    protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
        //通過路由定位器獲取路由信息
        return this.routeLocator.getRoutes().concatMap((route) -> {
            return Mono.just(route).filterWhen((r) -> {
                exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
                return (Publisher)r.getPredicate().apply(exchange);
            }).doOnError((e) -> {
                this.logger.error("Error applying predicate for route: " + route.getId(), e);
            }).onErrorResume((e) -> {
                return Mono.empty();
            });
        }).next().map((route) -> {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Route matched: " + route.getId());
            }
            this.validateRoute(route, exchange);
            return route;
        });
    }
    protected void validateRoute(Route route, ServerWebExchange exchange) {
    }
}

RoutePredicateHandlerMapping的執(zhí)行順序

  • 通過路由定位器獲取全部路由(RouteLocator)
  • 通過路由的謂語(Predicate)過濾掉不可用的路由信息
  • 查找到路由信息后將路由信息設(shè)置當(dāng)上下文環(huán)境中(GATEWAY_ROUTE_ATTR)
  • 返回gatway自定的webhandler(FilteringWebHandler)

備注:

在構(gòu)建方法中看到setOrder(1);作用:Spring Cloud Gateway 的 GatewayWebfluxEndpoint 提供 HTTP API ,不需要經(jīng)過網(wǎng)關(guān)。

通過 RequestMappingHandlerMapping 進(jìn)行請(qǐng)求匹配處理。RequestMappingHandlerMapping 的 order = 0 ,需要排在 RoutePredicateHandlerMapping 前面,所以設(shè)置 order = 1 。

1.3、FilteringWebHandler 過濾web請(qǐng)求處理

/**
 * 通過過濾器處理web請(qǐng)求的處理器
 */
public class FilteringWebHandler implements WebHandler {
    protected static final Log logger = LogFactory.getLog(FilteringWebHandler.class);
    /**
     * 全局過濾器
     */
    private final List<GatewayFilter> globalFilters;
    public FilteringWebHandler(List<GlobalFilter> globalFilters) {
        this.globalFilters = loadFilters(globalFilters);
    }
    /**
     * 包裝加載全局的過濾器,將全局過濾器包裝成GatewayFilter
     */
    private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
        return filters.stream()
                .map(filter -> {
                    //將所有的全局過濾器包裝成網(wǎng)關(guān)過濾器
                    GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
                    //判斷全局過濾器是否實(shí)現(xiàn)了可排序接口
                    if (filter instanceof Ordered) {
                        int order = ((Ordered) filter).getOrder();
                        //包裝成可排序的網(wǎng)關(guān)過濾器
                        return new OrderedGatewayFilter(gatewayFilter, order);
                    }
                    return gatewayFilter;
                }).collect(Collectors.toList());
    }
    @Override
    public Mono<Void> handle(ServerWebExchange exchange) {
        //獲取請(qǐng)求上下文設(shè)置的路由實(shí)例
        Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
        //獲取路由定義下的網(wǎng)關(guān)過濾器集合
        List<GatewayFilter> gatewayFilters = route.getFilters();
        //組合全局的過濾器與路由配置的過濾器
        List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
        //添加路由配置過濾器到集合尾部
        combined.addAll(gatewayFilters);
        //對(duì)過濾器進(jìn)行排序
        AnnotationAwareOrderComparator.sort(combined);
        logger.debug("Sorted gatewayFilterFactories: "+ combined);
        //創(chuàng)建過濾器鏈表對(duì)其進(jìn)行鏈?zhǔn)秸{(diào)用
        return new DefaultGatewayFilterChain(combined).filter(exchange);
    }
}

FilteringWebHandler的執(zhí)行順序

  • 構(gòu)建一個(gè)包含全局過濾器的集合(combined)
  • 獲取上下中的路由信息GATEWAY_ROUTE_ATTR
  • 將路由里的過濾器添加到集合中(combined)
  • 對(duì)過濾器集合進(jìn)行排序操作
  • 通過過濾器集合組裝過濾器鏈表,并進(jìn)行調(diào)用(DefaultGatewayFilterChain與Servlet中的FilterChain與原理是一致的)
  • 通過過濾器來處理請(qǐng)求到具體業(yè)務(wù)服務(wù)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java Kafka 消費(fèi)積壓監(jiān)控的示例代碼

    Java Kafka 消費(fèi)積壓監(jiān)控的示例代碼

    這篇文章主要介紹了Java Kafka 消費(fèi)積壓監(jiān)控,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • Idea配置Maven阿里云鏡像加速的實(shí)現(xiàn)

    Idea配置Maven阿里云鏡像加速的實(shí)現(xiàn)

    這篇文章主要介紹了Idea配置Maven阿里云鏡像加速的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • spring配置定時(shí)任務(wù)的幾種方式總結(jié)

    spring配置定時(shí)任務(wù)的幾種方式總結(jié)

    這篇文章主要介紹了spring配置定時(shí)任務(wù)的幾種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java并發(fā)編程工具類JUC之ArrayBlockingQueue

    java并發(fā)編程工具類JUC之ArrayBlockingQueue

    類ArrayBlockingQueue是BlockingQueue接口的實(shí)現(xiàn)類,它是有界的阻塞隊(duì)列,內(nèi)部使用數(shù)組存儲(chǔ)隊(duì)列元素,通過代碼給大家說明如何初始化一個(gè)ArrayBlockingQueue,并向其中添加一個(gè)對(duì)象,對(duì)java并發(fā)編程工具類ArrayBlockingQueue相關(guān)知識(shí)感興趣的朋友一起看看吧
    2021-05-05
  • SpringBoot+Mybatis分頁插件PageHelper實(shí)現(xiàn)分頁效果

    SpringBoot+Mybatis分頁插件PageHelper實(shí)現(xiàn)分頁效果

    這篇文章主要介紹了SpringBoot+Mybatis實(shí)現(xiàn)分頁效果,本案例是采用Mybatis分頁插件PageHelper實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • Java解析Excel內(nèi)容的方法

    Java解析Excel內(nèi)容的方法

    這篇文章主要介紹了Java解析Excel內(nèi)容的方法,實(shí)例分析了java解析excel文件的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • Java開發(fā)之spring security實(shí)現(xiàn)基于MongoDB的認(rèn)證功能

    Java開發(fā)之spring security實(shí)現(xiàn)基于MongoDB的認(rèn)證功能

    這篇文章主要介紹了Java開發(fā)之spring security實(shí)現(xiàn)基于MongoDB的認(rèn)證功能,結(jié)合實(shí)例形式分析了spring security在非JDBC環(huán)境下的自定義認(rèn)證服務(wù)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-11-11
  • Java中的static關(guān)鍵字深入理解

    Java中的static關(guān)鍵字深入理解

    這篇文章主要介紹了Java中的static關(guān)鍵字深入理解,文字和代碼列舉了實(shí)際例子,有感興趣的同學(xué)可以研究下
    2021-03-03
  • java.net.SocketTimeoutException: Read timed out異常的解決

    java.net.SocketTimeoutException: Read timed o

    本文主要介紹了java.net.SocketTimeoutException: Read timed out異常的解決,可能是因?yàn)榫W(wǎng)絡(luò)延遲、服務(wù)器響應(yīng)慢或連接不穩(wěn)定等原因造成的,下面就一起來介紹一下,感興趣的可以了解一下
    2024-05-05
  • IntelliJ IDEA 2019.2 x64的安裝、應(yīng)用與簡單配置(圖文)

    IntelliJ IDEA 2019.2 x64的安裝、應(yīng)用與簡單配置(圖文)

    這篇文章主要介紹了IntelliJ IDEA 2019.2 x64的安裝、應(yīng)用與簡單配置,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10

最新評(píng)論

临沧市| 周至县| 赤水市| 舒城县| 古交市| 来安县| 高邮市| 德保县| 丽江市| 依安县| 高青县| 古田县| 景德镇市| 德清县| 安丘市| 将乐县| 维西| 禄丰县| 江永县| 乌拉特后旗| 盐源县| 莱芜市| 顺义区| 六盘水市| 虞城县| 琼中| 景德镇市| 甘泉县| 沅江市| 桃园县| 龙川县| 格尔木市| 山东省| 綦江县| 靖宇县| 临泉县| 肇庆市| 宁陕县| 合作市| 齐齐哈尔市| 巫溪县|