您好,登錄后才能下訂單哦!
本篇內容介紹了“Feign調用全局異常處理的解決方法”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
TestService#addRecord(ParamVO) failed and no fallback available.;
對于failed and no fallback available.這種異常信息,是因為項目開啟了熔斷:
feign.hystrix.enabled: true
當調用服務時拋出了異常,卻沒有定義fallback方法,就會拋出上述異常。由此引出了第一個解決方式。
自定義Feign解析器:
import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; import com.crecgec.baseboot.jsoncore.exception.BaseException; import feign.Response; import feign.Util; import feign.codec.ErrorDecoder; import org.springframework.context.annotation.Configuration; import java.io.IOException; @Configuration public class FeignErrorDecoder implements ErrorDecoder { @Override public Exception decode(String methodKey, Response response) { try { // 這里直接拿到我們拋出的異常信息 String message = Util.toString(response.body().asReader()); try { JSONObject jsonObject = JSONObject.parseObject(message); return new BaseException(jsonObject.getString("resultMsg"), jsonObject.getInteger("resultCode")); } catch (JSONException e) { e.printStackTrace(); } } catch (IOException ignored) { } return decode(methodKey, response); } }
public class BaseException extends RuntimeException { private int status ; public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public BaseException() { } public BaseException(String message, int status) { super(message); this.status = status; } public BaseException(String message) { super(message); } public BaseException(String message, Throwable cause) { super(message, cause); } public BaseException(Throwable cause) { super(cause); } public BaseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
public class ResultSet { /** * 返回的狀態碼 */ private Integer resultCode; /** * 返回的消息 */ private String resultMsg; /** * 返回的數據 */ private Object data; public ResultSet() { } public ResultSet(Integer resultCode, String resultMsg) { this.resultCode = resultCode; this.resultMsg = resultMsg; } public ResultSet(Integer resultCode, String resultMsg, Object data) { this.resultCode = resultCode; this.resultMsg = resultMsg; this.data = data; } public Integer getResultCode() { return resultCode; } public void setResultCode(Integer resultCode) { this.resultCode = resultCode; } public String getResultMsg() { return resultMsg; } public void setResultMsg(String resultMsg) { this.resultMsg = resultMsg; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } }
@ExceptionHandler(value = BaseException.class) public ResultSet defaultErrorHandler(HttpServletRequest req, HttpServletResponse resp, BaseException e) { ResultSet resultSet = new ResultSet(); if (e.getStatus() == 400) { resultSet.setResultCode(-1); resultSet.setResultMsg(e.getMessage()); resultSet.setData(null); resp.setStatus(400); } else { resp.setStatus(500); if(logger.isErrorEnabled()){ logger.error("系統異常,請聯系系統開發人員進行處理", e); } resultSet.setResultCode(-1); resultSet.setResultMsg(e.getMessage()); resultSet.setData(null); } return resultSet; }
這樣就能完成了feign接收異常處理的自定義異常信息!
第三方系統調用我方系統@FeignClient接口時報錯
com.netflix.hystrix.exception.HystrixRuntimeException: WorkFlowTaskOperateService#processWorkFlowTaskSyncCallback(TaskProcessDTO) failed and no fallback available.
我方系統出現FeignException.
第三方調用者拋出的異常:HystrixRuntimeException
一檢查我們系統確實沒有指定fallback和configuration,并且調用方開啟了feign.hystrix.enabled: true
@FeignClient(value = "taxplan-workflow")
修改方法:
第三方調用在Application.java添加處理Feign異常的全局處理方法
@Bean public Feign.Builder feignBuilder() { return Feign.builder().requestInterceptor(new RequestInterceptor() { @Override public void apply(RequestTemplate requestTemplate) { Map<String, String> customHeaders = WebUtils.getCustomHeaders(); customHeaders.forEach((k, v) -> { requestTemplate.header(k, v); }); } }).errorDecoder(new CustomErrorDecoder()); }
這里使用了RequestInterceptor攔截器,可以定制請求頭,如果不想定制,可以改為
return Feign.builder().errorDecoder(new CustomErrorDecoder());
實現ErrorDecoder接口,其中ExceptionCode是枚舉類.
public Exception decode(String methodKey, Response response) { if (response.status() >= 400 && response.status() <= 499) { return new BaseBizException(ExceptionCode.CALL_INNER_ERROR, "Client error.httpStatusCode:" + response.status()); } else { if (response.status() >= 500 && response.status() <= 599 && response.body() != null) { try { String content = CharStreams.toString(new InputStreamReader(response.body().asInputStream(), StandardCharsets.UTF_8)); Map responseBody = (Map) JSONObject.parseObject(content, Map.class); if (responseBody.containsKey("code")) { return new BaseBizException(responseBody.get("code").toString(), Objects.toString(responseBody.get("msg"))); } } catch (Exception var5) { } } return new BaseBizException(ExceptionCode.CALL_INNER_ERROR); } }
ExceptionCode枚舉類如下:可以自定義增加刪除
public enum ExceptionCode { ILLEGAL_STATE(4001, "非法訪問"), PARAM_REQUIRED(4002, "參數不能為空"), PARAM_FORMAT_ILLEGAL(4003, "參數格式錯誤"), REQUEST_DATA_DUPLICATION(4004, "重復請求"), REQUEST_DATA_ERROR(4005, "請求數據錯誤"), REQUEST_DATA_NOT_MATCH(4006, "請求數據不一致"), RECORD_NOT_EXIST(5001, "記錄不存在"), RECORD_EXISTED(5002, "記錄已存在"), RECORD_ILLEGAL_STATE(5003, "數據異常"), BALANCE_NOT_ENOUGH(5103, "余額不足"), CALL_INNER_ERROR(5800, "調用內部服務接口異常"), THIRD_PART_ERROR(5801, "調用第三方接口異常"), SYSTEM_ERROR(9999, "系統異常"); public final int code; public final String defaultMessage; private ExceptionCode(int code, String defaultMessage) { this.code = code; this.defaultMessage = defaultMessage; } }
“Feign調用全局異常處理的解決方法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。