Spring RestTemplate为何必须搭配MultiValueMap?

简介: 微服务之间的大多都是使用 HTTP 通信,这自然少不了使用 HttpClient。在不适用 Spring 前,一般使用 Apache HttpClient 和 Ok HttpClient 等,而一旦引入 Spring,就有了更好选择 - RestTemplate。

微服务之间的大多都是使用 HTTP 通信,这自然少不了使用 HttpClient。

在不适用 Spring 前,一般使用 Apache HttpClient 和 Ok HttpClient 等,而一旦引入 Spring,就有了更好选择 - RestTemplate。


接口:

1.png

想接受一个 Form 表单请求,读取表单定义的两个参数 para1 和 para2,然后作为响应返回给客户端。

定义完接口后,使用 RestTemplate 来发送一个这样的表单请求,代码示例如下:

1.png

上述代码定义了一个 Map,包含了 2 个表单参数,然后使用 RestTemplate 的 postForObject 提交这个表单。

执行代码提示 400 错误,即请求出错:

image.png

就是缺少 para1 表单参数,why?

解析

RestTemplate 提交的表单,最后提交请求啥样?

Wireshark 抓包:

image.png

实际上是将定义的表单数据以 JSON 提交过去了,所以我们的接口处理自然取不到任何表单参数。

why?怎么变成 JSON 请求体提交数据呢?注意 RestTemplate 执行调用栈:

image.png

最终使用的 Jackson 工具序列化了表单

image.png

用到 JSON 的关键原因在

RestTemplate.HttpEntityRequestCallback#doWithRequest

1.png

根据当前要提交的 Body 内容,遍历当前支持的所有编解码器:


  • 若找到合适编解码器,用之完成 Body 转化


看下 JSON 的编解码器对是否合适的判断

AbstractJackson2HttpMessageConverter#canWrite

image.png

可见,当使用的 Body 为 HashMap,是可完成 JSON 序列化的。

所以后续将这个表单序列化为请求 Body了。


但我还是疑问,为何适应表单处理的编解码器不行?

那就该看编解码器判断是否支持的实现:

FormHttpMessageConverter#canWrite

image.png

可见只有当我们发送的 Body 是 MultiValueMap 才能使用表单来提交。

原来使用 RestTemplate 提交表单必须是 MultiValueMap!

而我们案例定义的就是普通的 HashMap,最终是按请求 Body 的方式发送出去的。

修正

换成 MultiValueMap 类型存储表单数据即可:

image.png

修正后,表单数据最终使用下面的代码进行了编码:

FormHttpMessageConverter#write


image.png

发送出的数据截图如下:

image.png

这就对了!其实官方文档也说明了:

image.png


参考:

目录
相关文章
|
6月前
|
XML 编解码 Java
Spring Boot 中的 RestTemplate和Retrofit 插件很好
Spring Boot 中的 RestTemplate和Retrofit 插件很好
141 1
|
6月前
|
XML 编解码 Java
我为什么放弃Spring Boot 中的 RestTemplate?选择 Retrofit
我为什么放弃Spring Boot 中的 RestTemplate?选择 Retrofit
110 0
|
6月前
|
Java Spring
【编程笔记】在 Spring 项目中使用 RestTemplate 发送网络请求
【编程笔记】在 Spring 项目中使用 RestTemplate 发送网络请求
126 0
|
6月前
|
Java
SpringBoot集成RestTemplate组件
SpringBoot集成RestTemplate组件
90 0
|
4月前
|
Java Spring
spring restTemplate 进行http请求的工具类封装
spring restTemplate 进行http请求的工具类封装
221 3
|
4月前
|
文字识别 Java Python
文本,文识10,springBoot提供RestTemplate以调用Flask OCR接口,调用flask实现ocr接口,用paddleocr进行图片识别云服务技术,单个paddleocr接口有影响
文本,文识10,springBoot提供RestTemplate以调用Flask OCR接口,调用flask实现ocr接口,用paddleocr进行图片识别云服务技术,单个paddleocr接口有影响
|
4月前
|
Java 微服务 Spring
微服务04---服务远程调用,根据订单id查询订单功能,根据id查询订单的同时,把订单所属的用户信息一起返回,Spring提供了一个工具RestTemplate,Bean写在对象前面,以后可以在任何地
微服务04---服务远程调用,根据订单id查询订单功能,根据id查询订单的同时,把订单所属的用户信息一起返回,Spring提供了一个工具RestTemplate,Bean写在对象前面,以后可以在任何地
|
5月前
|
Java Spring
springboot使用RestTemplate(基于2.6.7,返回泛型)
springboot使用RestTemplate(基于2.6.7,返回泛型)
|
缓存 Java 数据库
【Spring Cloud系列】- RestTemplate使用详解(下)
【Spring Cloud系列】- RestTemplate使用详解(下)
474 0
|
缓存 Java Apache
【Spring Cloud系列】- RestTemplate使用详解(上)
【Spring Cloud系列】- RestTemplate使用详解
375 0
下一篇
无影云桌面