使用 @FeignClient 处理异常

📅 2026/7/10 15:33:02 👁️ 阅读次数 📝 编程学习
使用 @FeignClient 处理异常

使用 @FeignClient 处理异常

  • 前言
  • 一、使用全局异常处理自定义返回码
  • 二、使用http状态码
    • 2.1. 使用 Feign 的 fallback(降级)机制
    • 2.2. 使用try catch进行异常捕获
    • 2.3. 使用自定义错误解码器(实现ErrorDecoder接口)

前言

在使用 @FeignClient 调用服务时,您可以通过以下方式处理异常。


一、使用全局异常处理自定义返回码

使用该方式,服务端接口http状态码还是200
通用响应类

@Data public class RestResponse<T> implements Serializable { /** * 操作返回信息 */ private String msg; /** * 操作返回信息代码 */ private Integer code; /** * 返回具体数据 */ private T data; public RestResponse<T> success(T data) { this.setData(data); this.setCode(200); this.setMsg("操作成功"); return this; } public RestResponse<T> error(Integer code, String msg) { this.setCode(code); this.setMsg(msg); return this; } public RestResponse error() { return error(ResultEnum.UNKNOWN_ERR); } public RestResponse<T> error(String msg) { error(); this.msg = msg; return this; } public RestResponse<T> error(ResultEnum rsEnum) { return error(rsEnum.getCode(), rsEnum.getMessage()); } public RestResponse<T> success() { this.code = 200; this.msg = "操作成功"; return this; } public RestResponse<T> success(ResultEnum resultEnum, T data) { this.setCode(resultEnum.getCode()); this.setMsg(resultEnum.getMessage()); this.setData(data); return this; } public RestResponse<T> success(Integer code, String message, T data) { this.setCode(code); this.setMsg(message); this.setData(data); return this; } }

全局异常处理器

@Slf4j @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public RestResponse ExceptionHandler(Exception e) { log.error(e.getMessage(), e); return new RestResponse().error(500, "接口调用失败"); } // 可以捕获其他类型的异常 }

FeignClient 接口

@Service @FeignClient(contextId = "TestService", value = "test") public interface TestService { @PostMapping("/open") RestResponse<TestResult> test(@RequestBody TestForm form); }

调用时通过自定义code来判断是否调用成功

RestResponse<TestResult> resp = service.test(form); if (!"200".equals(resp.getCode())) { // 处理错误,抛异常或返回默认结果 throw new BusinessException(resp.getMessage()); } TestResult result = resp.getData();

二、使用http状态码

2.1. 使用 Feign 的 fallback(降级)机制

服务端异常返回非200状态码

@Slf4j @RestController @RequestMapping("/open") public class OpenController { @Autowired private ITestService service; @PostMapping("/test") public Object test(TestForm form) { try { service.test(form); return ResponseEntity.ok("成功"); } catch (Exception e) { log.error("失败", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } } }

FeignClient 接口

@Service @FeignClient(contextId = "TestService", value = "test" fallback = MyFeignClientFallback.class) public interface TestService { @PostMapping("/open") TestResult test(@RequestBody TestForm form); }

MyFeignClientFallback自定义返回

@Component public class MyFeignClientFallback implements MyFeignClient { @Override public DataResponse getData() { // 这里返回默认值或 null return null; } }

2.2. 使用try catch进行异常捕获

服务端异常返回非200状态码

@Slf4j @RestController @RequestMapping("/open") public class OpenController { @Autowired private ITestService service; @PostMapping("/test") public Object test(TestForm form) { try { service.test(form); return ResponseEntity.ok("成功"); } catch (Exception e) { log.error("失败", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } } }

FeignClient 接口

@Service @FeignClient(contextId = "TestService", value = "test") public interface TestService { @PostMapping("/open") TestResult test(@RequestBody TestForm form); }

客户端调用

try { TestResult res = testService.test(); // 处理正常逻辑 } catch (Exception e) { // 处理异常情况,比如记录日志,返回默认值等 log.error("Feign调用失败", e); }

2.3. 使用自定义错误解码器(实现ErrorDecoder接口)

服务端异常返回非200状态码

@Slf4j @RestController @RequestMapping("/open") public class OpenController { @Autowired private ITestService service; @PostMapping("/test") public Object test(TestForm form) { try { service.test(form); return ResponseEntity.ok("成功"); } catch (Exception e) { log.error("失败", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } } }

自定义错误解码器

public class CustomErrorDecoder implements ErrorDecoder { @Override public Exception decode(String methodKey, Response response) { // 根据状态码返回不同的异常 if (response.status() == 404) { return new NotFoundException("Resource not found"); } else if (response.status() == 500) { return new InternalServerErrorException("Internal server error"); } return new FeignException("Unknown error"); } }

在Feign客户端配置中注入自定义错误解码器

@Configuration public class FeignConfig { @Bean public ErrorDecoder errorDecoder() { return new CustomErrorDecoder(); } }

FeignClient 接口引入自定义错误解码器

@Service @FeignClient(contextId = "TestService", value = "test", configuration = FeignConfig.class) public interface TestService { @PostMapping("/open") TestResult test(@RequestBody TestForm form); }