【问题标题】:Modifying request body in Zuul pre filter not working在 Zuul 预过滤器中修改请求正文不起作用
【发布时间】:2017-07-31 09:31:43
【问题描述】:

在我的应用程序中,我使用netflix zuul 将请求从一个微服务(网关)路由到另一个。请求的路由很好,但我还想在请求正文中引入一些参数,然后再将其路由到适当的微服务。为此,我正在使用像这样的 Zuul 预过滤器。

public class SimpleFilter extends ZuulFilter {

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

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

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

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

    @Override
    public Object run() {

        try {
            RequestContext context = RequestContext.getCurrentContext();

            InputStream in = (InputStream) context.get("requestEntity");
            if (in == null) {
                in = context.getRequest().getInputStream();
            }

            String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));

            // body = "request body modified via set('requestEntity'): "+ body;
            body = body.toUpperCase();
            context.set("requestEntity", new ByteArrayInputStream(body.getBytes("UTF-8")));

        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }

}

现在我只是尝试将正文更改为大写,但此请求路由到的微服务没有收到修改后的正文(大写)。相反,它会收到原始的。难道我做错了什么。任何帮助,将不胜感激。谢谢!!

【问题讨论】:

  • 你有一个名为 SimpleFilter 的 bean 吗?
  • 嘿@Laurynas 是的,我有这样的豆子。而且我调试发现requestEntity正在被修改并且包含context包含了经过上述步骤后的新body。但是请求被路由到的服务仍然包含以前的主体,即小案例

标签: java spring netflix-zuul spring-cloud-netflix


【解决方案1】:

能够执行以下操作 - 将 GET 请求转换为 POST 请求,并将正文内容添加到(代理的)POST 请求。

    public Object run() throws ZuulException {
        RequestContext context = RequestContext.getCurrentContext();
        context.addZuulRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        String body = String.format("a=%s&b=%s", a, b);

        final byte[] bytes = body.getBytes(StandardCharsets.UTF_8);
        context.setRequest(new HttpServletRequestWrapper(context.getRequest()) {
            @Override
            public ServletInputStream getInputStream() {
                return new ServletInputStreamWrapper(bytes);
            }

            @Override
            public int getContentLength() {
                return bytes.length;
            }

            @Override
            public long getContentLengthLong() {
                return bytes.length;
            }

            @Override
            public String getMethod() {
                return "POST";
            }
        });

        return null;
    }

【讨论】:

    【解决方案2】:

    试试这个它可能对你有用。

    requestContext.getCurrentContext().put("requestEntity", new ByteArrayInputStream(body.getBytes("UTF-8")));
    

    【讨论】:

      【解决方案3】:

      原来这个方法不能改变requestContext中的请求体。确实在requestContext中增加了一个新的字段“requestEntity”,但是context.getRequest().getInputStream()的请求体在这个操作之后保持不变。

      【讨论】:

        【解决方案4】:

        您可以修改请求正文,请参阅this answer 示例。您只需要包装新的请求数据并确保正确报告它的新内容长度。

        【讨论】:

          猜你喜欢
          • 2018-01-10
          • 2018-12-28
          • 2016-07-10
          • 2019-01-12
          • 1970-01-01
          • 2017-06-13
          • 2016-11-19
          • 2015-09-14
          • 2018-12-30
          相关资源
          最近更新 更多