简体   繁体   English

如何在 Zuul 后置过滤器中拦截和编辑响应正文?

[英]How to intercept and edit response body in Zuul post filter?

I am using Zuul post filter to intercept the response.我正在使用 Zuul 后过滤器来拦截响应。 My requirement is to add one new field to response json.我的要求是在响应 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?但是,无法将更新的响应设置为 RequestContext。如何在后过滤器中使用 Zuul 作为代理时读取响应正文,编辑并将其更新回 RequestContext?

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.任何人都可以帮我解决这个问题。

I had the same error and got crazy modifying the code described in How to get response body in Zuul post filter?我遇到了同样的错误,并且疯狂地修改了如何在 Zuul 后过滤器中获取响应正文中描述的代码 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() :最后,我通过在servletResponse.getOutputStream()而不是ctx.setResponseDataStream()OutputStream写入答案,在这篇文章中找到了解决方案:

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);
}

I had a similar task and tried to do it by writing to the OutputStream.我有一个类似的任务,并试图通过写入 OutputStream 来完成它。 This worked, but had a strange side effect that it made the HttpHeaders in the response to be deleted or corrupted.这有效,但有一个奇怪的副作用,它使响应中的 HttpHeaders 被删除或损坏。 This made the call produce CORS errors in production even though it ran fine locally through Postman.这使得调用在生产中产生 CORS 错误,即使它通过 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.我编写了从 Post Zuul 过滤器的 run() 方法调用的以下方法,以将单个节点/值添加到返回的 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);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM