【问题标题】:Handling HTTP redirections in FeignClient在 FeignClient 中处理 HTTP 重定向
【发布时间】:2017-06-12 00:59:32
【问题描述】:

FeignClient 是一个非常漂亮的工具,但不幸的是,如果您需要做一些与 Spring 之神的预期稍有不同的事情,那么您将受到伤害。

当前案例:我使用外部第三方 REST 服务,嗯,有趣关于 REST 的概念。特别是,如果您向他们发送正确的 JSON,他们会在正文中返回 HTTP 302 和 JSON。

不用说,FeignClient 真的,真的不喜欢这种恶作剧。我的界面:

@FeignClient(value = "someClient", configuration = SomeClientDecoderConfiguration.class)
public interface SomeClient {
    @RequestMapping(method = RequestMethod.POST, path = "${someClient.path}",
    produces = MediaType.APPLICATION_JSON_VALUE)
    JsonOrderCreateResponse orderCreate(JsonOrderCreateRequest request, @RequestHeader("Authorization") String authHeader);
}

我已经有自定义配置和错误解码器,但这些仅适用于 HTTP 4xx 和 5xx。如果系统遇到302,它会这样结束:

http://pastebin.com/raw/cGKWc4yg

如何防止这种情况并强制 FeignClient 像 200 一样处理 302?

【问题讨论】:

    标签: spring netflix-feign


    【解决方案1】:

    虽然没有办法强制 FeignClient 在没有疯狂变通办法的情况下正常处理超过 2xx 的任何内容,但有办法以最小的麻烦处理它。请注意,您需要最新版本!我必须在 POM 中输入:

    <dependency>
        <groupId>com.netflix.hystrix</groupId>
        <artifactId>hystrix-core</artifactId>
        <version>1.5.9</version>
    </dependency>
    

    那么,该怎么做呢?

    在任何需要返回响应的方法的 feign 客户端实现中。就是这样。

    如果您返回响应,框架将以特殊方式运行 - 在状态超过 2xx 的情况下,它不会抛出任何异常,也不会像某些...有天赋的...孩子一样尝试多次重试。换句话说,没有恶作剧。耶!

    例子:

    import feign.Response;
    
    @RequestMapping(method = RequestMethod.POST, path = "${someClient.path}")
    Response doThisOrThat(JsonSomeRequest someJson, @RequestHeader("Authorization") String authHeader);
    

    当然,您实际上需要手动处理响应(前面提到的最小麻烦):

    private JsonSomeResponse resolveResponse(JsonSomeRequest jsonRequest, String accessToken)
    {
        Response response = someClient.doThisOrThat(jsonRequest, "Bearer " + accessToken);
        JsonSomeResponse jsonResponse = null;
        String resultBody = "";
        try {
            try (BufferedReader buffer = new BufferedReader(new InputStreamReader(response.body().asInputStream()))) {
                resultBody = buffer.lines().collect(Collectors.joining("\n"));
            }
            jsonResponse = objectMapper.readValue(resultBody, JsonSomeResponse.class);
        } catch (IOException ex) {
            throw new RuntimeException("Failed to process response body.", ex);
        }
        // just an example of using exception
        if (response.status() >= 400) thrown new OmgWeAllAreDeadException();
        return jsonResponse;
    }
    

    然后你可以做任何你想做的事,检查 response.status() 来抛出你自己的异常,用任何状态码(比如 302)处理响应,就像 200 一样(哦,太可怕了!)等等。

    【讨论】:

      猜你喜欢
      • 2015-06-10
      • 2014-12-02
      • 1970-01-01
      • 2020-02-20
      • 2018-07-15
      • 2019-08-26
      • 1970-01-01
      • 2020-08-04
      • 2020-04-09
      相关资源
      最近更新 更多