面试题答案
一键面试- 全局异常处理器:
- 在每个微服务中创建全局异常处理器,使用
@ControllerAdvice
注解。例如:
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(FeignException.class) @ResponseBody public ResponseEntity<ErrorResponse> handleFeignException(FeignException ex) { ErrorResponse errorResponse = new ErrorResponse(); errorResponse.setErrorCode("FEIGN_001"); errorResponse.setErrorMessage("远程调用异常"); errorResponse.setDetails(ex.getMessage()); return new ResponseEntity<>(errorResponse, HttpStatus.valueOf(ex.status())); } @ExceptionHandler(BusinessException.class) @ResponseBody public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) { ErrorResponse errorResponse = new ErrorResponse(); errorResponse.setErrorCode("BUSINESS_001"); errorResponse.setErrorMessage("业务异常"); errorResponse.setDetails(ex.getMessage()); return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); } }
- 这里
ErrorResponse
是自定义的错误响应类,包含错误码、错误信息和详细描述。
- 在每个微服务中创建全局异常处理器,使用
- 自定义异常类:
- 定义业务异常类,例如:
public class BusinessException extends RuntimeException { public BusinessException(String message) { super(message); } }
- 这样在业务代码中,当业务逻辑出现异常时,可以抛出
BusinessException
。
- Feign异常处理:
- Feign默认的异常处理比较简单,我们可以自定义
ErrorDecoder
。
public class CustomErrorDecoder implements ErrorDecoder { @Override public Exception decode(String methodKey, Response response) { try { String body = Util.toString(response.body().asReader()); ErrorResponse errorResponse = new ObjectMapper().readValue(body, ErrorResponse.class); // 根据不同的错误码返回不同的异常 if ("FEIGN_001".equals(errorResponse.getErrorCode())) { return new FeignException.FeignClientException(response.status(), errorResponse.getErrorMessage(), response.request(), null); } return new FeignException.GenericFeignException(response.status(), errorResponse.getErrorMessage(), response.request(), null); } catch (IOException e) { return new FeignException.GenericFeignException(response.status(), "解析错误", response.request(), null); } } }
- 然后在Feign客户端配置中使用这个
ErrorDecoder
:
@Configuration public class FeignConfig { @Bean public ErrorDecoder errorDecoder() { return new CustomErrorDecoder(); } }
- Feign默认的异常处理比较简单,我们可以自定义
- 异常信息传递:
- 在Feign调用时,将异常信息封装在响应体中传递。例如,在被调用方的全局异常处理器中,将异常信息封装到
ErrorResponse
并返回。 - 调用方通过自定义的
ErrorDecoder
解析响应体中的异常信息,并抛出相应的异常,最终由调用方的全局异常处理器处理并返回友好的错误反馈给客户端。
- 在Feign调用时,将异常信息封装在响应体中传递。例如,在被调用方的全局异常处理器中,将异常信息封装到
- 可维护性和扩展性:
- 通过这种分层的异常处理机制,每个微服务的异常处理逻辑相对独立,便于维护。
- 当有新的异常类型出现时,只需在全局异常处理器中添加对应的
@ExceptionHandler
方法,以及在自定义ErrorDecoder
中添加相应的处理逻辑,即可实现扩展。