有天上飞的概念, 就要有落地的实现
概念十遍不如代码一遍, 朋友, 希望你把文中所有的代码案例都敲一遍
先赞后看, 养成习惯
SpringBoot 图文教程系列文章目录
SpringBoot 图文教程 1-SpringBoot+Mybatis 环境搭建 https://mp.weixin.qq.com/s/phk6j3ChBP-kPtS2xZeEZg
SpringBoot 图文教程 2 - 日志的使用「logback」「log4j」 https://mp.weixin.qq.com/s/7Mw_xhFF4Q5NtdtcsHc67Q
SpringBoot 图文教程 3-「'初恋'情结」集成 Jsp https://mp.weixin.qq.com/s/BYzVg5NBcF_ou_PyX8ygag
SpringBoot 图文教程 4-SpringBoot 实现文件上传下载 https://mp.weixin.qq.com/s/6ctykPo3eDBEB7YsC0PAZw
SpringBoot 图文教程 5-SpringBoot 中使用 Aop https://mp.weixin.qq.com/s/17qMRlv_mUfwkcVD05Bh2g
SpringBoot 图文教程 6-SpringBoot 中过滤器的使用 https://mp.weixin.qq.com/s/r2BO4UMNRAw_REA6nNFLKw
SpringBoot 图文教程 7-SpringBoot 拦截器的使用姿势这都有 https://mp.weixin.qq.com/s/YpDhuOTpt1vjYjnhnK8YdQ
SpringBoot 图文教程 8-SpringBoot 集成 MBG「代码生成器」 https://mp.weixin.qq.com/s/uGYO4fkw03Kxpfp_PIA8rQ
SpringBoot 图文教程 9-SpringBoot 导入导出 Excel 「Apache Poi」 https://mp.weixin.qq.com/s/BXfxhO5rFFg6XZQ0rZgGMg
SpringBoot 图文教程 10 - 模板导出 | 百万数据 Excel 导出 | 图片导出「easypoi」 https://mp.weixin.qq.com/s/8Yqfn27UCFP2lU3_IYb5AQ
SpringBoot 图文教程 11 - 从此不写 mapper 文件「SpringBoot 集成 MybatisPlus」 https://mp.weixin.qq.com/s/8KG5Wj77MYEUCIRFqWBdPQ
SpringBoot 图文教程 12-SpringData Jpa 的基本使用 https://mp.weixin.qq.com/s/gPfSjBj1hMWf23J50d5Z_g
SpringBoot 图文教程 13-SpringBoot+IDEA 实现代码热部署 https://mp.weixin.qq.com/s/DYP_12V01D0NJGEBdwK9Ew
SpringBoot 图文教程 14 - 阿里开源 EasyExcel「为百万数据读写设计」 https://mp.weixin.qq.com/s/FNuL3maNtiFCVR7hREYpLA
SpringBoot 图文教程 15 - 项目异常怎么办?「跳转 404 错误页面」「全局异常捕获」 https://mp.weixin.qq.com/s/O97_ZqoUCl5fICXHbSCf2Q
SpringBoot 图文教程 16-SpringBoot 多模块开发「web」「打包」 https://mp.weixin.qq.com/s/CDWnG0wr6hk6TvDYIELIaQ
前言
问个问题: 通过 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 请求方式:
url 拼接参数
url 拼接参数「占位符的方式」
获取响应实体对象「响应状态码」
- /**
- * 测试 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 请求三种情况
模拟携带表单参数
url 拼接参数
请求成功之后, 获取跳转地址
- /**
- * 测试 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 更多的用法, 请持续关注本系列教程.
来源: https://www.cnblogs.com/bingyang-py/p/12534913.html