国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringCloud GateWay通過過濾器GatewayFilter修改請求或響應(yīng)內(nèi)容

這篇具有很好參考價值的文章主要介紹了SpringCloud GateWay通過過濾器GatewayFilter修改請求或響應(yīng)內(nèi)容。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Spring Cloud Gateway在有些場景中需要獲取request body內(nèi)容進行參數(shù)校驗或參數(shù)修改,我們通過在GatewayFilter中獲取請求內(nèi)容來獲取和修改請求體,下面我們就基于ServerWebExchange來實現(xiàn):

ServerWebExchange命名為服務(wù)網(wǎng)絡(luò)交換器,存放著重要的請求-響應(yīng)屬性、請求實例和響應(yīng)實例等等,有點像Context的角色,其中有兩個重要的接口方法:

   // 獲取ServerHttpRequest對象
    ServerHttpRequest getRequest();

    // 獲取ServerHttpResponse對象
    ServerHttpResponse getResponse();

創(chuàng)建一個GatewayFilter,必須實現(xiàn)Ordered接口,返回一個小于-1的order值,這是因為NettyWriteResponseFilter的order值為-1,我們需要覆蓋返回響應(yīng)體的邏輯,自定義的GlobalFilter必須比NettyWriteResponseFilter優(yōu)先執(zhí)行。

public class RequestGatewayFilter implements GatewayFilter, Ordered {
@Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();

        // 處理參數(shù)
        MediaType contentType = headers.getContentType();

        if (exchange.getRequest().getMethod().equals(HttpMethod.POST)) {
        //Content-type為“application/json”
            if (MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) {
                return readBody(exchange, chain);
            }
            //Content-type為“application/x-www-form-urlencoded”
            else if(MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(contentType)){
                GatewayContext gatewayContext = new GatewayContext();
                gatewayContext.setRequestHeaders(headers);
                gatewayContext.getAllRequestData().addAll(request.getQueryParams());
                exchange.getAttributes().put(GatewayContext.CACHE_GATEWAY_CONTEXT,gatewayContext);

                return readFormData(exchange, chain, gatewayContext);

            }
//Content-type為“multipart/form-data”
else if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
                GatewayContext gatewayContext = new GatewayContext();
                gatewayContext.setRequestHeaders(headers);
                gatewayContext.getAllRequestData().addAll(request.getQueryParams());
                exchange.getAttributes().put(GatewayContext.CACHE_GATEWAY_CONTEXT,gatewayContext);

                return readMultipartData(exchange, chain, gatewayContext);
            }
        } else {
            return readGetData(exchange, chain);
        }
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        return -2;
    }
}

處理content-type為application/json的方法:

/**
     * ReadJsonBody
     *
     * @param exchange
     * @param chain
     * @return
     */
    private Mono<Void> readBody(ServerWebExchange exchange, GatewayFilterChain chain) {
        /**
         * join the body
         */
        return DataBufferUtils.join(exchange.getRequest().getBody()).flatMap(dataBuffer -> {
            byte[] bytes = new byte[dataBuffer.readableByteCount()];
            dataBuffer.read(bytes);
            DataBufferUtils.release(dataBuffer);
           
            /**
             * validate request params or form data
             */
            Result checkResult = null;
            try {
                String bodyString = new String(bytes, "utf-8");
                Map bodyMap = JSONObject.parseObject(bodyString,Map.class);

                //校驗參數(shù)
                checkResult = validParam(exchange, bodyMap);
                if(checkResult.getCode()!=0){
                    return  errorInfo(exchange, checkResult.getCode(), checkResult.getMessage());
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
                DataBufferUtils.retain(buffer);
                return Mono.just(buffer);
            });
            /**
             * repackage ServerHttpRequest
             */
            ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) {
                @Override
                public Flux<DataBuffer> getBody() {
                    return cachedFlux;
                }
            };

            ServerHttpResponse originalResponse = exchange.getResponse();
            originalResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON);
            DataBufferFactory bufferFactory = originalResponse.bufferFactory();
            ServerHttpResponseDecorator response = buildResponse(originalResponse, bufferFactory, (Map)checkResult.getResult());
            /**
             * mutate exchage with new ServerHttpRequest
             */
            ServerWebExchange mutatedExchange = exchange.mutate().request(mutatedRequest).response(response).build();
            /**
             * read body string with default messageReaders
             */
            return ServerRequest.create(mutatedExchange, MESSAGE_READERS).bodyToMono(String.class)
                    .doOnNext(objectValue -> {
                        log.debug("[GatewayContext]Read JsonBody:{}", objectValue);
                    }).then(chain.filter(mutatedExchange));
         
        });
    }

