RestTemplate get请求携带headers自动拼接参数方式
作者:词穷墨尽
这篇文章主要介绍了RestTemplate get请求携带headers自动拼接参数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
RestTemplate get请求携带headers自动拼接参数
/** * 根据get方式请求接口 * @param url * @param map * @param restTemplate * @return */ public static JSONObject requestByGet(String url,HashMap<String,Object> map, RestTemplate restTemplate,HttpHeaders headers){ // header填充 HttpEntity<MultiValueMap<String,Object>> request = new HttpEntity(null,headers); UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url); ResponseEntity responseEntity; //如果存在參數 if(!map.isEmpty()){ for (Map.Entry<String,Object> e: map.entrySet()) { //构建查询参数 builder.queryParam(e.getKey(),e.getValue()); } //拼接好参数后的URl//test.com/url?param1={param1}¶m2={param2}; String reallyUrl=builder.build().toString(); responseEntity =restTemplate.exchange(reallyUrl,HttpMethod.GET,request,String.class); }else{ responseEntity=restTemplate.exchange(url,HttpMethod.GET,request,String.class); } return getJSONObjectForResponseEntity(responseEntity); }
RestTemplate请求参数传递问题
问题
使用RestTemplate传递参数的时候,RestTemplate默认传递的是json格式,将参数放在请求体中,这就导致使用@RequestParam接收不到参数。下面测试集中参数传递的方式
测试方法
- 1.先重现错误,使用RestTemplate传递json,同时使用@RequestParam接收参数.
- 2.更改RestTemplate参数传递方式,将参数使用占位符在请求行拼接.
- 3.测试使用@RequestBody接收请求体中的数据(对象/集合/字符串/json数据).
测试
构造几个接口
/** * 测试restTemplate的数组型(List)数据的传递 */ @RestController public class UserController { /** * 接收一个json格式的字符串 数组转换为json字符串传递 */ @RequestMapping(value = "/test01") public String getRest01(@RequestParam("userList")String userList) { //转为list List<User> userList1 = JSONArray.parseArray(userList, User.class); for (User user : userList1) { System.out.println(user); } return "11111111111"; } /** * 测试直接传递单个对象 */ @RequestMapping(value = "/test02") public String getRest02(@RequestBody User user) { System.out.println(user); return "2222222222222"; } /** *测试使用list<>接收数组型的参数 */ @RequestMapping(value = "/test03") public String getRest03(@RequestBody List<User> userList) { System.out.println(userList); return "333333333333"; } /** * 使用String 接收请求体中数据 */ @RequestMapping(value = "/test04") public String getRest04(@RequestBody String userList) { //转为list List<User> userList1 = JSONArray.parseArray(userList, User.class); for (User user : userList1) { System.out.println(user); } return "444444444444444"; } /** * 使用JSONArray接收请求体中的数据 */ @RequestMapping(value = "/test05") public String getRest05(@RequestBody JSONArray jsonArray, HttpServletRequest request) { //获取请求头中的数据 String key = request.getHeader("key"); System.out.println(key); //转为list List<User> userList = JSONArray.parseArray(jsonArray.toJSONString(), User.class); for (User user : userList) { System.out.println(user); } return "55555555555555"; } }
使用单元测试测试接口
class ApplicationTests { private RestTemplate restTemplate = new RestTemplate(); //构建两个使用的对象并使用list封装起来 private List<User> userList = new ArrayList<>(); private User oneUser; private User twoUser; { //第一个对象 oneUser = new User(); oneUser.setName("第一个用户"); oneUser.setAge("第一个年龄"); oneUser.setAddress("第一个地址"); //第二个对象 twoUser = new User(); twoUser.setName("22222222第二个用户"); twoUser.setAge("2222222第二个年龄"); twoUser.setAddress("222222第二个地址"); //添加进list userList.add(oneUser); userList.add(twoUser); } /* * 当服务端使用@RequestParam("tableList")String tableList这种方式时 * 方法异常:HttpClientErrorException$BadRequest: 400 Bad Request * 原因:无法使用@RequestParam识别参数中的json格式的 * */ @Test void test01() { String url = "http://127.0.0.1:8080/test01"; //json格式的字符串 String jsonString = JSON.toJSONString(userList); Map<String, String> map = new HashMap<>(); map.put("userList", jsonString); String s = restTemplate.postForObject(url, map, String.class); System.out.println(s); } /* * 当服务端使用@RequestParam("tableList")String tableList这种方式时,改请求方式会成功 * 改变:使用了postForEntity方法(这个方法可以传递更多的请求信息,比如请求头等) * 使用的占位符的方式拼接json字符串, 在第一个方法参数中,最后的参数Object...是一个可变形参,可以传递多个参数,位置从1开始 * 原因:restTemplate默认的是json格式的参数,会在请求体中放着数据,而@RequestParam只能获取请求行中的参数 * 将参数改在请求行发送就能接收到了. * */ @Test void test02() { //使用占位符的方式 String url = "http://127.0.0.1:8080/test01?userList={1}"; String jsonString = JSON.toJSONString(userList); //使用占位符拼接参数 //连接(带有占位符的) / HttpEntity对象(暂时不用,后边会有) / 返回值 / 拼接的数据 ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, null, String.class, jsonString); System.out.println(responseEntity.toString()); } /* * 当服务端使用(@RequestBody User user)这种方式时,会成功 * @RequestBody 将会从请求体(body)中取数据,此时可以取到已经转为json格式的User对象(resttemplate会自动转) * 但是当传递的是数组型的数据时(List),服务端又改怎么样接收呢,使用test04测试一下. * */ @Test void test03() { //使用服务端的test02接口 String url = "http://127.0.0.1:8080/test02"; //测试只传递一个对象, 使用httpEntity来封装一下对象. HttpEntity<User> httpEntity = new HttpEntity<>(oneUser); ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class); System.out.println(responseEntity.toString()); } /* * 传递的是数组型的数据的时候,服务端可以使用List<>这种形式来接收,也会成功 * */ @Test void test04() { //使用服务端的test03接口,用list<>接收 String url = "http://127.0.0.1:8080/test03"; //测试传递一个list对象 HttpEntity<List<User>> httpEntity = new HttpEntity<>(userList); ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class); System.out.println(responseEntity.toString()); } /* * 传递的是数组型的数据的时候,服务端也可以使用String来接收json型的数据 * */ @Test void test05() { //使用服务端的test04接口,用String接收 String url = "http://127.0.0.1:8080/test04"; //测试传递一个list对象 HttpEntity<List<User>> httpEntity = new HttpEntity<>(userList); ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class); System.out.println(responseEntity.toString()); } /* * 传递的是数组型的数据的时候,服务端也可以使用JsonArray来接收 * */ @Test void test06() { //使用服务端的test04接口,用JsonArray接收 String url = "http://127.0.0.1:8080/test05"; //传递的参数的同时,自定义请求头 HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.set("key","value"); HttpEntity<List<User>> httpEntity = new HttpEntity<>(userList,httpHeaders); ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class); System.out.println(responseEntity.toString()); } /* * 总结一下: * 使用RestTemplate远程调用接口的时候,会默认将数据放在请求体中(body) * 而使用@RequestBody才能接收请求体中的数据. * @RequestParam只能接收请求行中的参数 * 根据位置选择使用的注解 * * postForEntity 方法可以自定义请求头,以及进行请求行的参数拼接,功能全 * */ }
心得
使用RestTemplate远程调用接口的时候,会默认将数据放在请求体中(body)
使用@RequestBody才能接收请求体中的数据.
@RequestParam只能接收请求行中的
服务端应该根据参数位置选择使用的注解
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。