是否可以在netflix zuul路由过滤器中更改http请求方法?

时间:2019-04-26 13:30:33

标签: netflix-zuul

我试图将使用MVC1模式构建的旧式api服务器的http GET方法调用转换为新的Restful api服务器,而无需使用netflix zuul和eureka更改前端源代码。

我添加了zuul前置过滤器,可将旧网址转换为在PreDecorationFilter之后工作的静态约定网址,并且效果很好。

但是现在我面临着通过区分url将GET方法转换为POST,PUT,DELETE等适当方法的问题,以便通过@ GetMapping / @ PostMapping / @ PutMapping / @ DeleteMapping在spring控制器中正确映射请求。 / p>

我研究了处理HttpClient的SimpleRoutingFilter,但是 由于环境的限制,我必须使用eureka服务ID才能路由到新的api服务器,这意味着我应该使用RibbonRoutingFilter,要在其中找到正确的位置,该功能非常复杂。

那么,是否可以在RibbonRoutingFilter之前更改http方法或发出新的http请求? 如果可能的话,您可以建议在哪里进行该操作或参考一下?

非常感谢!

================================================ ======================

Milenko Jevremovic,

您能告诉我有关使用Feign的更多细节吗?

我像下面一样捍卫@FeignClient

@PostMapping(value = "{url"}, consumes = "application/json")
ResponseEntity<?> postMethod(@PathVariable("url") String url);

并获取查询参数以请求主体以进行zuul预过滤器中的POST,

将逻辑从GET请求的URL转换为POST新的静态URL ...

byte[] bytes = objectMapper.writeValueAsBytes(ctx.get("requestQueryParams"));
ctx.setRequests(new HttpServletRequestWrapper(request) {
  @Override ..getMethod
  @Override ..getContentLength
  @Override ..getConentLengthLong
  @Override
  public ServletInputStream getInputStream() {
    return new ServletInputStreamWrapper(bytes);
  }
}
ResponseEntity<?> response feignClient.post(transformedNewApiUri);

并设置您建议的RequestContext代码。

新api服务器的控制器就像

@PostMapping
ResponseEntity<model> post(@RequestBody req..)

这对控制器很好,但是当我在控制器的post方法中看到http请求时, 没有参数的请求主体。

(HttpServleterRequest getInputStream显示为空)

由HttpServletRequestWrapper在zuul预过滤器中设置的请求数据是 没在Feign中使用过...? 更改GET查询时,请您告诉我更多的想法设置请求正文 到使用Feign的POST构造函数?

2 个答案:

答案 0 :(得分:0)

进行一些研究后未发现任何内置解决方案。

但是我想到的是,您可以在Pre过滤器中使用Feign客户端,获取响应,设置响应并将其立即从Pre过滤器返回给客户端。 / p>

您可以设置Feign客户端url或服务ID,如文档中所述,它也使用功能区。

在您的run方法中更改响应,例如:

...
RequestContext ctx = RequestContext.getCurrentContext();
ctx.setResponseStatusCode(your_code);
ctx.setResponseBody(new_body);
ctx.setSendZuulResponse(false);

return null

答案 1 :(得分:0)

无法更改HttpServletRequest的方法,但是可以替换RequestContext中的请求。 HttpServletRequestWrapper似乎很有帮助:

static class PostHttpServletRequest extends HttpServletRequestWrapper {
    public PostHttpServletRequest(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getMethod() {
        return "POST";
    }
}

因此方法run可以重写如下:

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

    HttpServletRequest request = ctx.getRequest();
    HttpServletRequest requestWrapper = new PostHttpServletRequest(request);
    ctx.setRequest(requestWrapper);

    return null;
}