赞
踩
现象
在spring cloud gateway中使用fegin调用服务时,返回时报错。
feign.codec.DecodeException: No qualifying bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:182)
原因分析
feign中对返回的数据进行解析时,缺少依赖对象导致。
feign对返回信息response解析
package org.springframework.cloud.openfeign.support;
...
public class SpringDecoder implements Decoder {
...
public Object decode(final Response response, Type type) throws IOException, FeignException {
if (!(type instanceof Class) && !(type instanceof ParameterizedType) && !(type instanceof WildcardType)) {
throw new DecodeException(response.status(), "type is not an instance of Class or ParameterizedType: " + type, response.request());
} else {
//异常处
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(type, ((HttpMessageConverters)this.messageConverters.getObject()).getConverters());
return extractor.extractData(new SpringDecoder.FeignResponseAdapter(response));
}
}
...
}
Spring内部方法验证
package org.springframework.beans.factory.support;
...
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
...
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
//此处判断HttpMessageConverters未加载导致异常
if (this.isRequired(descriptor)) {
this.raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
...
return autowiredBeanName;
}
...
}
处理办法
feign配置中增加HttpMessageConverters即可。
import feign.codec.Decoder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.ArrayList;
import java.util.List;
/**
* @description: feign配置
* @author: lizz
* @date: 2020/4/23 2:32 下午
*/
@SpringBootConfiguration
public class FeignConfig {
@Bean
public Decoder feignDecoder() {
return new ResponseEntityDecoder(new SpringDecoder(feignHttpMessageConverter()));
}
public ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(new GateWayMappingJackson2HttpMessageConverter());
return new ObjectFactory<HttpMessageConverters>() {
@Override
public HttpMessageConverters getObject() throws BeansException {
return httpMessageConverters;
}
};
}
public class GateWayMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
GateWayMappingJackson2HttpMessageConverter(){
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.valueOf(MediaType.TEXT_HTML_VALUE + ";charset=UTF-8"));
setSupportedMediaTypes(mediaTypes);
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。