獲取SpringCloud gateway響應的response的值,記錄踩坑

最近在作網關改造,想要經過Gateway過濾器獲取ResponseBody的值,查看了網上的帖子和官網內容:java

帖子:https://cloud.tencent.com/developer/article/1384111git

官網:https://github.com/spring-cloud/spring-cloud-gateway/blob/master/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactory.javagithub

但在實際操做中卻掉坑裏了,竟然不起做用,就是不進重寫但writeWith方法spring

 1 @Component
 2 @Order(-2)
 3 public class EncryptResponseBodyFilter implements GlobalFilter {
 4 
 5     @Override
 6     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
 7         ServerHttpResponse originalResponse = exchange.getResponse();
 8         DataBufferFactory bufferFactory = originalResponse.bufferFactory();
 9         ServerHttpResponseDecorator response = new ServerHttpResponseDecorator(originalResponse) {
10 
11             @Override
12             public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
13                 if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
14 
15                     Flux<? extends DataBuffer> fluxBody = Flux.from(body);
16                     return super.writeWith(fluxBody.map(dataBuffer -> {
17                         // probably should reuse buffers
18                         byte[] content = new byte[dataBuffer.readableByteCount()];
19                         dataBuffer.read(content);
20                         //釋放掉內存
21                         DataBufferUtils.release(dataBuffer);
22                         String s = new String(content, Charset.forName("UTF-8"));
23                         //TODO,s就是response的值,想修改、查看就隨意而爲了
24                         byte[] uppedContent = s.getBytes();
25                         return bufferFactory.wrap(uppedContent);
26                     }));
27                 }
28                 return super.writeWith(body);
29             }
30 
31             @Override
32             public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
33                 return writeWith(Flux.from(body)
34                         .flatMapSequential(p -> p));
35             }
36         };37         return chain.filter(exchange.mutate().response(response).build());
38     }

後來與帖子和官網代碼內容對比,只有Order的方式不一樣,就換了下實現Ordered重寫getOrder方法方式試試,結果出乎意料,竟然好用了!!!json

真的是絞盡腦汁啊,浪費了很多時間。。。。app

後來發現響應數據存在分段響應的問題:ide

參考:https://blog.csdn.net/fayeyiwang/article/details/9137// JSON響應數據拼接容器ui

private static Joiner joiner = Joiner.on(""); @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpResponse originalResponse = exchange.getResponse(); DataBufferFactory bufferFactory = originalResponse.bufferFactory(); ServerHttpResponseDecorator response = new ServerHttpResponseDecorator(originalResponse) { @Override public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) { if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) { // 獲取ContentType,判斷是否返回JSON格式數據
                String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR); if(StringUtils.isNotBlank(originalResponseContentType) && originalResponseContentType.contains("application/json")) { Flux<? extends DataBuffer> fluxBody = Flux.from(body); return super.writeWith(fluxBody.buffer().map(dataBuffers -> {//解決返回體分段傳輸
                      List<String> list = Lists.newArrayList(); dataBuffers.forEach(dataBuffer -> { try { byte[] content = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(content); DataBufferUtils.release(dataBuffer); list.add(new String(content, "utf-8")); } catch (Exception e) { logger.info("動態加載API加密規則失敗,失敗緣由:{}", Throwables.getStackTraceAsString(e)); } }); String responseData = joiner.join(list); // 二次處理(加密/過濾等)若是不須要作二次處理可直接跳過下行
                       responseData = beforeBodyWriteInternal(responseData, exchange.getRequest()); byte[] uppedContent = new String(responseData.getBytes(), Charset.forName("UTF-8")).getBytes(); originalResponse.getHeaders().setContentLength(uppedContent.length); return bufferFactory.wrap(uppedContent); })); } } return super.writeWith(body); } @Override public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) { return writeWith(Flux.from(body).flatMapSequential(p -> p));
} };
return chain.filter(exchange.mutate().response(response).build());}
相關文章
相關標籤/搜索