最近使用Spring 的 RestTemplate 工具类请求接口的时候发现参数传递的一个坑,也就是当我们把参数封装在Map里面的时候,Map 的类型选择。 使用RestTemplate post请求的时候主要可以通过三种方式实现
    1、调用postForObject方法  2、使用postForEntity方法 3、调用exchange方法
    postForObject和postForEntity方法的区别主要在于可以在postForEntity方法中设置header的属性,当需要指定header的属性值的时候,使用postForEntity方法。exchange方法和postForEntity类似,但是更灵活,exchange还可以调用get、put、delete请求。使用这三种方法调用post请求传递参数,Map不能定义为以下两种类型(url使用占位符进行参数传递时除外)
Map<String, Object> paramMap = new HashMap<String, Object>();

Map<String, Object> paramMap = new LinkedHashMap<String, Object>();

   经过测试,我发现这两种map里面的参数都不能被后台接收到,这个问题困扰我两天,终于,当我把Map类型换成LinkedMultiValueMap后,参数成功传递到后台。

MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();

  注:HashMap是以请求体传递,MultiValueMap是表单传递。

  经过测试,正确的POST传参方式如下

public static void main(String[] args) {
RestTemplate template = new RestTemplate();
String url = "http://192.168.2.40:8081/channel/channelHourData/getHourNewUserData";
// 封装参数,千万不要替换为Map与HashMap,否则参数无法传递
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
paramMap.add("dt", "20180416"); // 1、使用postForObject请求接口
String result = template.postForObject(url, paramMap, String.class);
System.out.println("result1==================" + result); // 2、使用postForEntity请求接口
HttpHeaders headers = new HttpHeaders();
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(paramMap,headers);
ResponseEntity<String> response2 = template.postForEntity(url, httpEntity, String.class);
System.out.println("result2====================" + response2.getBody()); // 3、使用exchange请求接口
ResponseEntity<String> response3 = template.exchange(url, HttpMethod.POST, httpEntity, String.class);
System.out.println("result3====================" + response3.getBody());
}

  补充:POST传参对象

     @Autowired
private RestTemplate restTemplate;
private String url="http://localhost:8080/users"; public Integer save(User user){
Map<String,String> map = restTemplate.postForObject(url, user, Map.class);
if(map.get("result").equals("success")){
//添加成功
return 1;
}
return -1;
} //这是访问的controller方法
@RequestMapping(value = "users",method = RequestMethod.POST)
public Map<String,String> save(@RequestBody User user){
Integer save = userService.save(user);
Map<String,String> map=new HashMap<>();
if(save>0){
map.put("result","success");
return map;
}
map.put("result","error");
return map;
}

  ps:post请求也可以通过占位符的方式进行传参(类似get),但是看起来不优雅,推荐使用文中的方式。

GET方式传参说明

如果是get请求,又想要把参数封装到map里面进行传递的话,Map需要使用HashMap,且url需要使用占位符,如下:

public static void main(String[] args) {
RestTemplate restTemplate2 = new RestTemplate();
String url = "http://127.0.0.1:8081/interact/getData?dt={dt}&ht={ht}"; // 封装参数,这里是HashMap
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("dt", "20181116");
paramMap.put("ht", "10"); //1、使用getForObject请求接口
String result1 = template.getForObject(url, String.class, paramMap);
System.out.println("result1====================" + result1); //2、使用exchange请求接口
HttpHeaders headers = new HttpHeaders();
headers.set("id", "lidy");
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(null,headers);
ResponseEntity<String> response2 = template.exchange(url, HttpMethod.GET, httpEntity, String.class,paramMap);
System.out.println("result2====================" + response2.getBody());
}

  

    RestTemplate提供的delete()和put()方法都没有返回值,但是我要调用的接口是有返回值的,网上的资料很多都是写的调用exchange()方法来实现,但是基本上都没有给出完整实例,导致我在参考他们的代码的时候会出现参数无法传递的问题,目前我已经解决该问题,现将我的解决方法分享出来
       我同样是使用exchange()方法来实现,但是url有讲究,需要像使用exchange方法调用get请求一样,使用占位符
       delete请求实例,请求方式使用 HttpMethod.DELETE(resultful风格使用占位符)
    /**
* 删除用户
* @param id
* @return
*/
public String delete(Long id) {
StringBuffer url = new StringBuffer(baseUrl)
.append("/user/delete/{id}"); Map<String, Object> paramMap = new HashMap<>();
paramMap.put("id", id); ResponseEntity<String > response = restTemplate.exchange(url.toString(), HttpMethod.DELETE, null, String .class, paramMap);
String result = response.getBody(); return result;
}

  补充:resultful风格直接拼接url

    //负责调用provider的方法,获取数据
