springgateway filter中如何根据exchange获取response的Content-Encoding

gateway从其他服务器获取的的响应有些是经过gzip压缩的,解析responsebody时不能直接获取需要解压
ServerHttpResponse originalResponse = exchange.getResponse();
originalResponse.getHeaders()获取不到任何数据

阅读 6k
1 个回答

会不会过滤器执行的时候不对,执行filter的时候,请求还没有结束,可以参考官网的修改reponse的filter

        public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {

                    Class inClass = config.getInClass();
                    Class outClass = config.getOutClass();

                    String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
                    HttpHeaders httpHeaders = new HttpHeaders();
                    //explicitly add it in this way instead of 'httpHeaders.setContentType(originalResponseContentType)'
                    //this will prevent exception in case of using non-standard media types like "Content-Type: image"
                    httpHeaders.add(HttpHeaders.CONTENT_TYPE, originalResponseContentType);
                    ResponseAdapter responseAdapter = new ResponseAdapter(body, httpHeaders);
                    DefaultClientResponse clientResponse = new DefaultClientResponse(responseAdapter, ExchangeStrategies.withDefaults());

                    //TODO: flux or mono
                    Mono modifiedBody = clientResponse.bodyToMono(inClass)
                            .flatMap(originalBody -> config.rewriteFunction.apply(exchange, originalBody));

                    BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, outClass);
                    CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, exchange.getResponse().getHeaders());
                    return bodyInserter.insert(outputMessage, new BodyInserterContext())
                            .then(Mono.defer(() -> {
                                long contentLength1 = getDelegate().getHeaders().getContentLength();
                                Flux<DataBuffer> messageBody = outputMessage.getBody();
                                //TODO: if (inputStream instanceof Mono) {
                                HttpHeaders headers = getDelegate().getHeaders();
                                if (/*headers.getContentLength() < 0 &&*/ !headers.containsKey(HttpHeaders.TRANSFER_ENCODING)) {
                                    messageBody = messageBody.doOnNext(data -> headers.setContentLength(data.readableByteCount()));
                                }
                                // }
                                //TODO: use isStreamingMediaType?
                                return getDelegate().writeWith(messageBody);
                            }));
                }

我看了下源码,官方也不是从exchange.getResponse.getHeaders中获取的头部,而是通过

String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);

获取的头部,然后新建的httpHeaders对象,不知道能不能通过Content-Type判断是否压缩的数据。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题