如何为多个假装客户端实现错误解码器



我在Spring Boot应用程序中有多个假客户端。我正在使用控制器建议来处理每个假客户端的自定义异常。

这是我的控制器建议,它处理两个自定义异常(每个客户端一个: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);
}
}

我已经为假客户端1实现了一个错误解码器。

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:
client:
config:
client1:
errorDecoder: feign.codec.ErrorDecoder.Default

我的问题是:处理多个假客户端异常的最佳方法是什么?我是否应该使用相同的错误解码器并将其响应视为通用异常?还是应该为每个假客户端创建一个错误解码器?

快速回答

如果使用不同的 API,则错误响应的格式不会相同。因此,单独处理它们似乎是最好的方法。

言论

从您的示例中,您似乎定义了一个自定义ErrorDecoder,该可能 未使用,因为您还在属性文件中将 feign 配置为对 client1 使用默认错误解码器。 即使您在某处为自定义ClientErrorDecoder定义了带有 bean 的@Configuration类, Spring Cloud 文档提到配置属性优先于@Configuration注释

如果我们同时创建 Bean 和配置属性@Configuration, 配置属性将优先。它将覆盖@Configuration 值。但是,如果要将优先级更改为@Configuration,则可以 可以将 feign.client.default-to-properties 更改为 false。

这是一个假设的修剪配置,用于处理具有不同错误解码器的多个假客户端:

客户1: 你告诉假装加载在 client1 的类CustomFeignConfiguration定义的 bean

@FeignClient(name = "client1", configuration = {CustomFeignConfiguration.class})
public interface Client1 {...}

客户端 2: Client2 将使用默认的假装ErrorDecoder因为未指定任何配置。(错误时会抛出FeignException)

@FeignClient(name = "client2")
public interface Client2 {...}

配置:这里要小心,如果你@Configuration添加到CustomFeignConfiguration,那么ClientErrorDecoderbean 将用于每个加载的假客户端(取决于你的应用程序组件扫描行为)

public class CustomFeignConfiguration {
@Bean
public ClientErrorDecoder clientErrorDecoder(ObjectMapper objectMapper) {
return new ClientErrorDecoder(objectMapper);
}
}

此配置也可以使用属性文件完成。

旁注

从我的角度来看,你甚至不需要控制器的建议。如果使用 Spring Web@ResponseStatus注释,则可以判断应该使用自定义ErrorDecoder抛出的异常正文发回哪个 HTTP 状态代码。

有用的资源

  • 春季云文档
  • 与主题相关的 GitHub 问题

最新更新