Reputation: 607
I am using Zuul post filter to intercept the response. My requirement is to add one new field to response json. I'm able to intercept the response and edit it. But, unable to set the updated response to RequestContext.How it is possible to read a response body ,edit and update it back to RequestContext while using Zuul as a proxy in post filter?
Please find the below code i am using.
private void updateResponseBody(RequestContext ctx) throws IOException, JSONException {
final InputStream responseDataStream = ctx.getResponseDataStream();
String responseData = CharStreams.toString(new InputStreamReader(responseDataStream, "UTF-8"));
JSONObject jsonObj = new JSONObject(responseData);
JSONArray groupsArray = jsonObj.getJSONArray("list");
for (int i = 0; i < groupsArray.length(); i++) {
JSONObject groupId = groupsArray.getJSONObject(i);
groupId.accumulate("new_json_field_name", "new_json_field_value");
}
String updatedResponse = jsonObj.toString();
// ctx.setResponseBody(body); // also not working
ctx.setResponseDataStream(org.apache.commons.io.IOUtils.toInputStream(updatedResponse, "UTF-8"));
}
Error I am getting is :
Error while sending response to client: java.io.IOException: An existing connection was forcibly closed by the remote host.
Can anyone please help me on this.
Upvotes: 2
Views: 3014
Reputation: 11
I had a similar task and tried to do it by writing to the OutputStream. This worked, but had a strange side effect that it made the HttpHeaders in the response to be deleted or corrupted. This made the call produce CORS errors in production even though it ran fine locally through Postman.
I wrote the following method that I call from the run() method of my Post Zuul Filter to add a single node/value to the return Json.
private void addJsonNode(RequestContext requestContext,String name, String id) {
HttpServletResponse servletResponse = requestContext.getResponse();
try {
final InputStream responseDataStream = requestContext.getResponseDataStream();
String responseData = CharStreams.toString(new InputStreamReader(responseDataStream, "UTF-8"));
JSONObject jsonObject = new JSONObject(responseData);
jsonObject.put(name, id);
String updatedResponse = jsonObject.toString(4);
requestContext.setResponseBody(updatedResponse);
} catch (IOException e) {
log.warn("Error reading body", e);
} catch (JSONException e) {
log.warn("Error reading body", e);
}
}
Upvotes: 0
Reputation: 3196
I had the same error and got crazy modifying the code described in How to get response body in Zuul post filter? trying different possibilities. Finally I found the solution in this post by writing the answer in the OutputStream
from servletResponse.getOutputStream()
instead of ctx.setResponseDataStream()
:
HttpServletResponse servletResponse = ctx.getResponse();
...
String updatedResponse = jsonObj.toString();
try {
OutputStream outStream = servletResponse.getOutputStream();
outStream.write(updatedResponse.getBytes(), 0, updatedResponse.length());
outStream.flush();
outStream.close();
} catch (IOException e) {
log.warn("Error reading body", e);
}
Upvotes: 2