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
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.
I've managed to overcome this. The solution consists of 4 steps:
ctx.getResponseDataStream()
into a ByteArrayOutputStreamcontext.setResponseBody(inputStream)
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);
}
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;
}
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);
}
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