spring-boot - 如何为多个 feign 客户端实现错误解码器
问题描述
我在 Spring Boot 应用程序中有多个 feign 客户端。我正在使用控制器建议来处理每个 feign 客户端的自定义异常。
这里我的控制器建议处理两个自定义异常(每个客户端一个:client1 和 client2):
@ControllerAdvice
public class ExceptionTranslator implements ProblemHandling {
@ExceptionHandler
public ResponseEntity<Problem> handleCustomClient1Exception(CustomException1 ex, NativeWebRequest request) {
Problem problem = Problem.builder()
.title(ex.getTitle())
.detail(ex.getMessage())
.status(ex.getStatusType())
.code(ex.getCode())
.build();
return create(ex, problem, request);
}
@ExceptionHandler
public ResponseEntity<Problem> handleCustomClient2Exception(CustomException2 ex, NativeWebRequest request) {
Problem problem = Problem.builder()
.title(ex.getTitle())
.detail(ex.getMessage())
.status(ex.getStatusType())
.code(ex.getCode())
.build();
return create(ex, problem, request);
}
}
我已经为 feign client1 实现了一个错误解码器。
public class ClientErrorDecoder implements ErrorDecoder {
final ObjectMapper mapper;
public ClientErrorDecoder() {
this.mapper = new ObjectMapper();
}
@Override
public Exception decode(String methodKey, Response response) {
ExceptionDTO exceptionDTO;
try {
exceptionDTO = mapper.readValue(response.body().asInputStream(), ExceptionDTO.class);
} catch (IOException e) {
throw new RuntimeException("Failed to process response body.", e);
}
return new CustomException1(exceptionDTO.getDetail(), exceptionDTO.getCode(), exceptionDTO.getTitle(), exceptionDTO.getStatus());
}
}
我还为特定客户端配置了 feign 以使用该错误解码器,如下所示:
feign:
client:
config:
client1:
errorDecoder: feign.codec.ErrorDecoder.Default
我的问题是:处理多个假装客户异常的最佳方法是什么?我应该使用相同的错误解码器并将它们的响应视为一般异常吗?或者我应该为每个 feign 客户端创建一个错误解码器?
解决方案
快速回答
如果您使用不同的 API,错误响应的格式将不会相同。因此,单独处理它们似乎是最好的方法。
评论
从您的示例中,您似乎定义了一个ErrorDecoder
可能未使用的自定义,因为您还配置了 feign 以在属性文件中为您的 client1 使用默认错误解码器。即使您在@Configuration
某个地方为您的自定义定义了一个带有 bean 的类ClientErrorDecoder
,
Spring Cloud 文档也提到配置属性优先于@Configuration
注释
如果我们同时创建 @Configuration bean 和配置属性,配置属性将胜出。它将覆盖 @Configuration 值。但是如果你想把优先级改成@Configuration,你可以把feign.client.default-to-properties改成false。
例子
这是一个假设的修剪配置,用于处理具有不同错误解码器的多个 feign 客户端:
Client1:您告诉 feign 加载在CustomFeignConfiguration
client1 的类中定义的 bean
@FeignClient(name = "client1", configuration = {CustomFeignConfiguration.class})
public interface Client1 {...}
Client2 : Client2 将使用默认的 Feign ErrorDecoder
,因为没有指定配置。(会抛出一个FeignException
错误)
@FeignClient(name = "client2")
public interface Client2 {...}
配置:这里要小心,如果添加@Configuration
到CustomFeignConfiguration
,那么ClientErrorDecoder
bean 将用于每个加载的 feign 客户端(取决于您的应用程序组件扫描行为)
public class CustomFeignConfiguration {
@Bean
public ClientErrorDecoder clientErrorDecoder(ObjectMapper objectMapper) {
return new ClientErrorDecoder(objectMapper);
}
}
此配置也可以使用属性文件完成。
旁注
从我的角度来看,您甚至不需要控制器建议。如果您使用 Spring Web@ResponseStatus
注解,您可以通过自定义的ErrorDecoder
.
有用的资源
推荐阅读
- javascript - 发生“isset ['buttonname']”时window.location.href不起作用(php js)
- dictionary - Ansible如何创建字典键列表
- java - 为什么我的处理程序方法在定义为 lambda 时没有被触发?
- elasticsearch - 如何在 ELK 的弹性搜索中映射数据?
- java - 在 cucumber+selenium 上使用多个浏览器实例
- python - 如何证明这些过程在 Python 中是鞅?
- javascript - jQuery data-drawer-trigger onclick
- suitescript - 如何将 getInputData() 中的值传递给 map reduce suitescript 中的 map() 函数?
- android - 无法以“NetworkOnMainThreadException”引起的意图启动服务
- regex - 匹配表输入的正则表达式