springCloud系列:FeignClient 客户端捕获到服务端抛出的自定义异常
解释:
在Spring Cloud中使用FeignClient时,如果服务端抛出了一个自定义异常,Feign会将这个异常封装成一个FeignException
。FeignException
是RuntimeException
的一个实例,它包含了服务端返回的HTTP状态码和响应体。
解决方法:
- 自定义异常处理:可以使用
@ControllerAdvice
和@ExceptionHandler
注解来处理特定的异常。 - 使用
ResponseEntityExceptionHandler
:在Feign客户端的实现类中,继承ResponseEntityExceptionHandler
,重写handleFeignException
方法,可以捕获并处理FeignException
。 - 使用Feign的解码器(Decoder):可以自定义一个解码器,在解码器中判断响应体是否为自定义异常,并进行相应处理。
示例代码:
@FeignClient(name = "service-provider", configuration = FeignClientConfiguration.class)
public interface ServiceProviderClient {
// 假设服务端的一个接口
@GetMapping("/api/resource/{id}")
MyResource getResource(@PathVariable("id") Long id);
}
@Configuration
public class FeignClientConfiguration {
@Bean
public Decoder feignDecoder() {
return (response, bodyType, targetType) -> {
if (bodyType.equals(ResponseEntity.class)) {
// 直接返回ResponseEntity,不做处理
return ResponseEntity.status(response.status()).headers(response.headers()).body(null);
}
// 正常的解码逻辑
return new Gson().fromJson(response.body().asReader(Charsets.UTF_8), targetType);
};
}
}
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(FeignException.class)
public ResponseEntity<Object> handleFeignException(FeignException e) {
try {
// 解析响应体为自定义异常对象
MyCustomException customException = new ObjectMapper().readValue(e.contentUTF8(), MyCustomException.class);
// 根据自定义异常进行处理
// ...
return ResponseEntity.status(e.status()).body(customException);
} catch (IOException ioException) {
// 处理异常解析失败的情况
// ...
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error parsing response");
}
}
}
在这个示例中,首先定义了一个Feign客户端接口,然后创建了一个配置类FeignClientConfiguration
,在其中定义了一个自定义的解码器。在解码器中,我们检查返回类型,如果是ResponseEntity
,则直接返回响应实体,不做进一步处理。对于其他类型,则使用Gson进行解码。
最后,我们定义了一个全局异常处理器GlobalExceptionHandler
,在其中捕获FeignException
,并根据自定义异常进行相应的处理。如果解析自定义异常时发生异常,则返回一个内部服务器错误。
评论已关闭