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;
    }
    
  • 相关阅读:
    spring-cloud服务器雪崩效应
    zookeeper集群
    Hash表的扩容(转载)
    算法时间复杂度和空间复杂度的计算
    Java 8 新特性
    jdk8 流操作
    jdk8十大特性并代码demo(转)
    hashmap实现原理2
    hashmap实现原理
    Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行
  • 原文地址:https://www.cnblogs.com/luguojun/p/14294728.html
Copyright © 2011-2022 走看看