處理content-type為application/x-www-form-urlencoded的方法:

/**
     * ReadFormData
     * @param exchange
     * @param chain
     * @return
     */
    private Mono<Void> readFormData(ServerWebExchange exchange, GatewayFilterChain chain, GatewayContext gatewayContext){
        HttpHeaders headers = exchange.getRequest().getHeaders();
        return exchange.getFormData().switchIfEmpty(
                        Mono.defer(() -> Mono.just(new LinkedMultiValueMap<>()))
                ).flatMap(formDataMap -> {
                    Charset charset = headers.getContentType().getCharset();
                    charset = charset == null? StandardCharsets.UTF_8:charset;
                    String charsetName = charset.name();
                    MultiValueMap<String, String> paramMap = exchange.getRequest().getQueryParams();
                    Map map = convertMap(paramMap);
                    /*
                     * formData is empty just return
                     */
                    if((null == formDataMap || formDataMap.isEmpty()) && (null == map || map.isEmpty())){
                        return chain.filter(exchange);
                    }
                    StringBuilder formDataBodyBuilder = new StringBuilder();
                    String entryKey;
                    List<String> entryValue;
                    try {
                        /*
                         * repackage form data
                         */
                        for (Map.Entry<String, List<String>> entry : formDataMap.entrySet()) {
                            entryKey = entry.getKey();
                            entryValue = entry.getValue();
                            if (entryValue.size() > 1) {
                                for(String value : entryValue){
                        formDataBodyBuilder.append(entryKey).append("=").append(value).append("&");
                                }
                            } else {
                                       formDataBodyBuilder.append(entryKey).append("=").append(entryValue.get(0)).append("&");
                            }
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    /*
                     * substring with the last char '&'
                     */
                    String formDataBodyString = "";
                    if(formDataBodyBuilder.length()>0){
                        formDataBodyString = formDataBodyBuilder.substring(0, formDataBodyBuilder.length() - 1);
                    }
                    /*
                     * get data bytes
                     */
                    byte[] bodyBytes =  formDataBodyString.getBytes(charset);
                    int contentLength = bodyBytes.length;
                    HttpHeaders httpHeaders = new HttpHeaders();
                    httpHeaders.putAll(exchange.getRequest().getHeaders());
                    httpHeaders.remove(HttpHeaders.CONTENT_LENGTH);
                    /*
                     * in case of content-length not matched
                     */
                    httpHeaders.setContentLength(contentLength);

                    /**
                     * validate request params or form data
                     */
                    Map<String, Object> bodyMap = StringUtils.isEmpty(formDataBodyString)?new HashMap<String, Object>():decodeFormBody(formDataBodyString);
                    Result checkResult = validParam(exchange, bodyMap);
                    if(checkResult.getCode()!=0){
                        return  errorInfo(exchange, checkResult.getCode(), checkResult.getMessage());
                    }
                    /*
                     * use BodyInserter to InsertFormData Body
                     */
                    BodyInserter<String, ReactiveHttpOutputMessage> bodyInserter = BodyInserters.fromObject(formDataBodyString);
                    CachedBodyOutputMessage cachedBodyOutputMessage = new CachedBodyOutputMessage(exchange, httpHeaders);
                    log.debug("[GatewayContext]Rewrite Form Data :{}",formDataBodyString);
                    return bodyInserter.insert(cachedBodyOutputMessage,  new BodyInserterContext())
                            .then(Mono.defer(() -> {
                                ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(
                                        exchange.getRequest()) {
                                    @Override
                                    public HttpHeaders getHeaders() {
                                        return httpHeaders;
                                    }
                                    @Override
                                    public Flux<DataBuffer> getBody() {
                                        return cachedBodyOutputMessage.getBody();
                                    }
                                };
                                ServerHttpResponse originalResponse = exchange.getResponse();
                                originalResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                                DataBufferFactory bufferFactory = originalResponse.bufferFactory();
                                ServerHttpResponseDecorator response = buildResponse(originalResponse, bufferFactory, (Map)checkResult.getResult());
                                return chain.filter(exchange.mutate().request(decorator).response(response).build());
                            }));

        });

    }

有時需要對返回的數(shù)據(jù)統(tǒng)一處理,那么可以通過封裝ServerHttpResponseDecorator進行處理,ServerHttpResponse裝飾器ServerHttpResponseDecorator,主要覆蓋寫入響應(yīng)體數(shù)據(jù)緩沖區(qū)的部分。

    private ServerHttpResponseDecorator buildResponse(ServerHttpResponse originalResponse, DataBufferFactory bufferFactory, Map result) {
        return new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                System.out.println("++++++++++++++++++++++++1");
                if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
                    Flux<? extends DataBuffer> fluxBody = Flux.from(body);
                    return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                        DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                        DataBuffer join = dataBufferFactory.join(dataBuffers);
                        byte[] content = new byte[join.readableByteCount()];
                        join.read(content);
                        DataBufferUtils.release(join);
                        // 流轉(zhuǎn)為字符串
                        String responseData = new String(content, Charsets.UTF_8);
                        System.out.println(responseData);

                        Map map = JSON.parseObject(responseData);
                        //處理返回的數(shù)據(jù)
                        
                        //To do

                       
                        byte[] uppedContent = responseData.getBytes(Charsets.UTF_8);
                        originalResponse.getHeaders().setContentLength(uppedContent.length);
                        return bufferFactory.wrap(uppedContent);
                    }));
                } else {
                    System.out.println("----------"+getStatusCode());
                }
                return super.writeWith(body);
            }

            @Override
            public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
                return writeWith(Flux.from(body).flatMapSequential(p -> p));
            }
        };
    }

