Feign调用接口解决处理内部异常的问题

更新时间:2023-05-24 02:57:48 阅读: 评论:0

Feign调⽤接⼝解决处理内部异常的问题
问题描述:
当使⽤feign调⽤接⼝,出现400~500~的接⼝问题时。会出错feign:FeignException。(因为是错误,只能⽤catch Throwable,不可使⽤catch Exception捕获异常)导致程序⽆法继续运⾏。
问题原因:
由于feign默认的错误处理类是FunFeignFallback会throw new AfsBaExceptio导致外部⽆法捕获异常。
package com.ruicar.feign;
import com.alibaba.fastjson.JSONObject;
import com.ruicar.xception.AfsBaException;
import com.ruicar.util.IRespon;
import feign.FeignException;
import lombok.AllArgsConstructor;
import lombok.Data;
slf4j.Slf4j;
import lib.proxy.MethodInterceptor;
import lib.proxy.MethodProxy;
import org.springframework.lang.Nullable;
import flect.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 cau;
private static byte JSON_START = '{';
@Nullable
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
String errorMessage = Message();
if (!(cau instanceof FeignException)) {
<("FunFeignFallback:[{}.{}] rviceId:[{}] message:[{}]", Name(), Name(), targetName, errorMessage);            ("feign调⽤失败", cau);
return IRespon.fail("请求失败,请稍后再试");
}
int status = ((FeignException.FeignClientException) this.cau).status();
boolean isAuthFail = (status==426||status==403||status==401)&&"afs-auth".equals(targetName);
FeignException exception = (FeignException) cau;
if(isAuthFail){
log.warn("授权失败==========原始返回信息:[{}]",tUTF8());
}el {
<("FunFeignFallback:[{}.{}] rviceId:[{}] message:[{}]", Name(), Name(), targetName, errorMessage);            ("", cau);
<("原始返回信息{}",tUTF8());
}
ReturnType().equals(Void.class)){
throw new AfsBaException("接⼝调⽤失败");
}
ReturnType().equals(IRespon.class)){
if(exception instanceof FeignException.Forbidden){
return IRespon.fail("没有权限").tCode("403");
}
if(exception instanceof FeignException.NotFound){
return IRespon.fail("请求路径不存在").tCode("404");
}
if(exception instanceof FeignException.BadRequest){
return IRespon.fail("参数错误").tCode("400");
}
t()==null||t().length==0){
return IRespon.fail("请求失败,请稍后再试");
}
if(JSON_START==t()[0]){
return JSONObject.t(),IRespon.class);
}el{
return IRespon.tUTF8());
}
}el{
try {
ReturnType().equals(String.class)){
tUTF8();
}el ReturnType().equals(JSONObject.class)){
if(JSON_START==t()[0]){
return JSONObject.t(), JSONObject.class);
}
}el if(!ReturnType().equals(Object.class)){
return JSONObject.t(), ReturnType());
}
if(JSON_START==t()[0]){
JSONObject jsonObject = JSONObject.t(), JSONObject.class);                    ainsKey("code")&&ainsKey("msg")) {
JavaObject(IRespon.class);
}
}
}catch (Throwable e){}
英文月份
throw new AfsBaException("接⼝调⽤失败");
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return fal;
}
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.tCau(throwable);
return invoiceApiFeignFallback;
}
}
2.feign调⽤ InvoiceApiFeignFallbackFactory
package com.ruicar.afs.cloud.invoice.feign;
import com.alibaba.fastjson.JSONObject;
import com.ruicar.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;
pillowfightimport org.springframework.web.bind.annotation.RequestHeader;
import java.util.Map;
/**
* @description: 发票验证接⼝
* @author: rongji.zhang
val* @date: 2020/8/14 10:32
*/
@FeignClient(name = "invoice", url = "${atwall.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;
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 cau;
/**
* @param dto
* @param headers
* @return
*/
@Override
public JSONObject InvoiceCheck(InvoiceCheckDto dto, Map<String, String> headers) {
<("feign 接⼝调⽤失败", cau);
return null;
}
}
Feign远程调⽤失败-----丢请求头
山市翻译
@FeignClient("guli-cart")
public interface CartFenignService {
@GetMapping("/currentUrCartItems")
List<OrderItemVo> getCurrentUrCartItems();
}// 这样去掉接⼝时其实Feign在底层是⼀个全新的requst所有请求头就没有了
解决办法使⽤Feign远程掉⽤拦截器,在远程请求是先创建拦截器
@Bean("requestInterceptor")
public RequestInterceptor requestInterceptor() {
return new RequestInterceptor() {
how do you do @Override
public void apply(RequestTemplate template) {
/**
* 把以前的Cookie放到新请求中去原理就是运⽤了同⼀线程数据共享  ThreadLocal
*/
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestAttributes();
HttpServletRequest request = Request();
String cookie = Header("Cookie");
template.header("Cookie", cookie);
}
};
}
但是上⾯的办法只能解决同意线程问题,在多线程下还是会丢失请求头多线程下解决办法:
RequestAttributes requestAttributes = RequestAttributes();把请求单独拿出来给每个线程单独
RequestContextHolder.tRequestAttributes(requestAttributes);
这样就可以了~
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

本文发布于:2023-05-24 02:57:48,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/120338.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:请求   问题   远程   解决   定义   处理
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图