在Zuul预过滤器中修改请求体不起作用

时间:2017-07-31 09:31:44

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

在我的应用程序中,我使用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;
    }

}

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

4 个答案:

答案 0 :(得分:1)

尝试这一个它可能适用于您的情况。

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

答案 1 :(得分: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 :(得分:0)

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

答案 3 :(得分:0)

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