zoukankan      html  css  js  c++  java
  • SpringBoot图文教程17—上手就会 RestTemplate 使用指南「Get Post」「设置请求头」

    有天上飞的概念,就要有落地的实现

    • 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍

    • 先赞后看,养成习惯

    SpringBoot 图文教程系列文章目录

    1. SpringBoot图文教程1—SpringBoot+Mybatis 环境搭建
    2. SpringBoot图文教程2—日志的使用「logback」「log4j」
    3. SpringBoot图文教程3—「‘初恋’情结」集成Jsp
    4. SpringBoot图文教程4—SpringBoot 实现文件上传下载
    5. SpringBoot图文教程5—SpringBoot 中使用Aop
    6. SpringBoot图文教程6—SpringBoot中过滤器的使用
    7. SpringBoot图文教程7—SpringBoot拦截器的使用姿势这都有
    8. SpringBoot图文教程8—SpringBoot集成MBG「代码生成器」
    9. SpringBoot图文教程9—SpringBoot 导入导出 Excel 「Apache Poi」
    10. SpringBoot图文教程10—模板导出|百万数据Excel导出|图片导出「easypoi」
    11. SpringBoot图文教程11—从此不写mapper文件「SpringBoot集成MybatisPlus」
    12. SpringBoot图文教程12—SpringData Jpa的基本使用
    13. SpringBoot图文教程13—SpringBoot+IDEA实现代码热部署
    14. SpringBoot图文教程14—阿里开源EasyExcel「为百万数据读写设计」
    15. SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」
    16. SpringBoot图文教程16—SpringBoot 多模块开发「web」「打包」

    前言

    问个问题:通过Java代码怎么发送Http请求,请求另一个Java程序的Controller方法呢?

    好像真的有点触及到知识盲区了呦

    在以前的代码中,Java程序都是被请求的一方,发送请求的要么是Ajax,要么是浏览器,要么是postman等,今天就来一起学习一下如何通过Java代码发送Http请求。

    RestTemplate 的使用

    准备工作「可以跳过,不影响教程学习」

    因为我们要通过RestTemplate发送请求,请求另外一个项目的Controller层方法(接口),所以我们首先需要一个被请求的项目。
    关于这个项目,我已经搭建好了,码云地址为:https://gitee.com/bingqilinpeishenme/boot-demo/tree/master/boot-base-rest

    在项目中有三个方法,分别是测试Get请求和Post请求如下

    package com.lby.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    
    /**
     * @author luxiaoyang
     * @create 2020-03-18-20:02
     */
    @Controller
    public class TestController {
        /**
         * @GetMapping("testRestGet") 当前方法只接受Get请求
         * 等价于
         * @RequestMapping(path = "testRestGet",method = RequestMethod.GET)
         */
        @GetMapping("testRestGet")
        @ResponseBody
        public String testRestGet(String username){
            return "这是一个Get请求,接受参数:"+username;
        }
    
        /**
         * @PostMapping("") 当前方法只接受Post请求
         * 等价于
         * @RequestMapping(path = "testRestPost",method = RequestMethod.POST)
         */
        @PostMapping("testRestPost")
        @ResponseBody
        public String testRestPost(String username){
            return "这是一个Post请求,接受参数:"+username;
        }
    
        /**
         * 测试 postForLocation 给RestTemplate响应url地址
         */
        @PostMapping("testRestPostLocation")
        public String testRestPostLocation(String username){
            System.out.println(username);
            return "redirect:/success.html";
        }
    }
    
    

    什么是RestTemplate

    Spring中封装的通过Java代码发送RestFul请求的模板类,内置发送get post delete等请求的方法,在SpringBoot中只要导入spring-boot-starter-web的依赖可以直接使用。

    快速开始

    确定项目中导入spring-boot-starter-web的依赖。

    第一步:配置RestTemplate

    /**
     * RestTemplate配置
     */
    @Configuration
    public class RestTemplateConfig {
    
        @Bean
        public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
            return new RestTemplate(factory);
        }
    
        @Bean
        public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
            SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
            //        超时设置
            factory.setReadTimeout(5000);//ms
            factory.setConnectTimeout(15000);//ms
            return factory;
        }
    }
    

    第二步:直接使用RestTemplate的Api发送请求

    这一步,我们直接在测试类中发送Get方式的请求,进行简单的测试,感受到效果之后,再进行更多API深入的学习。

    package com.lby;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.web.client.RestTemplate;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = {BootResttemplateApplication.class})
    public class BootResttemplateApplicationTests {
    
        @Autowired
        private RestTemplate restTemplate;
    
    
        /**
         * 测试get请求
         */
        @Test
        public void test1(){
            /**
             * getForObject
             * 
             * 参数1 要请求的地址的url  必填项
             * 参数2 响应数据的类型 是String 还是 Map等 必填项
             * 参数3 请求携带参数 选填
             *
             * getForObject 方法的返回值就是 被调用接口响应的数据
             */
            String result = restTemplate.getForObject("http://localhost:8802/product/showProductById?id=1", String.class);
    
            System.out.println(result);
        }
    
    }
    
    

    RestTemplate的主要API

    HTTP Method RestTemplate Methods
    Get getForObject, getForEntity
    Post postForEntity, postForObject, postForLocation
    PUT put
    any exchange, execute
    DELETE delete
    HEAD headForHeaders
    OPTIONS optionsForAllow

    以上是RestTemplate的主要API,其中大部分的API会在后续的代码中详细讲解。

    Get请求的所有使用方式

    Get请求方式:

    1. url拼接参数
    2. url拼接参数「占位符的方式」
    3. 获取响应实体对象「响应状态码」
         /**
         * 测试get请求
         */
        @Test
        public void test1(){
            /**
             * getForObject
             *
             * 参数1 要请求的地址的url  必填项
             * 参数2 响应数据的类型 是String 还是 Map等 必填项
             * 参数3 请求携带参数 选填
             *
             * getForObject 方法的返回值就是 被调用接口响应的数据
             */
            String result = restTemplate.getForObject("http://localhost:8802/testRestGet?username=zhangsan", String.class);
    
            System.out.println(result);
            /**
             * getForEntity 方法
             * 参数1 要请求的地址的url  必填项
             * 参数2 响应数据的类型 是String 还是 Map等 必填项
             * 参数3 请求携带参数 选填
             *
             * 返回值类型为 ResponseEntity
             *
             * 可以通过ResponseEntity 获取响应的数据,响应的状态码等信息
             */
            ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost:8802/testRestGet?username=zhangsan", String.class);
    
            System.out.println("获取响应的状态:"+responseEntity.getStatusCode());
    
            System.out.println("获取响应的数据:"+responseEntity.getBody());
    
            /**
             * 通过Map传参
             */
            Map map= new HashMap();
            map.put("name","zhangsan");
    
            String resultId = restTemplate.getForObject("http://localhost:8802/testRestGet?username={name}",
                    String.class,map);
    
            System.out.println(resultId);
    
        }
    

    需要注意的是通过Map方式传参

    执行测试类代码,可以看到如下效果:

    Post请求的所有使用方式

    post请求三种情况

    1. 模拟携带表单参数
    2. url拼接参数
    3. 请求成功之后,获取跳转地址
     /**
         * 测试Post请求
         */
        @Test
        public void test2(){
            /**
             * postForObject 返回值为响应的数据
             * 参数1 要请求地址的url
             * 参数2 通过LinkedMultiValueMap对象封装请求参数  模拟表单参数,封装在请求体中
             * 参数3 响应数据的类型
             */
            LinkedMultiValueMap<String, String> request = new LinkedMultiValueMap<>();
            request.set("username","zhangsan");
    
            String result = restTemplate.postForObject("http://localhost:8802/testRestPost",request,String.class);
    
            System.out.println(result);
    
            /**
             * Post请求的时候同样也可以进行参数拼接,使用方式和Get一样
             * 示例如下,通过map封装数据,利用占位符的方式可以将参数拼接到url上
             * 和Get请求url拼接一样
             */
            Map map = new HashMap();
            map.put("password","123456");
    
            String result2 = restTemplate.postForObject("http://localhost:8802/testRestPost?password={password}",request,
                    String.class,map);
    
            /**
             * postForLocation 这个API和前两个都不一样
             *
             * 登录or注册都是post请求,而这些操作完成之后呢?大部分都是跳转到别的页面去了,这种场景下,就可以使用 postForLocation 了,提交数据,并获取返回的URI
             * 响应参数要跳转的地址
             */
            URI uri = restTemplate.postForLocation("http://localhost:8802/testRestPostLocation", request);
            System.out.println("postForLocation请求到的地址为:"+uri);
        }
    
    

    执行测试方法,效果如下:

    Tips:delete,put等请求方式的使用类似Get和Post,模仿Get和Post 即可搞定。

    Get和Post如何设置请求头

    通用方式设置请求头「适合Get,Post等请求」

    1.创建ClientHttpRequestInterceptor类,添加请求头

    package com.lby;
    
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpRequest;
    import org.springframework.http.client.ClientHttpRequestExecution;
    import org.springframework.http.client.ClientHttpRequestInterceptor;
    import org.springframework.http.client.ClientHttpResponse;
    
    import java.io.IOException;
    
    /**
     * @author luxiaoyang
     * @create 2020-03-20-20:37
     */
    public class UserAgentInterceptor implements ClientHttpRequestInterceptor {
        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
    
            HttpHeaders headers = request.getHeaders();
    //        设置请求头参数
            headers.add(HttpHeaders.USER_AGENT,
                    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36");
            return execution.execute(request, body);
        }
    }
    
    

    2.在Get请求的时候,使用请求头

      /**
         * 通用方式设置请求头
         */
        @Test
        public void test3(){
            /**
             * RestTemplate设置使用请求头的拦截器
             */
            restTemplate.setInterceptors(Collections.singletonList(new UserAgentInterceptor()));
    
            /**
             * 正常的发送请求
             */
            String result = restTemplate.getForObject("http://localhost:8802/testRestGet?username=zhangsan", String.class);
    
            System.out.println(result);
        }
    

    Post请求设置请求头的第二种方式

    Post请求的第二个参数是Request,可以根据请求头 + 请求参数,构建 HttpEntity 对象,将这个作为post的请求request参数传入。具体的代码如下:

      /**
         * Post方式设置请求头
         */
        @Test
        public void test4(){
            //1. 设置请求头参数
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.add(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
                    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36");
            //2. 模拟表单参数 请求体携带参数
            MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
            requestBody.add("username", "zhangsan");
            //3. 封装HttpEntity对象
            HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(requestBody, requestHeaders);
            RestTemplate restTemplate = new RestTemplate();
    
            //4. 发送Post请求
            ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost:8802/testRestPost", requestEntity, String.class);
            System.out.println(responseEntity.getBody());
        }
    

    总结

    所有示例代码下载地址:https://gitee.com/bingqilinpeishenme/boot-demo/tree/master

    恭喜你完成了本章的学习,为你鼓掌!如果本文对你有帮助,请帮忙点赞,评论,转发,这对作者很重要,谢谢。

    让我们再次回顾本文的学习目标

    • 掌握SpringBoot中RestTemplate的使用

    要掌握SpringBoot更多的用法,请持续关注本系列教程。

    欢迎关注本人公众号:鹿老师的Java笔记,将在长期更新Java技术图文教程和视频教程,Java学习经验,Java面试经验以及Java实战开发经验。

  • 相关阅读:
    HDU 5963 朋友
    BZOJ 4805 欧拉函数求和
    BZOJ 2153 设计铁路
    BZOJ 2631 tree
    BZOJ 4804 欧拉心算
    BZOJ 4806 炮
    BZOJ 3774 最优选择
    BZOJ 4800 Ice Hockey World Championship
    BZOJ 3894 文理分科
    北方大学多校联合训练第十一场E:Modules
  • 原文地址:https://www.cnblogs.com/bingyang-py/p/12534913.html
Copyright © 2011-2022 走看看