RestTemplate get请求携带headers自动拼接参数方式

 更新时间:2023年07月06日 17:08:16   作者:词穷墨尽  
这篇文章主要介绍了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}&param2={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只能接收请求行中的

服务端应该根据参数位置选择使用的注解

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 理解Java当中的回调机制(翻译)

    理解Java当中的回调机制(翻译)

    今天我要和大家分享一些东西,举例来说这个在JavaScript中用的很多。我要讲讲回调(callbacks)。你知道什么时候用,怎么用这个吗?你真的理解了它在java环境中的用法了吗?当我也问我自己这些问题,这也是我开始研究这些的原因
    2014-10-10
  • JAVA发送HTTP请求的多种方式详细总结

    JAVA发送HTTP请求的多种方式详细总结

    目前做项目中有一个需求是这样的,需要通过Java发送url请求,查看该url是否有效,这时我们可以通过获取状态码来判断,下面这篇文章主要给大家介绍了关于JAVA发送HTTP请求的多种方式总结的相关资料,需要的朋友可以参考下
    2023-01-01
  • SpringBoot跨域Access-Control-Allow-Origin实现解析

    SpringBoot跨域Access-Control-Allow-Origin实现解析

    这篇文章主要介绍了SpringBoot跨域Access-Control-Allow-Origin实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • spring cloud 使用Eureka 进行服务治理方法

    spring cloud 使用Eureka 进行服务治理方法

    这篇文章主要介绍了spring cloud 使用Eureka 进行服务治理方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • java实现单链表中的增删改

    java实现单链表中的增删改

    这篇文章主要为大家详细介绍了java实现单链表中的增删改,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • IO中flush()函数的使用代码示例

    IO中flush()函数的使用代码示例

    这篇文章主要介绍了IO中flush()函数的使用代码示例,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • java查找文件夹下最新生成的文件的方法

    java查找文件夹下最新生成的文件的方法

    在本篇文章中我们给大家分享了关于java怎么查找文件夹下最新生成的文件的相关方法和知识点,有需要的朋友们参考下。
    2019-07-07
  • Spring整合TimerTask实现定时任务调度

    Spring整合TimerTask实现定时任务调度

    这篇文章主要介绍了Spring整合TimerTask实现定时任务调度的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • Spring boot2+jpa+thymeleaf实现增删改查

    Spring boot2+jpa+thymeleaf实现增删改查

    这篇文章主要介绍了Spring boot2+jpa+thymeleaf实现增删改查,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • 关于Java利用反射实现动态运行一行或多行代码

    关于Java利用反射实现动态运行一行或多行代码

    这篇文章主要介绍了关于Java利用反射实现动态运行一行或多行代码,借鉴了别人的方法和书上的内容,最后将题目完成了,和大家一起分享以下解决方法,需要的朋友可以参考下
    2023-04-04

最新评论