【原创】大叔问题定位分享(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即可;
【原创】大叔问题定位分享(34)Spring的RestTemplate请求json数据后内容被修改的更多相关文章
- Spring使用fastjson处理json数据
1.搭建SpringMVC+spring环境 2.配置web.xml以及springmvc-config.xml,web.xml同Spring使用jackson处理json数据一样,Springmvc ...
- Spring使用Jackson处理json数据
1.搭建SpringMVC+Spring环境 2.配置web.xml.SpringMVC-config.xml <?xml version="1.0" encoding=&q ...
- Spring mvc,jQuery和JSON数据交互
一.实验环境的搭建 1.Spring mvc jar. 导入spring mvc运行所需jar包.导入如下(有多余) 2.json的支持jar 3.加入jQuery. 选用jquery-3.0.0.m ...
- Spring boot之返回json数据
1.步骤: 1. 编写实体类Demo 2. 编写getDemo()方法 3. 测试 2.项目构建 编写实体类Demo package com.kfit; /** * 这是一个测试实体类. */ pub ...
- 【原创】大叔问题定位分享(35)spring中session失效时间
spring项目中将sessionid对应的cookie过期时间设置很长,但是实际session还是在半个小时后失效,跟了一下代码,spring中session实现接口为 org.springfram ...
- 【原创】大叔问题定位分享(6)Dubbo monitor服务iowait高,负载高
一 问题 Dubbo monitor所在服务器状态异常,iowait一直很高,load也一直很高,监控如下: iowait如图: load如图: 二 分析 通过iotop命令可以查看当前系统中磁盘io ...
- 【原创】大叔问题定位分享(3)Kafka集群broker进程逐个报错退出
kafka0.8.1 一 问题现象 生产环境kafka服务器134.135.136分别在10月11号.10月13号挂掉: 134日志 [2014-10-13 16:45:41,902] FATAL [ ...
- 【原创】大叔问题定位分享(1)HBase RegionServer频繁挂掉
最近hbase集群很多region server挂掉,查看其中一个RegionServer1日志发现,17:17:14挂的时候服务器压力很大,有大量的responseTooSlow,也有不少gc,但是 ...
- 【原创】大叔问题定位分享(30)mesos agent启动失败:Failed to perform recovery: Incompatible agent info detected
mesos agent启动失败,报错如下: Feb 15 22:03:18 server1.bj mesos-slave[1190]: E0215 22:03:18.622994 1192 slave ...
随机推荐
- Ubuntu 配置ISCSI服务
摘要:sudo apt-get install iscsitarget立刻搞定, 然后编辑配置文件:sudovim/etc/ietd.conf默认的配置文件, 有详细的配置说明和示例,本博先备份了事, ...
- Qt 字符串QString arg()用法总结
1.QString::arg()//用字符串变量参数依次替代字符串中最小数值 QString i = "iTest"; // current file's nu ...
- rocketmq备忘
rocketmq unrecognized VM option 'MetaspaceSize=128m' => jdk1.8 JAVA_HOME https://blog.csdn.net/c3 ...
- mac 配置apache
Apache配置 对httpd.conf文件的配置.首先打开 /etc/apache2/httpd.conf文件,也就是Apache2.4的相关配置文件. 连接php 首先我们将相应的PHP版本配置进 ...
- SSM整合junit单元测试之org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
想用SSM做一点小测试,项目整合完毕,直接使用junit测试mybatis,出现如下错误(SuperTest类中进行了spring运行环境加载): 解决思路: 检查mapper接口与mapper.xm ...
- Vue+element 需要用到拖拽组件 vuedraggable
新需求是要求界面上的14个可以拖拽,点击保存之后保存拖拽之后的顺序. 确定需求之后肯定第一时间是百度,发现有个插件vuedragger拖拽,按照教程就懵懂的开始了. 官方示例:https://davi ...
- Linux(CentOS)下安装tesseract-ocr以及配置依赖leptonica
下载 wget https://github.com/tesseract-ocr/tesseract/archive/4.1.0.tar.gz wget http://www.leptonica.or ...
- loadrunner脚本因为没有token报错
目录 场景 解决过程 解决方案 总结 场景 用loadrunner11录制脚本,处理后回放,加上检查点,报错找不到检查点对应的内容,去掉检查点,没有报错,但是打开页面没有该操作的痕迹.手动在页面上操作 ...
- python基础学习19,01
听说python入门很容易,所以想试试对我这个零基础会不会很友好呢.做随笔也顺便督促自己不要轻易放弃学习. #登录接口 print("请输入用户名密码") _username = ...
- 如何查看linux系统安装时间
第一种方法: 先查看系统盘挂到哪个分区上,然后用 dumpe2fs 查看这个磁盘分区 创建的时间,即可查出此 服务器 系统安装的时间.() # dumpe2fs /dev/sda3|grep -i ...