在 FeignClient 中处理 HTTP 重定向
Handling HTTP redirections in FeignClient
FeignClient 是一个非常漂亮的工具,但不幸的是,如果你需要做一些与 Spring 众神的意图稍有不同的事情,你就会受到伤害。
当前情况:我使用外部第三方 REST 服务,嗯,关于 REST 的概念有趣。特别是,如果您向他们发送正确的 JSON,他们会在正文中 return 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?
虽然没有办法强制 FeignClient 在没有疯狂的解决方法的情况下正常处理超过 2xx 的任何内容,但有办法以最小的麻烦来处理它。请注意,您将需要 非常新的 版本!我必须在 POM 中输入:
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.9</version>
</dependency>
那么,怎么做呢?
在伪造客户端实现中,您需要 return 响应的任何方法。就是这样。
如果您 return 响应,框架将以特殊方式运行 - 如果状态超过 2xx,它不会抛出任何异常,也不会像某些人那样尝试重试多次...有天赋的.. . child。换句话说,没有恶作剧。耶!
示例:
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() 以抛出你自己的异常,以与 200 相同的方式处理任何状态代码(如 302)的响应(哦,恐怖!)等等。
FeignClient 是一个非常漂亮的工具,但不幸的是,如果你需要做一些与 Spring 众神的意图稍有不同的事情,你就会受到伤害。
当前情况:我使用外部第三方 REST 服务,嗯,关于 REST 的概念有趣。特别是,如果您向他们发送正确的 JSON,他们会在正文中 return 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?
虽然没有办法强制 FeignClient 在没有疯狂的解决方法的情况下正常处理超过 2xx 的任何内容,但有办法以最小的麻烦来处理它。请注意,您将需要 非常新的 版本!我必须在 POM 中输入:
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.9</version>
</dependency>
那么,怎么做呢?
在伪造客户端实现中,您需要 return 响应的任何方法。就是这样。
如果您 return 响应,框架将以特殊方式运行 - 如果状态超过 2xx,它不会抛出任何异常,也不会像某些人那样尝试重试多次...有天赋的.. . child。换句话说,没有恶作剧。耶!
示例:
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() 以抛出你自己的异常,以与 200 相同的方式处理任何状态代码(如 302)的响应(哦,恐怖!)等等。