有天上飞的概念,就要有落地的实现html
- 概念十遍不如代码一遍,朋友,但愿你把文中全部的代码案例都敲一遍
- 先赞后看,养成习惯
SpringBoot 图文教程系列文章目录java
问个问题:经过Java代码怎么发送Http请求,请求另外一个Java程序的Controller方法呢?git
好像真的有点触及到知识盲区了呦web
在之前的代码中,Java程序都是被请求的一方,发送请求的要么是Ajax,要么是浏览器,要么是postman等,今天就来一块儿学习一下如何经过Java代码发送Http请求。面试
由于咱们要经过RestTemplate发送请求,请求另一个项目的Controller层方法(接口),因此咱们首先须要一个被请求的项目。
关于这个项目,我已经搭建好了,码云地址为:https://gitee.com/bingqilinpe...spring
在项目中有三个方法,分别是测试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"; } }
Spring中封装的经过Java代码发送RestFul请求的模板类,内置发送get post delete等请求的方法,在SpringBoot中只要导入spring-boot-starter-web的依赖能够直接使用。app
肯定项目中导入spring-boot-starter-web的依赖。ide
第一步:配置RestTemplatespring-boot
/** * 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); } }
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请求 */ @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请求 */ @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 便可搞定。
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请求的第二个参数是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/bingqilinpe...恭喜你完成了本章的学习,为你鼓掌!若是本文对你有帮助,请帮忙点赞,评论,转发,这对做者很重要,谢谢。
让咱们再次回顾本文的学习目标
- 掌握SpringBoot中RestTemplate的使用
要掌握SpringBoot更多的用法,请持续关注本系列教程。
欢迎关注本人公众号:鹿老师的Java笔记,将在长期更新Java技术图文教程和视频教程,Java学习经验,Java面试经验以及Java实战开发经验。