【原创】大叔问题定位分享(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 ...
随机推荐
- shell脚本编程进阶
在linux shell中,通常我们将一些命令写在一个文件中就算是一个shell脚本了,但是如果需要执行更为复杂的逻辑判断,我们就需要使用流程控制语句来支持了.所谓流程控制既是通过使用流程控制语句对程 ...
- Qt图形测绘窗口部件介绍
Qt 图形测绘窗口部件,主要使用第三方窗口部件: 1.Qwt:http://qwt.sourceforge.net 开源免费 2.GraphPak: http://www.ics.com 收费 3. ...
- 阿里云 docker image 加速
使用的国内网络下载docker image太困难了,简直龟速,于是上网查看如何加速docker image的下载,没想到网上还真有,看来现在自己的知识圈子太小了,还需要多接触新的知识.找到第一个atu ...
- PHP中的src32
crc32() 函数计算一个字符串的 crc32 多项式. 该函数可用于验证数据的完整性. 语法 crc32(str 参数 描述 string 必需.规定要计算的字符串. 说明 生成 string 参 ...
- 微信小程序之状态管理A
其实这个标题 不是很对 主要是最近小程序项目中 有这么一个状态 所有商品都共用一个商品详情页面 大概就是这样子 为了公司 保险起见,一些展示的内容已经处理 但是无伤大雅 就是这么两个按钮 左侧粉色 ...
- P2602 [ZJOI2010]数字计数&P1239 计数器&P4999 烦人的数学作业
P2602 [ZJOI2010]数字计数 题解 DFS 恶心的数位DP 对于这道题,我们可以一个数字一个数字的求 也就是分别统计区间 [ L , R ] 内部数字 i 出现的次数 (0<=i&l ...
- Android解决AVD Hardware Buttons 和DPAD无法使用问题
如图所示按键用鼠标点击时无法响应. 解决方案: 以我创建的AVD名为Tablet为例 1.找到用户目录(我的用户目录yummy),然后进入如下目录 mac: ~/yummy/.android/avd/ ...
- react+laravel与服务端渲染的几点思考
一.前后端完全分离 1.用React.js做MVC中的V,剩下的交给Laravel 2.Laravel用来做API接口开发. 3.好处:实现了前后端开发的分离,从而加快前后端开发效率.另外若是多端的如 ...
- Oracle事务、视图、序列
回顾什么是事务? 一个不可分割的子操作形成一个整体,该整体要么全部执行成功,要么全部执行失败.例如:转帐 回顾为什么要用事务? 如果不用事务的话,为转帐为例,可能出现一个用户钱增加了,另一个用户钱不变 ...
- 利用phpStudy 探针 提权网站服务器
声明: 本教程仅仅是演示管理员安全意识不强,存在弱口令情况.网站被非法入侵的演示,请勿用于恶意用途! 今天看到论坛有人发布了一个通过这phpStudy 探针 关键字搜索检索提权网址服务器,这个挺简单的 ...