Feign 호출 인터페이스 로 내부 이상 처리
feign 호출 인 터 페 이 스 를 사용 하면 400~500~의 인터페이스 문제 가 발생 할 때.오류 발생 feign:FeignException.(오류 로 인해 catch Throwable 만 사용 할 수 있 고 catch Exception 으로 이상 을 포착 할 수 없습니다)프로그램 이 계속 실 행 될 수 없습니다.
문제 의 원인:
feign 의 기본 오류 처리 클래스 가 FunFeignFallback 이기 때문에 throw new AfsBaseExceptio 로 인해 외부 에서 이상 을 포착 할 수 없습니다.
package com.ruicar.afs.cloud.common.core.feign;
import com.alibaba.fastjson.JSONObject;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import feign.FeignException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.lang.Nullable;
import java.lang.reflect.Method;
import java.util.Objects;
@Data
@AllArgsConstructor
@Slf4j
public class FunFeignFallback<T> implements MethodInterceptor {
private final Class<T> targetType;
private final String targetName;
private final Throwable cause;
private static byte JSON_START = '{';
@Nullable
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
String errorMessage = cause.getMessage();
if (!(cause instanceof FeignException)) {
log.error("FunFeignFallback:[{}.{}] serviceId:[{}] message:[{}]", targetType.getName(), method.getName(), targetName, errorMessage);
log.error("feign ", cause);
return IResponse.fail(" , ");
}
int status = ((FeignException.FeignClientException) this.cause).status();
boolean isAuthFail = (status==426||status==403||status==401)&&"afs-auth".equals(targetName);
FeignException exception = (FeignException) cause;
if(isAuthFail){
log.warn(" ========== :[{}]",exception.contentUTF8());
}else {
log.error("FunFeignFallback:[{}.{}] serviceId:[{}] message:[{}]", targetType.getName(), method.getName(), targetName, errorMessage);
log.error("", cause);
log.error(" {}",exception.contentUTF8());
}
if(method.getReturnType().equals(Void.class)){
throw new AfsBaseException(" ");
}
if(method.getReturnType().equals(IResponse.class)){
if(exception instanceof FeignException.Forbidden){
return IResponse.fail(" ").setCode("403");
}
if(exception instanceof FeignException.NotFound){
return IResponse.fail(" ").setCode("404");
}
if(exception instanceof FeignException.BadRequest){
return IResponse.fail(" ").setCode("400");
}
if(exception.content()==null||exception.content().length==0){
return IResponse.fail(" , ");
}
if(JSON_START==exception.content()[0]){
return JSONObject.parseObject(exception.content(),IResponse.class);
}else{
return IResponse.fail(exception.contentUTF8());
}
}else{
try {
if(method.getReturnType().equals(String.class)){
return exception.contentUTF8();
}else if(method.getReturnType().equals(JSONObject.class)){
if(JSON_START==exception.content()[0]){
return JSONObject.parseObject(exception.content(), JSONObject.class);
}
}else if(!method.getReturnType().equals(Object.class)){
return JSONObject.parseObject(exception.content(), method.getReturnType());
}
if(JSON_START==exception.content()[0]){
JSONObject jsonObject = JSONObject.parseObject(exception.content(), JSONObject.class);
if(jsonObject.containsKey("code")&&jsonObject.containsKey("msg")) {
return jsonObject.toJavaObject(IResponse.class);
}
}
}catch (Throwable e){}
throw new AfsBaseException(" ");
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
FunFeignFallback<?> that = (FunFeignFallback<?>) o;
return targetType.equals(that.targetType);
}
@Override
public int hashCode() {
return Objects.hash(targetType);
}
}
문제 해결:사용자 정의 feignFallback 이상 처리:1.사용자 정의 이상 처리 InvoiceApiFeignFallbackFactory
package com.ruicar.afs.cloud.invoice.factory;
import com.ruicar.afs.cloud.invoice.fallback.InvoiceApiFeignFallback;
import com.ruicar.afs.cloud.invoice.feign.InvoiceApiFeign;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
@Component
public class InvoiceApiFeignFallbackFactory implements FallbackFactory<InvoiceApiFeign> {
@Override
public InvoiceApiFeign create(Throwable throwable) {
InvoiceApiFeignFallback invoiceApiFeignFallback = new InvoiceApiFeignFallback();
invoiceApiFeignFallback.setCause(throwable);
return invoiceApiFeignFallback;
}
}
2.feign 호출 Invoice ApiFeignFallback Factory
package com.ruicar.afs.cloud.invoice.feign;
import com.alibaba.fastjson.JSONObject;
import com.ruicar.afs.cloud.common.core.feign.annotations.AfsFeignClear;
import com.ruicar.afs.cloud.invoice.dto.InvoiceCheckDto;
import com.ruicar.afs.cloud.invoice.factory.InvoiceApiFeignFallbackFactory;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import java.util.Map;
/**
* @description:
* @author: rongji.zhang
* @date: 2020/8/14 10:32
*/
@FeignClient(name = "invoice", url = "${com.greatwall.systems.invoice-system.url}" ,fallbackFactory = InvoiceApiFeignFallbackFactory.class)
public interface InvoiceApiFeign {
/**
*
* @param dto
* @return
*/
@ApiOperation(" API ")
@PostMapping(value = "/vi/check")
@AfsFeignClear(true)// token
JSONObject InvoiceCheck(@RequestBody InvoiceCheckDto dto, @RequestHeader Map<String, String> headers);
}
3.사용자 정의 오류 처리 실현
package com.ruicar.afs.cloud.invoice.fallback;
import com.alibaba.fastjson.JSONObject;
import com.ruicar.afs.cloud.invoice.dto.InvoiceCheckDto;
import com.ruicar.afs.cloud.invoice.feign.InvoiceApiFeign;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author Fzero
* @date 2019-01-24
*/
@Slf4j
@Component
public class InvoiceApiFeignFallback implements InvoiceApiFeign {
@Setter
private Throwable cause;
/**
* @param dto
* @param headers
* @return
*/
@Override
public JSONObject InvoiceCheck(InvoiceCheckDto dto, Map<String, String> headers) {
log.error("feign ", cause);
return null;
}
}
Feign 원 격 호출 실패
@FeignClient("guli-cart")
public interface CartFenignService {
@GetMapping("/currentUserCartItems")
List<OrderItemVo> getCurrentUserCartItems();
}// Feign requst
해결 방법 Feign 원 격 차단 기 를 사용 합 니 다.원 격 요청 시 차단 기 를 먼저 만 듭 니 다.
@Bean("requestInterceptor")
public RequestInterceptor requestInterceptor() {
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
/**
* Cookie ThreadLocal
*/
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String cookie = request.getHeader("Cookie");
template.header("Cookie", cookie);
}
};
}
그러나 위의 방법 은 동의 스 레 드 문 제 를 해결 할 수 있 을 뿐 다 중 스 레 드 에서 요청 헤드 를 잃 어 버 릴 수 있 습 니 다.다 중 스 레 드 에서 해결 방법:
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
요청 을 따로 꺼 내 서 스 레 드 마다 따로 드 리 겠 습 니 다.
RequestContextHolder.setRequestAttributes(requestAttributes);
이렇게 하면 돼~이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
SpringCloud 통합 JPA Feign 원격 호출 보고서 415 Unsupported Media Type이상은 오류 정보입니다. 검사할 때 POST 전참 오류인 줄 알았습니다. 컨슈머 feign 인터페이스 인터페이스 공급자 왜냐하면 이전에 전달 대상을 호출해도 문제가 없었기 때문에 모든 것을 실체류에서 찾았어요. 갑자...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.