概要
` 提示:restTemplate,messageConverters
概要:
restTemplate当没有指定contentType的时候。 会根据对应的messageConverters 循环比对,拿到对应的解析器。当引入其他包的时候,可能会导致对应解析器出错导致异常。小编此时是因为引入了一个com.huaweicloud.sdk相关的jar包。 对应包中含有
com.fasterxml.jackson.dataformat.xml.XmlMapper 对应类。以至于加载进来了MappingJackson2XmlHttpMessageConverter。
他和MappingJackson2HttpMessageConverter 对应 if (messageConverter instanceof GenericHttpMessageConverter) 为true.
又因其加载顺序在json之前。 没有指定对应contentType的情况下走到了xml。 导致对应的错误异常。 因此通过源码来探寻一番。给大伙儿避避坑
整体架构流程
当restTemplate初始化的时候。会新增加对应默认的解析器。
其中对应有的converter是根据对应包中是否有加载到对应的类来决定。
其中当restTemplate调用restTemplate.postForEntity等方法的时候。 跟进对应代码可以发现
``
此刻会把对应加载的messageConverters加载到对应的 Extractor中。 调用对应的execute方法。
当没有指定contentType的时候。
当没有引入对应其他jar包的时候。默认的解析器为下图:
当引入其他jar包的时候。
这里第6个位置的数据已经发生了变化。 当调用restTemplate继续发送的时候。没有指定对应contentType。
对应的write中。 会去addDefaultHeaders.其中
其中会拿到对应MappingJackson2XmlHttpMessageConverter初始化
对应这个类初始化的时候是
public MappingJackson2XmlHttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper, new MediaType(“application”, “xml”),
new MediaType(“text”, “xml”),
new MediaType(“application”, “*+xml”));
Assert.isInstanceOf(XmlMapper.class, objectMapper, “XmlMapper required”);
}
其中会get(0).拿到application/xml塞入对应的contentType。 以及用MappingJackson2XmlHttpMessageConverter进行解析。
List mediaTypes = getSupportedMediaTypes();
return (!mediaTypes.isEmpty() ? mediaTypes.get(0) : null);
所以会出异常。
如果指定了对应的contentType。 则循环解析器的同时。会canWrite里面对应传递的contentType。其中解析器中是否匹配。
小结
`当使用restTemplate的时候,注意指定对应的contentType.以免引入jar包的时候无感知的被影响。
也可以在项目中自己创建对应的restTemplateBean。提前指定好对应项目中的使用。 不过相对扩展性不太好。