springboot 整合 RestTemplate 与 使用方法

RestTemplate 的 postForObject 方法有四个参数

  • String url => 顾名思义 这个参数是请求的url路径
  • Object request => 请求的body 这个参数需要再controller类用 @RequestBody 注解接收
  • Class<T> responseType => 接收响应体的类型
  • ------------ 第四个参数 postForObject 方法多种重构
  • Map<String,?> uriVariables => uri 变量 顾名思义 这是放置变量的地方
  • Object... uriVariables => 可变长 Object 类型 参数

RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析

 

 首先我们使用最简单的一种 可变长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;
    }
}

测试

RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析

 

 

返回成功 

接下来我们使用 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 方法中 , 那么接着追踪
RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析

 

 进入httpEntityCallBack方法中

RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析

 

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

进入HttpEntityRequestCallback

RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析

 

 这里会出现一个分支 instanceof 类型判定 requestBody 参数是否是 HttpEntity类型

如果不是则 创建一个HttpEntity类将 requestBody 参数传入

那么我们来看一下 HttpEntity 是怎么个构造

RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析

 

 这里可以看到 HttpEntity 有两个构造方法 一个是 传入 泛型的body 另一个是传入 MultiValueMap<String,String> headers

那么 这个MultiValueMap 是个什么东东

百度一下 发现 MultiValueMap 可以让一个key对应多个value,感觉是value产生了链表结构,可以很好的解决一些不好处理的字符串问题

找到 MultiValueMap 接口的实现类
RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析

 

 RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析

 

 这里我们使用 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方法源码解析

 

 返回值正确 操作成功 

相关文章:

  • 2021-11-26
  • 1970-01-01
  • 2021-10-09
  • 2022-12-23
  • 2022-03-03
  • 2021-09-22
猜你喜欢
  • 2022-12-23
  • 2021-12-11
  • 2022-12-23
  • 2021-07-24
  • 2021-05-16
相关资源
相似解决方案