Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get response body in Zuul post filter?

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:

@Component
public class PostFilter extends ZuulFilter {

    private static final Logger log = LoggerFactory.getLogger(PostFilter.class);

    @Override
    public String filterType() {
        return "post";
    }

    @Override
    public int filterOrder() {
        return 2000;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        ctx.getResponseBody(); // null

        // cant't do this, cause input stream is used later in other filters and I got InputStream Closed exception
        // GZIPInputStream gzipInputStream = new GZIPInputStream(stream);
        return null;
    }

}
like image 257
Dariusz Mydlarz Avatar asked Jan 29 '16 15:01

Dariusz Mydlarz


People also ask

How does ZUUL filter work?

Zuul provides a framework to dynamically read, compile, and run these Filters. Filters do not communicate with each other directly - instead they share state through a RequestContext which is unique to each request. Filters are currently written in Groovy, although Zuul supports any JVM-based language.

In what order are ZUUL filters executed?

There are four types of standard filters in Zuul: pre for pre-routing filtering, route for routing to an origin, post for post-routing filters, and error for error handling.

How do you handle exception in ZUUL?

First, we obtain the instance of the RequestContext. Next, we verify whether throwable obtained from RequestContext is an instance of ZuulException. Then, we check if the cause of the nested exception in throwable is an instance of ConnectException. Finally, we've set the context with custom properties of the response.


2 Answers

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);
}
like image 128
VincentS Avatar answered Sep 20 '22 11:09

VincentS


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);
}
like image 29
codesalsa Avatar answered Sep 21 '22 11:09

codesalsa