zoukankan      html  css  js  c++  java
  • spring cloud feign客户端调用JSON数据接口对自定义类型反序列化失败源码分析

    源码

    • org.springframework.cloud.openfeign.support.SpringDecoder
    // 解码响应信息
    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
    // 处理响应数据
    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
    // 此方法判断媒体类型是否可读取,值类型是否可以反序列化
    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
    // 查询对于值类型是否存在反序列化器
    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;
    }
    
  • 相关阅读:
    C语言指针强制类型转换
    iphone开发实现单选框
    深入研究java.lang.Runtime类
    hoj 1760 The jackpot一维
    人生最有趣味的事
    GAE 博客——B3log Solo 0.3.0 正式版发布了!
    “三国演义”何处去
    boost库中的智能指针向上转换
    GAE 博客——B3log Solo 0.3.5 正式版发布了!
    GAE 博客——B3log Solo 0.3.0 正式版发布了!
  • 原文地址:https://www.cnblogs.com/luguojun/p/14294728.html
Copyright © 2011-2022 走看看