解析Spring RestTemplate必须搭配MultiValueMap的理由

 更新时间:2021年11月25日 16:28:26   作者:chenzk的博客  
本文给大家介绍Spring RestTemplate必须搭配MultiValueMap的理由,本文通过实例图文相结合给大家介绍的非常详细,需要的朋友参考下吧
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

什么是REST?

? REST(RepresentationalState Transfer)是Roy Fielding 提出的一个描述互联系统架构风格的名词。REST定义了一组体系架构原则,您可以根据这些原则设计以系统资源为中心的Web 服务,包括使用不同语言编写的客户端如何通过 HTTP处理和传输资源状态。

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

接口:

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

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

上述代码定义了一个 Map,包含了 2 个表单参数,然后使用 RestTemplate 的 postForObject 提交这个表单。
执行代码提示 400 错误,即请求出错:

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

解析

RestTemplate 提交的表单,最后提交请求啥样?
Wireshark 抓包:

实际上是将定义的表单数据以 JSON 提交过去了,所以我们的接口处理自然取不到任何表单参数。
why?怎么变成 JSON 请求体提交数据呢?注意 RestTemplate 执行调用栈:

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

用到 JSON 的关键原因在

RestTemplate.HttpEntityRequestCallback#doWithRequest

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

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

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

AbstractJackson2HttpMessageConverter#canWrite

可见,当使用的 Body 为 HashMap,是可完成 JSON 序列化的。
所以后续将这个表单序列化为请求 Body了。

但我还是疑问,为何适应表单处理的编解码器不行?
那就该看编解码器判断是否支持的实现:

FormHttpMessageConverter#canWrite

可见只有当我们发送的 Body 是 MultiValueMap 才能使用表单来提交。
原来使用 RestTemplate 提交表单必须是 MultiValueMap!
而我们案例定义的就是普通的 HashMap,最终是按请求 Body 的方式发送出去的。

修正

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

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

FormHttpMessageConverter#write

发送出的数据截图如下:

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

参考:

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

到此这篇关于解析Spring RestTemplate必须搭配MultiValueMap的理由的文章就介绍到这了,更多相关Spring RestTemplate MultiValueMap内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • grails不能运行fork模式解决方法

    grails不能运行fork模式解决方法

    这篇文章主要介绍了如何解决grails2.3.2中不能运行fork模式的异常,大家参考使用吧
    2013-11-11
  • shade解决mybatis包冲突问题及项目引用的方法

    shade解决mybatis包冲突问题及项目引用的方法

    这篇文章主要介绍了shade解决mybatis包冲突问题及项目引用的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • springboot vue 跨域问题的解决

    springboot vue 跨域问题的解决

    这篇文章主要介绍了springboot vue 跨域问题的解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • java实现图的邻接表存储结构的两种方式及实例应用详解

    java实现图的邻接表存储结构的两种方式及实例应用详解

    这篇文章主要介绍了java实现图的邻接表存储结构的两种方式及实例应用详解,邻接表构建图是必须需要一个Graph对象,也就是图对象!该对象包含属性有:顶点数、边数以及图的顶点集合,需要的朋友可以参考下
    2019-06-06
  • Idea?编译并运行?Spark?3.1.1?源码的方法

    Idea?编译并运行?Spark?3.1.1?源码的方法

    这篇文章主要介绍了Idea?编译并运行?Spark?3.1.1源码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-11-11
  • 详解使用spring aop实现业务层mysql 读写分离

    详解使用spring aop实现业务层mysql 读写分离

    本篇文章主要介绍了使用spring aop实现业务层mysql 读写分离,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • 浅谈JAVA 异常对于性能的影响

    浅谈JAVA 异常对于性能的影响

    Java的异常处理为什么会影响性能?异常开销很大。那么,这是不是就意味着您不该使用异常?当然不是。但是,何时应该使用异常,何时又不应该使用异常呢?不幸的是,答案不是一下子就说得清楚的,我们来详细探讨下。
    2015-05-05
  • Java实现TCP和UDP协议详解

    Java实现TCP和UDP协议详解

    这篇文章主要介绍了Java实现TCP和UDP协议详解,TCP(传输控制协议)和UDP(用户数据报协议)是两种最常用的传输层协议,它们都用于在网络上传输数据,但是它们之间有很多不同之处,需要的朋友可以参考下
    2023-07-07
  • java实现的RC4加密解密算法示例

    java实现的RC4加密解密算法示例

    这篇文章主要介绍了java实现的RC4加密解密算法,结合具体实例形式分析了java RC4加密解密算法的实现与使用技巧,需要的朋友可以参考下
    2017-06-06
  • Java排序算法总结之插入排序

    Java排序算法总结之插入排序

    这篇文章主要介绍了Java排序算法总结之插入排序,较为详细的分析了插入排序的原理与java实现技巧,需要的朋友可以参考下
    2015-05-05

最新评论

?


http://www.vxiaotou.com