@Autowired
private RestTemplate restTemplate;
//在provider端资源的路径
private String url="http://localhost:8080/details"; public String deleteDetail(Integer id){
ResponseEntity<String> response = restTemplate.exchange(url + "/" + id, HttpMethod.DELETE, null, String.class);
String result = response.getBody();
return result;
} //被调用的controller方法
@ResponseBody
@RequestMapping(value = "details/{id}",method = RequestMethod.DELETE)
public String deleteDetail(@PathVariable Integer id){
Integer integer = detailService.deleteDetail(id);
if(integer>0){
return "success";
}
return "error";
}

  不是resultful风格可以使用占位符

private String url="http://localhost:8080/details?id={id}";

public String deleteDetail(Integer id){

        Map<String, Object> paramMap = new HashMap<>();
paramMap.put("id", id);
ResponseEntity<String > response = restTemplate.exchange(url.toString(), HttpMethod.DELETE, null, String .class, paramMap);
String result = response.getBody();
return result;
}

  

put请求实例,请求方式使用 HttpMethod.PUT

    /**
* 更新用户基础信息
* @param userInfoDTO
* @return
*/
public String edit(UserInfoDTO userInfoDTO) {
StringBuffer url = new StringBuffer(baseUrl)
.append("/user/edit?tmp=1")
.append("&id={id}")
.append("&userName={userName}")
.append("&nickName={nickName}")
.append("&realName={realName}")
.append("&sex={sex}")
.append("&birthday={birthday}"); Map<String, Object> paramMap = new HashMap<>();
paramMap.put("userId", userInfoDTO.getId());
paramMap.put("userName", userInfoDTO.getUserName());
paramMap.put("nickName", userInfoDTO.getNickName());
paramMap.put("realName", userInfoDTO.getRealName());
paramMap.put("sex", userInfoDTO.getSex());
paramMap.put("birthday", userInfoDTO.getBirthday()); ResponseEntity<String > response = restTemplate.exchange(url.toString(), HttpMethod.PUT, null, String .class, paramMap);
String result = response.getBody();
return result; }
 
  再次补充exchange()传参对象:
    //测试post的controller
@RequestMapping(value = "detailsPost",method = RequestMethod.POST)
public String test02(@RequestBody Detail detail){
System.out.println("POST-"+detail);
return "error";
}
//测试put的controller
@RequestMapping(value = "detailsPut",method = RequestMethod.PUT)
public String test03(@RequestBody Detail detail){
System.out.println("PUT-"+detail);
return "error";
}
//测试delete的controller
@RequestMapping(value = "detailsDelete",method = RequestMethod.DELETE)
public String test04(@RequestBody Detail detail){
System.out.println("DELETE-"+detail);
return "error";
} //测试方法
public String test(){
//put传递对象
//String json = "{\"author\":\"zsw\",\"createdate\":1582010438846,\"id\":1,\"summary\":\"牡丹\",\"title\":\"菏泽\"}";
//HttpHeaders headers = new HttpHeaders();
//headers.setContentType(MediaType.APPLICATION_JSON);
//HttpEntity<String> entity = new HttpEntity<>(json,headers);
//ResponseEntity<String> resp = restTemplate.exchange("http://localhost:8080/detailsPut", HttpMethod.PUT, entity, String.class); //delete传递对象
Detail detail=new Detail();
detail.setId(1L);
detail.setSummary("牡丹");
detail.setTitle("菏泽");
detail.setAuthor("zsw");
detail.setCreatedate(new Timestamp(new Date().getTime()));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Detail> entity = new HttpEntity<>(detail,headers);
ResponseEntity<String> resp = restTemplate.exchange("http://localhost:8080/detailsDelete", HttpMethod.DELETE, entity, String.class); String result = resp.getBody();
System.out.println(result);
return result;
}

  delete请求和上面一样,但是get不行,直接报错400。好像是get不支持这种传参。https://blog.belonk.com/c/http_resttemplate_get_with_body.htm 和这大哥的情况一样,但是他的解决方案我没搞明白,so 如有大佬还望指点一下老弟,不胜感激。

  exchange()传递单个参数可以使用占位符:

        //post传递单参
// ResponseEntity<String> resp = restTemplate.exchange("http://localhost:8080/detailsPostD?id={id}&name={name}", HttpMethod.POST, null, String.class,1,"zsw");
//put传递单参
Map<String,Object> map=new HashMap<>();
map.put("id",1);
map.put("name","zsw");
ResponseEntity<String> resp = restTemplate.exchange("http://localhost:8080/detailsPutD?id={id}&name={name}", HttpMethod.PUT, null, String.class,map);

  get、post、put、delete请求通用。

 

