有天上飞的概念,就要有落地的实现
概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍
先赞后看,养成习惯
springboot 图文教程系列文章目录
问个问题:通过java代码怎么发送http请求,请求另一个java程序的controller方法呢?
好像真的有点触及到知识盲区了呦
在以前的代码中,java程序都是被请求的一方,发送请求的要么是ajax,要么是浏览器,要么是postman等,今天就来一起学习一下如何通过java代码发送http请求。
因为我们要通过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"; } }
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); } }
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/bingqilinpeishenme/boot-demo/tree/master
恭喜你完成了本章的学习,为你鼓掌!如果本文对你有帮助,请帮忙点赞,评论,转发,这对作者很重要,谢谢。
让我们再次回顾本文的学习目标
- 掌握springboot中resttemplate的使用
要掌握springboot更多的用法,请持续关注本系列教程。
欢迎关注本人公众号:鹿老师的java笔记,将在长期更新java技术图文教程和视频教程,java学习经验,java面试经验以及java实战开发经验。
如对本文有疑问, 点击进行留言回复!!
mac os 新系统配置—— anaconda安装及管理——idea安装配置
ubuntu 16.04 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) 亲试可行
网友评论