title: How to transform client request body with a zuul filter?
body: <p>I want to use Zuul to authenticate, transform and forward request from a client to internal services. The goal is to hide from the client a legacy API.</p>
  
  <p>What I have in mind is: a client sends a POST request with the JSON representation of an object A to the API Gateway where Zuul is embedded. The API Gateway transforms the body from A to LegacyA and send it to the internal service.</p>
  
  <p>For example, I search a way to transform the following JSON:</p>
  
  <pre><code>["hello","world"]
  </code></pre>
  
  <p>in this JSON:</p>
  
  <pre><code>{hashCode("hello"):"hello", hashCode("world"):"world")}
  </code></pre>
  
  <p>I want to use a pre-filter. But I have problem to rewrite a valid request.</p>
  
  <p>Do you have any idea how can I do that?</p>
  
  <p>I have written this filter:</p>
  
  <pre><code>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&lt;String&gt; test = objectMapper.readValue(inputStream, new TypeReference&lt;List&lt;String&gt;&gt;() {
              });
              Map&lt;Integer, String&gt; result = test.stream()
                      .collect(Collectors.toMap(String::hashCode, str -&gt; str));
  
              byte[] json = objectMapper.writeValueAsBytes(result);
              ServletInputStream response = new ServletInputStreamWrapper(json);
  
              return response;
          }
      }
  }
  </code></pre>
  
  <p>The problem that I have is with the Content-Length which is not updated accordinally. </p>