2017-01-27 11 views
0

Я хочу использовать Zuul для аутентификации, преобразования и пересылки запроса от клиента к внутренним службам. Цель состоит в том, чтобы скрыть от клиента устаревший API.Как преобразовать тело запроса клиента с помощью фильтра zuul?

Что я имею в виду: клиент отправляет запрос POST с представлением JSON объекта A в шлюз API, в который встроен Zuul. Шлюз 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, который не обновляется accordinally.

ответ

1

Взгляните на следующий пример преобразования тела запроса. Я полагаю, это должно сработать для вас.

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

 Смежные вопросы

  • Нет связанных вопросов^_^