前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring cloud feign客户端调用JSON数据接口对自定义类型反序列化失败源码分析

spring cloud feign客户端调用JSON数据接口对自定义类型反序列化失败源码分析

作者头像
路过君
发布2020-06-19 16:43:05
3.8K0
发布2020-06-19 16:43:05
举报
文章被收录于专栏:路过君BLOG from CSDN

源码

  • org.springframework.cloud.openfeign.support.SpringDecoder
代码语言:javascript
复制
// 解码响应信息
public Object decode(final Response response, Type type)
			throws IOException, FeignException {
if (type instanceof Class || type instanceof ParameterizedType
			|| type instanceof WildcardType) {
		@SuppressWarnings({ "unchecked", "rawtypes" })
		HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
				type, this.messageConverters.getObject().getConverters());
		// 处理响应数据
		return extractor.extractData(new FeignResponseAdapter(response));
	}
	throw new DecodeException(response.status(),
			"type is not an instance of Class or ParameterizedType: " + type,
			response.request());
}
  • org.springframework.web.client.HttpMessageConverterExtractor
代码语言:javascript
复制
// 处理响应数据
public T extractData(ClientHttpResponse response) throws IOException {
	MessageBodyClientHttpResponseWrapper responseWrapper = new MessageBodyClientHttpResponseWrapper(response);
	if (!responseWrapper.hasMessageBody() || responseWrapper.hasEmptyMessageBody()) {
		return null;
	}
	MediaType contentType = getContentType(responseWrapper);

	try {
		for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
			if (messageConverter instanceof GenericHttpMessageConverter) {
				GenericHttpMessageConverter<?> genericMessageConverter =
						(GenericHttpMessageConverter<?>) messageConverter;
				// 调用MessageConverter判断是否支持反序列化
				if (genericMessageConverter.canRead(this.responseType, null, contentType)) {
					if (logger.isDebugEnabled()) {
						ResolvableType resolvableType = ResolvableType.forType(this.responseType);
						logger.debug("Reading to [" + resolvableType + "]");
					}
					return (T) genericMessageConverter.read(this.responseType, null, responseWrapper);
				}
			}
			if (this.responseClass != null) {
				if (messageConverter.canRead(this.responseClass, contentType)) {
					if (logger.isDebugEnabled()) {
						String className = this.responseClass.getName();
						logger.debug("Reading to [" + className + "] as \"" + contentType + "\"");
					}
					return (T) messageConverter.read((Class) this.responseClass, responseWrapper);
				}
			}
		}
	}
	catch (IOException | HttpMessageNotReadableException ex) {
		throw new RestClientException("Error while extracting response for type [" +
				this.responseType + "] and content type [" + contentType + "]", ex);
	}

	throw new RestClientException("Could not extract response: no suitable HttpMessageConverter found " +
			"for response type [" + this.responseType + "] and content type [" + contentType + "]");
}
  • org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter
代码语言:javascript
复制
// 此方法判断媒体类型是否可读取,值类型是否可以反序列化
public boolean canRead(Type type, @Nullable Class<?> contextClass, @Nullable MediaType mediaType) {
	if (!canRead(mediaType)) {
		return false;
	}
	JavaType javaType = getJavaType(type, contextClass);
	AtomicReference<Throwable> causeRef = new AtomicReference<>();
	if (this.objectMapper.canDeserialize(javaType, causeRef)) {
		return true;
	}
	// 如果无法反序列化,此处对无法支持反序列化的异常进行捕获并输出日志(此处日志级别为DEBUG)
	logWarningIfNecessary(javaType, causeRef.get());
	return false;
}
  • com.fasterxml.jackson.databind.DeserializationContext
代码语言:javascript
复制
// 查询对于值类型是否存在反序列化器
public boolean hasValueDeserializerFor(JavaType type, AtomicReference<Throwable> cause) {
  try {
        return _cache.hasValueDeserializerFor(this, _factory, type);
    } catch (JsonMappingException e) {
    	// 如果不支持反序列化,抛出异常在此处捕获并注入到cause中
        if (cause != null) {
            cause.set(e);
        }
    } catch (RuntimeException e) {
        if (cause == null) { // earlier behavior
            throw e;
        }
        cause.set(e);
    }
    return false;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/05/29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 源码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档