激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

香港云服务器
服務(wù)器之家 - 編程語言 - Java教程 - spring cloud gateway中如何讀取請求參數(shù)

spring cloud gateway中如何讀取請求參數(shù)

2021-10-11 09:35影落離風 Java教程

這篇文章主要介紹了spring cloud gateway中如何讀取請求參數(shù)的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

spring cloud gateway讀取請求參數(shù)

1. 我的版本:

  • spring-cloud:Hoxton.RELEASE
  • spring-boot:2.2.2.RELEASE
  • spring-cloud-starter-gateway

2. 請求日志

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
 
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;
 
/**
 * @author MinWeikai
 * @date 2019-12-20 18:09:39
 */
@Slf4j
@Component
public class LoggerFilter implements GlobalFilter {
 
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String method = request.getMethodValue();
 
        if (HttpMethod.POST.matches(method)) {
            return DataBufferUtils.join(exchange.getRequest().getBody())
                    .flatMap(dataBuffer -> {
                        byte[] bytes = new byte[dataBuffer.readableByteCount()];
                        dataBuffer.read(bytes);
                        String bodyString = new String(bytes, StandardCharsets.UTF_8);
                        logtrace(exchange, bodyString);
                        exchange.getAttributes().put("POST_BODY", bodyString);
                        DataBufferUtils.release(dataBuffer);
                        Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                            DataBuffer buffer = exchange.getResponse().bufferFactory()
                                    .wrap(bytes);
                            return Mono.just(buffer);
                        });
 
                        ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                                exchange.getRequest()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                return cachedFlux;
                            }
                        };
                        return chain.filter(exchange.mutate().request(mutatedRequest)
                                .build());
                    });
        } else if (HttpMethod.GET.matches(method)) {
            Map m = request.getQueryParams();
            logtrace(exchange, m.toString());
        }
        return chain.filter(exchange);
    }
 
    /**
     * 日志信息
     *
     * @param exchange
     * @param param    請求參數(shù)
     */
    private void logtrace(ServerWebExchange exchange, String param) {
        ServerHttpRequest serverHttpRequest = exchange.getRequest();
        String path = serverHttpRequest.getURI().getPath();
        String method = serverHttpRequest.getMethodValue();
        String headers = serverHttpRequest.getHeaders().entrySet()
                .stream()
                .map(entry -> "            " + entry.getKey() + ": [" + String.join(";", entry.getValue()) + "]")
                .collect(Collectors.joining("\n"));
        log.info("\n" + "----------------             ----------------             ---------------->>\n" +
                        "HttpMethod : {}\n" +
                        "Uri        : {}\n" +
                        "Param      : {}\n" +
                        "Headers    : \n" +
                        "{}\n" +
                        "\"<<----------------             ----------------             ----------------"
                , method, path, param, headers);
    }
 
}

3. 測試輸出,我這邊測試沒有問題,日志正常輸出

spring cloud gateway中如何讀取請求參數(shù)

gateway網(wǎng)關(guān)轉(zhuǎn)發(fā)請求添加參數(shù)

在繼承AbstractGatewayFilterFactory的過濾器中

GET請求添加參數(shù)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 參考api文檔中GatewapFilter中“添加請求參數(shù)攔截器”:AddRequestParameterGatewayFilterFactory.java
 
            //記錄日志
            //logger.info("全局參數(shù)處理: {} url:{} 參數(shù):{}",method.toString(),serverHttpRequest.getURI().getRawPath(),newRequestQueryParams.toString());
            // 獲取原參數(shù)
            URI uri = serverHttpRequest.getURI();
            StringBuilder query = new StringBuilder();
            String originalQuery = uri.getRawQuery();
            if (org.springframework.util.StringUtils.hasText(originalQuery)) {
                query.append(originalQuery);
                if (originalQuery.charAt(originalQuery.length() - 1) != '&') {
                    query.append('&');
                }
            }
            // 添加查詢參數(shù)
            query.append(ServiceConstants.COMMON_PARAMETER_ENTERPRISEID+"="+authenticationVO.getEnterpriseId()
                    +"&"+ServiceConstants.COMMON_PARAMETER_USERID+"="+authenticationVO.getUserId());
 
            // 替換查詢參數(shù)
            URI newUri = UriComponentsBuilder.fromUri(uri)
                    .replaceQuery(query.toString())
                    .build(true)
                    .toUri();
 
            ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
            return chain.filter(exchange.mutate().request(request).build());

POST請求添加參數(shù)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//從請求里獲取Post請求體
                    String bodyStr = resolveBodyFromRequest(serverHttpRequest);
                    String userId = "123";
