有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Zuul预过滤器中的java修改请求正文不工作

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

}

目前,我只是试图将正文改为大写,但该请求路由到的微服务没有收到修改后的正文(大写)。相反,它收到的是原始的。我做错什么了吗。任何帮助都将不胜感激。谢谢


共 (3) 个答案

  1. # 1 楼答案

    试试这个,对你来说可能有用

    requestContext.getCurrentContext().put("requestEntity", new ByteArrayInputStream(body.getBytes("UTF-8")));
    
  2. # 2 楼答案

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

  3. # 3 楼答案

    能够执行以下操作-将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;
        }