獲取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());}
相關文章
相關標籤/搜索