问题
feign调用后,服务端返回FeignExecption:500 FeignClient.FunctionName
FeignClient添加配置处理类
@FeignClient(value = "serviceName",configuration = FeignExceptionConfiguration.class)
实现fegin的异常处理类,具体实现类:
import feign.Util;
import feign.codec.ErrorDecoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.springframework.context.annotation.Bean;
@Slf4j
public class FeignExceptionConfiguration {
@Bean
public ErrorDecoder errorDecoder() {
return new UserErrorDecoder();
}
/**
* 重新实现feign的异常处理,捕捉restful接口返回的json格式的异常信息
*
*/
public class UserErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
Exception exception = null;
ObjectMapper mapper = new ObjectMapper();
//空属性处理
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_EMPTY);
//设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//禁止使用int代表enum的order来反序列化enum
mapper.configure(DeserializationConfig.Feature.FAIL_ON_NUMBERS_FOR_ENUMS, true);
try {
String json = Util.toString(response.body().asReader());
exception = new RuntimeException(json);
if (StringUtils.isEmpty(json)) {
return null;
}
FeignFaildResult result = mapper.readValue(json, FeignFaildResult.class);
// 业务异常包装成自定义异常类MyException
if (result.getStatus() != HttpStatus.OK.value()) {
exception = new MyException(result.getMessage(),result.getStatus());
}
} catch (IOException ex) {
log.error(ex.getMessage(), ex);
}
return exception;
}
}
}
异常json数据格式化java对象:
String json = Util.toString(response.body().asReader());
/**
* 根据 json 来定义需要的字段
*/
@Data
public class FeignFaildResult {
private String message;
private int status;
}
这么一来,服务端返回的异常就可以在调用端统一封装为自定义异常类MyException
public class MyException extends RuntimeException {
// 自定义异常代码
private int status = 503;
// 构造方法
public MyException(String message, int status) {
super(message);
this.status = status;
}
}