RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析
springboot 整合 RestTemplate 与 使用方法
RestTemplate 的 postForObject 方法有四个参数
- String url => 顾名思义 这个参数是请求的url路径
- Object request => 请求的body 这个参数需要再controller类用 @RequestBody 注解接收
- Class<T> responseType => 接收响应体的类型
- ------------ 第四个参数 postForObject 方法多种重构
- Map<String,?> uriVariables => uri 变量 顾名思义 这是放置变量的地方
- Object... uriVariables => 可变长 Object 类型 参数

首先我们使用最简单的一种 可变长Object 参数 进行传值
@Service
public class HelloService { @Autowired
RestTemplate restTemplate; public String helloService(String name,Integer age){
return restTemplate.postForObject("http://SERVICE-HELLO/hello?name={name}&age={age}", null, String.class, name,age);
}
}
需要再url上拼接参数并使用{参数名}占位符站位
然后将参数放到 第四个参数 可变长 Object 参数上 即可
Controller类代码
@RestController
public class DemoController {
@Value("${server.port}")
String port; @PostMapping("hello")
public String home(String name,Integer age){
return "hello " + name + " you age is " + age + " ,i am from port:" + port;
}
}
测试

返回成功
接下来我们使用 Map传值
public String helloService(String name,Integer age){
Map<String,Object> map = new HashMap<>();
map.put("name",name);
map.put("age",age);
return restTemplate.postForObject("http://SERVICE-HELLO/hello?name={name}&age={age}", null, String.class, map);
}
只需要将参数放入到map中即可
那有些人要问了 , 为什么不能用 第二个 request 参数传值 , 其实是可以的
我试过用HashMap 和 LinkedHashMap 都是接收不到的
所以我们来看一下源码是怎么写的
首先进入到 postForObject 方法中 发现request 参数 传入了一个 httpEntityCallBack 方法中 , 那么接着追踪
进入httpEntityCallBack方法中

httpEntityCallBack方法又调用了 RestTemplate的HttpEntityRequestCallback方法
进入HttpEntityRequestCallback

这里会出现一个分支 instanceof 类型判定 requestBody 参数是否是 HttpEntity类型
如果不是则 创建一个HttpEntity类将 requestBody 参数传入
那么我们来看一下 HttpEntity 是怎么个构造

这里可以看到 HttpEntity 有两个构造方法 一个是 传入 泛型的body 另一个是传入 MultiValueMap<String,String> headers
那么 这个MultiValueMap 是个什么东东
百度一下 发现 MultiValueMap 可以让一个key对应多个value,感觉是value产生了链表结构,可以很好的解决一些不好处理的字符串问题
找到 MultiValueMap 接口的实现类

这里我们使用 LinkedMultiValueMap
public String helloService(String name,Integer age){
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
paramMap.add("name",name);
paramMap.add("age", age);
return restTemplate.postForObject("http://SERVICE-HELLO/hello",paramMap,String.class);
}
Controller代码
public class DemoController {
@Value("${server.port}")
String port;
@PostMapping("hello")
public String home(String name,Integer age){
return "MultiValueMap : hello " + name + " you age is " + age + " ,i am from port:" + port;
}
}
测试

返回值正确 操作成功
RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析的更多相关文章
- RestTemplate post请求使用map传参 Controller 接收不到值的解决方案 postForObject方法源码解析.md
结论 post方法中如果使用map传参,需要使用MultiValueMap来传递 RestTemplate 的 postForObject 方法有四个参数 String url => 顾名思义 ...
- MapReduce中一次reduce方法的调用中key的值不断变化分析及源码解析
摘要:mapreduce中执行reduce(KEYIN key, Iterable<VALUEIN> values, Context context),调用一次reduce方法,迭代val ...
- iOS网络请求-AFNetworking源码解析
趁着端午节日,自己没有什么过多的安排,准备花4-5天左右,针对网络请求源码AFNetworking和YTKNetwork进行解析以及这两年多iOS实际开发经验(其实YTKNetwork也是对AFNet ...
- 【安卓网络请求开源框架Volley源码解析系列】定制自己的Request请求及Volley框架源码剖析
通过前面的学习我们已经掌握了Volley的基本用法,没看过的建议大家先去阅读我的博文[安卓网络请求开源框架Volley源码解析系列]初识Volley及其基本用法.如StringRequest用来请求一 ...
- Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析
Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析 Volley之所以高效好用,一个在于请求重试策略,一个就在于请求结果缓存. 通过上一篇文章http://www.cnblogs.com ...
- # Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析#
Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析 Volley源码一共40多个类和接口.除去一些工具类的实现,核心代码只有20多个类.所以相对来说分析起来没有那么吃力.但是要想分析透 ...
- Flask之 请求,应用 上下文源码解析
什么是上下文? 每一段程序都有很多外部变量.只有像Add这种简单的函数才是没有外部变量的.一旦你的一段程序有了外部变量,这段程序就不完整,不能独立运行.你为了使他们运行,就要给所有的外部变量一个一个写 ...
- Thinkphp6源码分析之解析,Thinkphp6路由,Thinkphp6路由源码解析,Thinkphp6请求流程解析,Thinkphp6源码
Thinkphp6源码解析之分析 路由篇-请求流程 0x00 前言: 第一次写这么长的博客,所以可能排版啊,分析啊,什么的可能会比较乱.但是我大致的流程已经觉得是说的够清楚了.几乎是每行源码上都有注释 ...
- Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析
Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们 ...
随机推荐
- C语言:最大公约数
//求最大公约数 #include <stdio.h> main() { int m,n,i,k; scanf("%d,%d",&m,&n); k=m& ...
- mysql jdbc8.0连接mysql
- Matplotlib不能显示中文和正负号的问题
参考链接:https://www.jianshu.com/p/240ea3ae0dc9 在使用matplotlib画饼状图时,遇到了如下问题 UserWarning: findfont: Font f ...
- Java键盘获取数据
java录入键盘数据,整型.浮点型.布尔型.字符串. 通过导入java.util.Scanner实现各类操作 import java.util.Scanner;//导入包 public class H ...
- 【阅读笔记】Java核心技术卷一 #1.Chapter3
3 Java的基本程序设计结构 3.1 一个简单的 Java 应用程序(略) 3.2 注释(略) 3.3 数据类型 8种基本类型 byte,short,int,long float,double ch ...
- SpringBoot自动装配-Condition
1. 简介 @Conditional注解在Spring4.0中引入,其主要作用就是判断条件是否满足,从而决定是否初始化并向容器注册Bean. 2. 定义 2.1 @Conditional @Condi ...
- Wordpress 4.6 任意命令执行漏洞(PwnScriptum)
漏洞存在后台登录地方的找回密码页面:http://192.168.49.2:8080/wp-login.php?action=lostpassword 抓包进行修改包 输入一个存在的用户,然后点击获取 ...
- AHKManager.ahk AHK管理器 2019年12月15日
AHKManager.ahk AHK管理器 2019年12月15日 快捷键 {Alt} + {F1} ///////////////////////////////////////////// ...
- 透视RPC协议:SOFA-BOLT协议源码分析
前提 最近在看Netty相关的资料,刚好SOFA-BOLT是一个比较成熟的Netty自定义协议栈实现,于是决定研读SOFA-BOLT的源码,详细分析其协议的组成,简单分析其客户端和服务端的源码实现. ...
- Android 键盘属性
键盘定义:通过Keyboard说明是一个软键盘定义文件,Row元素说明这是一行按键的定义,Key元素说明这是一个按键的定义.Key元素通过一些属性来定义每个按键,下面是一些常用的属性介绍: Codes ...