Java RestTemplate传递参数的更多相关文章

  1. Java方法传递参数传值还是传址的问题

    这几天重构项目代码遇到一个疑问:可不可以在方法A中定义一个boolean变量b为false,然后A调用方法C把b传递到C方法中经过一些列业务判断后修改为true,C执行结束后A方法中b的值还是原来的f ...

  2. jquery ajax 用 data 和 headers 向 java RESTful 传递参数区别

    jquery 的 ajax 是非常方便的一个函数,记录一下 $.ajax 生成的 http 报文 一.使用 data 传递参数: $.ajax({ url : "webrs/test/add ...

  3. Unity3D研究院之打开Activity与调用JAVA代码传递参数

    原地址:http://www.xuanyusong.com/archives/667    Unity for Android 比较特殊,Unity for IOS 打包是将XCODE工程直接交给开发 ...

  4. JAVA中传递参数乱码问题

    url传递中文如果jsp页面,myeclipse.web.xml中org.springframework.web.filter.CharacterEncodingFilter,都是UTF-8编码,直接 ...

  5. JAVA接口传递参数(POST),从接口接收数据(JSON) -----记录

    1,给接口传递json格式的数据 import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOEx ...

  6. JAVA方法传递参数:传值?传引用?

    先来看下面这三段代码: //Example1: public class Example1 { static void check(int a) { a++; } public static void ...

  7. jquery通过ajax-json访问java后台传递参数,通过request.getParameter获取不到参数的说明

    http://m.blog.csdn.net/blog/eyebrother/36007145 所以当后台通过request.getParameter("name");对参数值的作 ...

  8. java调用python脚本并向python脚本传递参数

    1.安装Eclipse 先安装jdk,再安装Eclipse,成功后开始建立py_java项目,在这个项目的存储目录SRC下建立test包,在test包中New-Class,新建MyDemo类,建好完成 ...

  9. SpringMVC中使用Ajax POST请求以json格式传递参数服务端通过request.getParameter("name")无法获取参数值问题分析

    SpringMVC中使用Ajax POST请求以json格式传递参数服务端通过request.getParameter("name")无法获取参数值问题分析 一:问题demo展示 ...

随机推荐

  1. Charles--/安装/破解/支持https抓包

     一.安装破解Charles 1.下载charles4.0.2版本,下面的jar包需要和charles版本对应 2.下载地址:https://www.cr173.com/soft/494576.htm ...

  2. <C#任务导引教程>练习四

    //27,创建一个控制台应用程序,声明两个DateTime类型的变量dt,获取系统的当前日期时间,然后使用Format格式化进行规范using System;class Program{    sta ...

  3. Jetpack架构组件学习(2)——ViewModel和Livedata使用

    要看本系列其他文章,可访问此链接Jetpack架构学习 | Stars-One的杂货小窝 原文地址:Jetpack架构组件学习(2)--ViewModel和Livedata使用 | Stars-One ...

  4. Devs--开源规则引擎介绍

    Devs Devs是一款轻量级的规则引擎. 开源地址:https://github.com/CrankZ/devs 基础概念 此规则引擎的基础概念有字段.条件.规则等. 其中字段组成条件,条件组成规则 ...

  5. 如何在Docker容器中使用Arthas

    Arthas(阿尔萨斯) 能为你做什么? Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱. 当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: 这个类从哪个 jar ...

  6. 洛谷 P6177 - Count on a tree II/【模板】树分块(树分块)

    洛谷题面传送门 好家伙,在做这道题之前我甚至不知道有个东西叫树分块 树分块,说白了就是像对序列分块一样设一个阈值 \(B\),然后在树上随机撒 \(\dfrac{n}{B}\) 个关键点,满足任意一个 ...

  7. BZOJ 3926 诸神眷顾的幻想乡

    BZOJ 3926 诸神眷顾的幻想乡 开始看错题看成了每个点度数不超过20 后来翻了翻题解原来看错题的不止我一个 既然叶子数量不超过20,考虑树上的任何一条路径,以任何点为根时,如果它不是一条从上到下 ...

  8. Codeforces 1483F - Exam(AC 自动机)

    Codeforces 题目传送门 & 洛谷题目传送门 一道 ACAM 的 hot tea 首先建出 ACAM.考虑枚举长串,以及短串在长串中出现的最后位置 \(j\),这个复杂度显然是 \(\ ...

  9. BZOJ 3043 [Poetize6] IncDec Sequence

    题目描述 给定一个长度为n的数列$a_1,a_2,--,a_n$​,每次可以选择一个区间[l,r],使这个区间内的数都加1或者都减1. 请问至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最 ...

  10. 【R方差分析】蛋白质表达量多组比较

    初始数据类似: 蛋白质组数据虽不是严格的正态分布,但目前最常用的检验方法还是T检验(两组比较)和方差分析(多组比较).这个话题值得深究,这里不展开. 主要是求多个蛋白的Pvalue值或FDR,用于差异 ...