有没有办法在 netflix zuul 路由过滤器中更改 http 请求方法?

Is there a way to change http request method in netflix zuul routing filter?

我正在尝试将 http GET 方法调用从使用 MVC1 模式构建的遗留 api 服务器转换为新的 restful api 服务器,而无需使用任何前端源代码更改Netflix zuul 和尤里卡。

我在 PreDecorationFilter 之后添加了 zuul 预过滤器,将遗留 url 转换为 restful 约定 url,并且工作正常。

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

我查看了处理 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);

并获取查询参数以请求正文 POST 在 zuul 前置过滤器中,

将逻辑从 GET 请求 url 转换为 POST 新 restful 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 pre filter中设置的请求数据为 可能没有在 Feign 中使用...? 更改 GET 查询时,请给我更多关于设置请求正文的想法吗 到 POST 使用 Feign 的构造函数?

做了一些研究后没有找到任何内置解决方案。

但我想到的是,您可以在 Pre 过滤器中使用 Feign 客户端,获取响应,设置响应并 return 立即从您的 Pre 过滤器。

您可以设置 Feign 客户端 url 或您的服务 ID,就像文档中解释的那样,它也使用 ribbon 。

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

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

return null

无法更改 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;
}