更多接口、代碼工具、開發(fā)資源請訪問昂焱數(shù)據(jù):https://www.ayshuju.com文章來源地址http://www.zghlxwxcb.cn/news/detail-559622.html

到了這里,關(guān)于SpringCloud GateWay通過過濾器GatewayFilter修改請求或響應(yīng)內(nèi)容的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • SpringCloud - Spring Cloud 之 Gateway網(wǎng)關(guān),Route路由,Predicate 謂詞/斷言,F(xiàn)ilter 過濾器(十三)

    SpringCloud - Spring Cloud 之 Gateway網(wǎng)關(guān),Route路由,Predicate 謂詞/斷言,F(xiàn)ilter 過濾器(十三)

    閱讀本文前可先參考 ??????SpringCloud - Spring Cloud根/父項目,開發(fā)準備(二)_MinggeQingchun的博客-CSDN博客 SpringCloud - Spring Cloud 之 Gateway網(wǎng)關(guān)(十三)_MinggeQingchun的博客-CSDN博客 Web 有三大組件(監(jiān)聽器 過濾器 servlet),Spring Cloud GateWay 最主要的功能就是路由轉(zhuǎn)發(fā),而在定義

    2024年02月14日
    瀏覽(29)
  • 【Java】SpringCloud Gateway自定義過濾器中獲取ServerHttpRequest的body中的數(shù)據(jù)為NULL的問題

    【Java】SpringCloud Gateway自定義過濾器中獲取ServerHttpRequest的body中的數(shù)據(jù)為NULL的問題

    這個情況出現(xiàn)在,我需要進行驗證碼的校驗,因此用戶的請求首先需要被驗證碼過濾器校驗,而驗證碼過濾器不需要設(shè)定為全局過濾器,因此我就單純的把它設(shè)定為了一個局部過濾器,代碼如下 然后我進行請求的時候,json參數(shù)如下 然后請求經(jīng)過解析后會發(fā)現(xiàn),字符串居然是

    2024年02月09日
    瀏覽(17)
  • Gateway自定義過濾器——全局過濾器

    Gateway自定義過濾器——全局過濾器

    首先,我們要知道全局過濾器其實是特殊路由過濾器(特殊的GatewayFilter),會有條件地作用于所有路由。 為什么要自定義全局過濾器?就好比是看大門的保安大叔,平時主要是做好進出大門外來人員登記即可,但是因為新冠疫情,現(xiàn)在還需要給外來人員測量體溫等等。而已有的

    2024年02月16日
    瀏覽(23)
  • Gateway網(wǎng)關(guān) 全局過濾器

    Gateway網(wǎng)關(guān) 全局過濾器

    一、全局過濾器 全局過濾器GlobalFilter 全局過濾器的作用也是處理一切進入網(wǎng)關(guān)的請求和微服務(wù)響應(yīng),與GatewayFilter的作用一樣。 區(qū)別在于GatewayFilter通過配置定義,處理邏輯是固定的。 需求:定義全局過濾器,攔截請求,判斷請求的參數(shù)是否滿足下面條件: 參數(shù)中是否有au

    2024年02月07日
    瀏覽(23)
  • gateway-過濾器執(zhí)行順序

    請求進入網(wǎng)關(guān)會碰到三類過濾器:當前路由過濾器、DefaultFilter、GlobalFilter。 請求路由后,會將當前路由過濾器和DefaultFilter、GlobalFilter,合并到一個過濾器鏈(集合)中,排序后依次執(zhí)行每個過濾器 過濾器執(zhí)行順序 1.每一個過濾器都必須指定一個int類型的order值,order值越小

    2024年02月13日
    瀏覽(19)
  • 網(wǎng)關(guān)Gateway過濾器的使用

    網(wǎng)關(guān)Gateway過濾器的使用

    前言: 最近在學習微服務(wù)相關(guān)的知識,看了黑馬的相關(guān)課程,將關(guān)于Gateway過濾器的知識又總結(jié)了一些,希望能幫到各位小伙兒們以及加深下自己的印象?? 如果文章有什么需要改進的地方還請大佬多多指教?? 小威先感謝大家的支持了?? Gateway網(wǎng)關(guān)的過濾器分為兩種,一種是

    2023年04月09日
    瀏覽(23)
  • gateway之過濾器(Filter)詳解

    gateway之過濾器(Filter)詳解

    在Spring Cloud中,過濾器(Filter)是一種關(guān)鍵的組件,用于在微服務(wù)架構(gòu)中處理和轉(zhuǎn)換傳入請求以及傳出響應(yīng)。過濾器位于服務(wù)網(wǎng)關(guān)或代理中,并通過攔截請求和響應(yīng)流量來提供各種功能。 過濾器在請求的不同生命周期階段執(zhí)行特定的操作,例如鑒權(quán)、認證、請求轉(zhuǎn)發(fā)、限流、

    2024年02月05日
    瀏覽(20)
  • Spring Cloud Gateway 過濾器

    Spring Cloud Gateway 過濾器

    Spring Cloud Gateway 過濾器的種類有30多種。 官文文檔地址: Spring Cloud Gateway https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories Spring Cloud Gateway大體可以分為下面兩種類型的過濾器: 1、內(nèi)置的過濾器 ? ? ? ? 1.1、內(nèi)置的局部過濾器 ? ? ? ? 1.2、內(nèi)置的全

    2024年03月28日
    瀏覽(21)
  • gateway過濾器沒生效,特殊原因

    gateway過濾器沒生效,特殊原因

    看這邊文章的前提,你要會gateway,知道過濾器怎么配置? 直接來看過濾器,局部過濾器 再來看配置 請求路徑 http://127.0.0.1:8080/appframework/services/catalog/catalogSpecials.json?pageindex=1pagesize=10pkid=d9873700ef7e42b3b8f4e782f345975b 看起來確實沒什么問題 注意: 我這里還有個應(yīng)用,就是網(wǎng)關(guān)轉(zhuǎn)

    2024年02月14日
    瀏覽(21)
  • Spring Cloud Gateway 過濾器詳解

    Spring Cloud Gateway 過濾器詳解

    Spring Cloud Gateway根據(jù)作用范圍劃分為:GatewayFilter和GlobalFilter 由filter工作流程點,可以知道filter有著非常重要的作用,在“pre”類型的過濾器可以做參數(shù)校驗、權(quán)限校驗、流量監(jiān)控、日志輸出、協(xié)議轉(zhuǎn)換等,在“post”類型的過濾器中可以做響應(yīng)內(nèi)容、響應(yīng)頭的修改,日志的輸

    2023年04月08日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包