How to get response body in Zuul post filter?

前端 未结 6 1222
时光说笑
时光说笑 2021-01-04 06:55

How it is possible to read a response body while using Zuul as a proxy in post filter?

I am trying to call the code like this:

@Componen         


        
相关标签:
6条回答
  • 2021-01-04 07:39

    As you can see in this example, you have two methods available to extract the response body:

    1- ctx.getResponseBody();

    2- ctx.getResponseDataStream();

    You have to check which one is not null and use that one.

    0 讨论(0)
  • 2021-01-04 07:41

    I've managed to overcome this. The solution consists of 4 steps:

    1. Read ctx.getResponseDataStream() into a ByteArrayOutputStream
    2. Copy OutputStream to 2 InputStreams.
    3. Use one of it for your custom purposes.
    4. Use the second to reassign to context: context.setResponseBody(inputStream)
      • reading stream from point 1 would cause that the stream cannot be read again, so this way you're passing a new fresh stream that wasn't read yet
    0 讨论(0)
  • 2021-01-04 07:41

    Thanks for suggestion, this is the code I used that works.

    try (final InputStream responseDataStream = ctx.getResponseDataStream()) {
       final String responseData = CharStreams.toString(new InputStreamReader(responseDataStream, "UTF-8"));
       ctx.setResponseBody(responseData);
    } catch (IOException e) {
       logger.warn("Error reading body",e);
    }
    
    0 讨论(0)
  • 2021-01-04 07:44

    None of the answers worked for me. 1) Order of the filter needs to be lower that 1000 (sending response filter)

    2) Code:

     private String getResponseData(RequestContext ctx) throws IOException {
        String responseData = null;
    
        final InputStream responseDataStream = ctx.getResponseDataStream();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ByteArrayOutputStream copy = new ByteArrayOutputStream();
        int read = 0;
        byte[] buff = new byte[1024];
        while ((read = responseDataStream.read(buff)) != -1) {
            bos.write(buff, 0, read);
            copy.write(buff, 0, read);
        }
        InputStream isFromFirstData = new ByteArrayInputStream(bos.toByteArray());
    
        boolean responseGZipped = ctx.getResponseGZipped();
        try {
            InputStream zin = null;
            if (responseGZipped) {
                zin = new GZIPInputStream(isFromFirstData);
            } else {
                zin = responseDataStream;
            }
            responseData = CharStreams.toString(new InputStreamReader(zin, "UTF-8"));
            ctx.setResponseDataStream(new ByteArrayInputStream(copy.toByteArray()));
    
        } catch (IOException e) {
            logger.warn("Error reading body {}", e.getMessage());
        }
    
        return responseData;
    }
    
    0 讨论(0)
  • 2021-01-04 07:55

    If someone is struggling with compressed answer, here's the solution I used:

    // Read the compressed response
    RequestContext ctx = RequestContext.getCurrentContext();
    InputStream compressedResponseDataStream = ctx.getResponseDataStream();
    try {
        // Uncompress and transform the response
        InputStream responseDataStream = new GZIPInputStream(compressedResponseDataStream);
        String responseAsString = StreamUtils.copyToString(responseDataStream, Charset.forName("UTF-8"));
        // Do want you want with your String response
        ...
        // Replace the response with the modified object
        ctx.setResponseBody(responseAsString);
    } catch (IOException e) {
        logger.warn("Error reading body", e);
    }
    
    0 讨论(0)
  • 2021-01-04 07:56

    Be careful with the filterNumber

    Using anything greater than 1000 leads to an "InputStream already closed" error because the response body has already been read and

    I used the number 10 and worked fine

    0 讨论(0)
提交回复
热议问题