您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Feign調(diào)用全局異常處理的解決方法”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
TestService#addRecord(ParamVO) failed and no fallback available.;
對(duì)于failed and no fallback available.這種異常信息,是因?yàn)轫?xiàng)目開(kāi)啟了熔斷:
feign.hystrix.enabled: true
當(dāng)調(diào)用服務(wù)時(shí)拋出了異常,卻沒(méi)有定義fallback方法,就會(huì)拋出上述異常。由此引出了第一個(gè)解決方式。
自定義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 { /** * 返回的狀態(tài)碼 */ private Integer resultCode; /** * 返回的消息 */ private String resultMsg; /** * 返回的數(shù)據(jù) */ 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("系統(tǒng)異常,請(qǐng)聯(lián)系系統(tǒng)開(kāi)發(fā)人員進(jìn)行處理", e); } resultSet.setResultCode(-1); resultSet.setResultMsg(e.getMessage()); resultSet.setData(null); } return resultSet; }
這樣就能完成了feign接收異常處理的自定義異常信息!
第三方系統(tǒng)調(diào)用我方系統(tǒng)@FeignClient接口時(shí)報(bào)錯(cuò)
com.netflix.hystrix.exception.HystrixRuntimeException: WorkFlowTaskOperateService#processWorkFlowTaskSyncCallback(TaskProcessDTO) failed and no fallback available.
我方系統(tǒng)出現(xiàn)FeignException.
第三方調(diào)用者拋出的異常:HystrixRuntimeException
一檢查我們系統(tǒng)確實(shí)沒(méi)有指定fallback和configuration,并且調(diào)用方開(kāi)啟了feign.hystrix.enabled: true
@FeignClient(value = "taxplan-workflow")
修改方法:
第三方調(diào)用在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攔截器,可以定制請(qǐng)求頭,如果不想定制,可以改為
return Feign.builder().errorDecoder(new CustomErrorDecoder());
實(shí)現(xiàn)ErrorDecoder接口,其中ExceptionCode是枚舉類(lèi).
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枚舉類(lèi)如下:可以自定義增加刪除
public enum ExceptionCode { ILLEGAL_STATE(4001, "非法訪問(wèn)"), PARAM_REQUIRED(4002, "參數(shù)不能為空"), PARAM_FORMAT_ILLEGAL(4003, "參數(shù)格式錯(cuò)誤"), REQUEST_DATA_DUPLICATION(4004, "重復(fù)請(qǐng)求"), REQUEST_DATA_ERROR(4005, "請(qǐng)求數(shù)據(jù)錯(cuò)誤"), REQUEST_DATA_NOT_MATCH(4006, "請(qǐng)求數(shù)據(jù)不一致"), RECORD_NOT_EXIST(5001, "記錄不存在"), RECORD_EXISTED(5002, "記錄已存在"), RECORD_ILLEGAL_STATE(5003, "數(shù)據(jù)異常"), BALANCE_NOT_ENOUGH(5103, "余額不足"), CALL_INNER_ERROR(5800, "調(diào)用內(nèi)部服務(wù)接口異常"), THIRD_PART_ERROR(5801, "調(diào)用第三方接口異常"), SYSTEM_ERROR(9999, "系統(tǒng)異常"); public final int code; public final String defaultMessage; private ExceptionCode(int code, String defaultMessage) { this.code = code; this.defaultMessage = defaultMessage; } }
“Feign調(diào)用全局異常處理的解決方法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。