// 這種處理方式,必須保證post請求時,原始post表單必須有數(shù)據(jù)過來,不然會報錯
                    if (StringUtils.isEmpty(bodyStr)) {
                        logger.error("請求異常:{} POST請求必須傳遞參數(shù)", serverHttpRequest.getURI().getRawPath());
                        ServerHttpResponse response = exchange.getResponse();
                        response.setStatusCode(HttpStatus.BAD_REQUEST);
                        return response.setComplete();
                    }
                    //application/x-www-form-urlencoded和application/json才添加參數(shù)
                    //其他上傳文件之類的,不做參數(shù)處理,因為文件流添加參數(shù),文件原格式就會出問題了
                   /* if (MediaType.APPLICATION_FORM_URLENCODED_VALUE.equalsIgnoreCase(contentType)) {
                        // 普通鍵值對,增加參數(shù)
                        bodyStr = String.format(bodyStr+"&%s=%s&%s=%s",ServiceConstants.COMMON_PARAMETER_ENTERPRISEID,authenticationVO.getEnterpriseId()
                                ,ServiceConstants.COMMON_PARAMETER_USERID,authenticationVO.getUserId());
                    }*/
                    // 新增body參數(shù)
                    if (MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType)) {
                        JSONObject jsonObject = new JSONObject(bodyStr);
                        jsonObject.put("userId", userId);
                        bodyStr = jsonObject.toString();
                    }
                    //記錄日志
                    logger.info("全局參數(shù)處理: {} url:{} 參數(shù):{}", method.toString(), serverHttpRequest.getURI().getRawPath(), bodyStr);
                    //下面的將請求體再次封裝寫回到request里,傳到下一級,否則,由于請求體已被消費,后續(xù)的服務(wù)將取不到值
                    URI uri = serverHttpRequest.getURI();
                    URI newUri = UriComponentsBuilder.fromUri(uri).build(true).toUri();
                    ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
                    DataBuffer bodyDataBuffer = stringBuffer(bodyStr);
                    Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
                    // 定義新的消息頭
                    HttpHeaders headers = new HttpHeaders();
                    headers.putAll(exchange.getRequest().getHeaders());
                    // 添加消息頭
//                    headers.set(ServiceConstants.SHIRO_SESSION_PRINCIPALS,GsonUtils.toJson(authenticationVO));
                    // 由于修改了傳遞參數(shù),需要重新設(shè)置CONTENT_LENGTH,長度是字節(jié)長度,不是字符串長度
                    int length = bodyStr.getBytes().length;
                    headers.remove(HttpHeaders.CONTENT_LENGTH);
                    headers.setContentLength(length);
                    // 設(shè)置CONTENT_TYPE
                    if (StringUtils.isEmpty(contentType)) {
                        headers.set(HttpHeaders.CONTENT_TYPE, contentType);
                    }
                    // 由于post的body只能訂閱一次,由于上面代碼中已經(jīng)訂閱過一次body。所以要再次封裝請求到request才行,不然會報錯請求已經(jīng)訂閱過
                    request = new ServerHttpRequestDecorator(request) {
                        @Override
                        public HttpHeaders getHeaders() {
                            long contentLength = headers.getContentLength();
                            HttpHeaders httpHeaders = new HttpHeaders();
                            httpHeaders.putAll(super.getHeaders());
                            if (contentLength > 0) {
                                httpHeaders.setContentLength(contentLength);
                            } else {
                                // TODO: this causes a 'HTTP/1.1 411 Length Required' on httpbin.org
                                httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
                            }
                            return httpHeaders;
                        }
                        @Override
                        public Flux<DataBuffer> getBody() {
                            return bodyFlux;
                        }
                    };
                    //封裝request,傳給下一級
                    request.mutate().header(HttpHeaders.CONTENT_LENGTH, Integer.toString(bodyStr.length()));
                    return chain.filter(exchange.mutate().request(request).build());
   /**
     * 從Flux<DataBuffer>中獲取字符串的方法
     * @return 請求體
     */
    private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
        //獲取請求體
        Flux<DataBuffer> body = serverHttpRequest.getBody();
        AtomicReference<String> bodyRef = new AtomicReference<>();
        body.subscribe(buffer -> {
            CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
            DataBufferUtils.release(buffer);
            bodyRef.set(charBuffer.toString());
        });
        //獲取request body
        return bodyRef.get();
    }
?
1
2
3
4
5
6
7
8
9
10
11
12
/**
* 字符串轉(zhuǎn)DataBuffer
* @param value
* @return
*/
private DataBuffer stringBuffer(String value) {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes);
return buffer;
}

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/weixin_41187876/article/details/103637035

延伸 · 閱讀

精彩推薦
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java實現(xiàn)搶紅包功能

    Java實現(xiàn)搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現(xiàn)搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關(guān)于小米推送Java代碼,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩(wěn)中求8032021-07-12
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發(fā)項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發(fā)現(xiàn)了對于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關(guān)于Java8中S...

    阿杜7472021-02-04
  • Java教程Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經(jīng)有好久沒有升過級了。升級完畢重啟之后,突然發(fā)現(xiàn)好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程xml與Java對象的轉(zhuǎn)換詳解

    xml與Java對象的轉(zhuǎn)換詳解

    這篇文章主要介紹了xml與Java對象的轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
2876
主站蜘蛛池模板: 爱操在线| 免看黄大片aa | 久久超| 色婷婷久久一区二区 | 亚洲成人涩涩 | 日韩在线观看视频一区 | 91精品国产乱码久久桃 | 免费午夜视频在线观看 | 91精品国产乱码久久桃 | 黄色av网站在线观看 | 黄网站在线播放视频免费观看 | gril hd | 精品国产96亚洲一区二区三区 | 视频一区二区三区中文字幕 | 成人久久久精品国产乱码一区二区 | 精品国产96亚洲一区二区三区 | 特级黄色影院 | 牛牛碰在线 | 成人午夜影院 | 99视频网 | 黄色免费在线网站 | 91免费无限观看 | 欧美日韩精品一二三区 | 久久国产不卡 | 成人不卡 | 一级毛片免费大片 | 成人福利视频在线观看 | 久久成人黄色 | 黄色成人av在线 | 久久96国产精品久久久 | 欧美人一级淫片a免费播放 久久久久久久久91 国产99久久久久久免费看 | 日韩美女电影 | 黄色av网站免费 | 欧美一级三级在线观看 | 爽爽视频免费看 | 毛片在线播放视频 | 亚洲一区在线免费视频 | 成人做爰s片免费看网站 | 曰批全过程120分钟免费69 | 国产做爰 | 久久国产精品免费视频 |