如何使用zuul过滤器转换客户端请求主体?

问题描述 投票:1回答:1

我想使用Zuul来验证,转换和转发从客户端到内部服务的请求。目标是从客户端隐藏遗留API。

我的想法是:客户端将一个带有对象A的JSON表示的POST请求发送到嵌入了Zuul的API网关。 API网关将正文从A转换为LegacyA并将其发送到内部服务。

例如,我搜索一种转换以下JSON的方法:

["hello","world"]

在这个JSON中:

{hashCode("hello"):"hello", hashCode("world"):"world")}

我想使用预过滤器。但我有问题重写有效的请求。

你知道我怎么能这样做吗?

我写过这个过滤器:

public class RestZuulFilter extends ZuulFilter {

    private final ObjectMapper objectMapper;

    @Autowired
    public RestZuulFilter(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

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

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

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

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();

        HttpServletRequestWrapper wrapper = new MyWrapper(ctx.getRequest());
        ctx.setRequest(wrapper);

        return null;
    }

    class MyWrapper extends HttpServletRequestWrapper {

        /**
         * Constructs a request object wrapping the given request.
         *
         * @param request The request to wrap
         * @throws IllegalArgumentException if the request is null
         */
        public MyWrapper(HttpServletRequest request) {
            super(request);
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {
            ServletInputStream inputStream = this.getRequest().getInputStream();

            List<String> test = objectMapper.readValue(inputStream, new TypeReference<List<String>>() {
            });
            Map<Integer, String> result = test.stream()
                    .collect(Collectors.toMap(String::hashCode, str -> str));

            byte[] json = objectMapper.writeValueAsBytes(result);
            ServletInputStream response = new ServletInputStreamWrapper(json);

            return response;
        }
    }
}

我遇到的问题是Content-Length没有相应更新。

java spring netflix-zuul
1个回答
3
投票

看一下正在转换的请求体的以下示例。我认为这对你有用。

    InputStream in = (InputStream) context.get("requestEntity");
    if (in == null) {
        in = context.getRequest().getInputStream();
    }
    String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
    body = body.toUpperCase();
    context.set("requestEntity", new ByteArrayInputStream(body.getBytes("UTF-8")));

对于完整的课程:

https://github.com/spring-cloud-samples/sample-zuul-filters/blob/master/src/main/java/org/springframework/cloud/samplezuulfilters/UppercaseRequestEntityFilter.java

© www.soinside.com 2019 - 2024. All rights reserved.