zoukankan      html  css  js  c++  java
  • 【原创】大叔问题定位分享(34)Spring的RestTemplate请求json数据后内容被修改

    先看代码

    org.springframework.web.client.RestTemplate

        public RestTemplate() {
            this.messageConverters = new ArrayList();
            this.errorHandler = new DefaultResponseErrorHandler();
            this.headersExtractor = new RestTemplate.HeadersExtractor();
            this.messageConverters.add(new ByteArrayHttpMessageConverter());
            this.messageConverters.add(new StringHttpMessageConverter());
            this.messageConverters.add(new ResourceHttpMessageConverter(false));
    
            try {
                this.messageConverters.add(new SourceHttpMessageConverter());
            } catch (Error var2) {
                ;
            }
    
            this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
            if(romePresent) {
                this.messageConverters.add(new AtomFeedHttpMessageConverter());
                this.messageConverters.add(new RssChannelHttpMessageConverter());
            }
    
            if(jackson2XmlPresent) {
                this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
            } else if(jaxb2Present) {
                this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
            }
    
            if(jackson2Present) {
                this.messageConverters.add(new MappingJackson2HttpMessageConverter());
            } else if(gsonPresent) {
                this.messageConverters.add(new GsonHttpMessageConverter());
            } else if(jsonbPresent) {
                this.messageConverters.add(new JsonbHttpMessageConverter());
            }
    
            if(jackson2SmilePresent) {
                this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
            }
    
            if(jackson2CborPresent) {
                this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());
            }
    
            this.uriTemplateHandler = initUriTemplateHandler();
        }

    构造函数中会根据各种boolean标志添加很多MessageConverter,而这些boolean标志来自

        static {
            ClassLoader classLoader = RestTemplate.class.getClassLoader();
            romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader);
            jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader);
            jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
            jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
            jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
            jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader);
            gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader);
            jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader);
        }

    在发请求时

        public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException {
            RequestCallback requestCallback = this.httpEntityCallback(request, responseType);
            ResponseExtractor<ResponseEntity<T>> responseExtractor = this.responseEntityExtractor(responseType);
            return (ResponseEntity)nonNull(this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables));
        }

    会创建一个ResponseExtractor

        private class ResponseEntityResponseExtractor<T> implements ResponseExtractor<ResponseEntity<T>> {
            @Nullable
            private final HttpMessageConverterExtractor<T> delegate;
    
            public ResponseEntityResponseExtractor(@Nullable Type responseType) {
                if(responseType != null && Void.class != responseType) {
                    this.delegate = new HttpMessageConverterExtractor(responseType, RestTemplate.this.getMessageConverters(), RestTemplate.this.logger);
                } else {
                    this.delegate = null;
                }
    
            }

    可见是根据responseType创建了一个代理,然后代理中包含了所有添加过的MessageConverter

    而在execute中会调用

        protected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
            Assert.notNull(url, "URI is required");
            Assert.notNull(method, "HttpMethod is required");
            ClientHttpResponse response = null;
    
            Object var14;
            try {
                ClientHttpRequest request = this.createRequest(url, method);
                if(requestCallback != null) {
                    requestCallback.doWithRequest(request);
                }
    
                response = request.execute();
                this.handleResponse(url, method, response);
                var14 = responseExtractor != null?responseExtractor.extractData(response):null;

    即responseExecutor.extractData,来看下这个函数

        public T extractData(ClientHttpResponse response) throws IOException {
            MessageBodyClientHttpResponseWrapper responseWrapper = new MessageBodyClientHttpResponseWrapper(response);
            if(responseWrapper.hasMessageBody() && !responseWrapper.hasEmptyMessageBody()) {
                MediaType contentType = this.getContentType(responseWrapper);
    
                try {
                    Iterator var4 = this.messageConverters.iterator();
    
                    while(var4.hasNext()) {
                        HttpMessageConverter<?> messageConverter = (HttpMessageConverter)var4.next();
                        if(messageConverter instanceof GenericHttpMessageConverter) {
                            GenericHttpMessageConverter<?> genericMessageConverter = (GenericHttpMessageConverter)messageConverter;
                            if(genericMessageConverter.canRead(this.responseType, (Class)null, contentType)) {
                                if(this.logger.isDebugEnabled()) {
                                    ResolvableType resolvableType = ResolvableType.forType(this.responseType);
                                    this.logger.debug("Reading to [" + resolvableType + "]");
                                }
    
                                return genericMessageConverter.read(this.responseType, (Class)null, responseWrapper);
                            }
                        }
    
                        if(this.responseClass != null && messageConverter.canRead(this.responseClass, contentType)) {
                            if(this.logger.isDebugEnabled()) {
                                String className = this.responseClass.getName();
                                this.logger.debug("Reading to [" + className + "] as "" + contentType + """);
                            }
    
                            return messageConverter.read(this.responseClass, responseWrapper);
                        }
                    }
                } catch (HttpMessageNotReadableException | IOException var8) {
                    throw new RestClientException("Error while extracting response for type [" + this.responseType + "] and content type [" + contentType + "]", var8);
                }
    
                throw new RestClientException("Could not extract response: no suitable HttpMessageConverter found for response type [" + this.responseType + "] and content type [" + contentType + "]");
            } else {
                return null;
            }
        }

    所以当你发现使用RestTemplate发请求后数据被修改的时候,要检查相应的content type,要检查RestTemplate中有哪些MessageConverter(包括各个boolean标志),

    如果确定数据不需要被修改时,可以调用RestTemplate.setMessageConverters方法,传入默认的StringHttpMessageConverter即可;

  • 相关阅读:
    topcoder srm 681 div1
    topcoder srm 683 div1
    topcoder srm 684 div1
    topcoder srm 715 div1
    topcoder srm 685 div1
    topcoder srm 687 div1
    topcoder srm 688 div1
    topcoder srm 689 div1
    topcoder srm 686 div1
    topcoder srm 690 div1 -3
  • 原文地址:https://www.cnblogs.com/barneywill/p/11141164.html
Copyright © 2011-2022 走看看