记录:287
场景:基于Spring Boot使用Java调用http请求的6种方式。服务端发布一个POST请求和2个GET请求。使用6种方式实现的客户端都调用服务端发布的这3个方法。可以直观感受和比对6种http请求的客户端。
版本:
- Spring Boot 2.6.3
- Spring Framework 5.3.15
- Spring Cloud 2021.0.1
一、案例场景
本例实现6种方式客户端调用同一个服务端的3种方法。
1.服务端
在服务端发布一个POST请求,2个GET请求。
1.1 接口信息
(1)POST请求
- [访问URL]: http://127.0.0.1:19091/server/comm/f1
- [请求方式]: POST
- [请求参数]: JSON
- {"userName":"HangZhou20220719","tradeName":"Vue进阶教程"}
- [返回值]: JSON
- {code=200, message=成功}
(2)GET请求(一)
- [访问URL]: http://127.0.0.1:19091/server/comm/f2
- [请求方式]: GET
- [请求参数]: String
- obj=HangZhou20220719
- [返回值]: JSON
- {code=200, message=成功}
(3)GET请求(二)
- [访问URL]: http://127.0.0.1:19091/server/comm/f3/{obj}
- [请求方式]: GET
- [请求参数]: String
- obj=HangZhou20220719
- [返回值]: JSON
- {code=200, message=成功}
1.2 服务端代码
服务端3个接口代码。
- @Slf4j
- @RestController
- @RequestMapping("/comm")
- public class CommonController {
- /**
- * 1.发布POST请求
- * 入参注解: @RequestBody
- * 返回注解: @ResponseBody(@RestController包含此注解)
- * */
- @PostMapping("/f1")
- public Object f1(@RequestBody Object obj) {
- log.info("CommonController->f1,接收参数,obj = " + obj.toString());
- log.info("CommonController->f1,处理业务.");
- log.info("CommonController->f1,返回.");
- return ResultObj.builder().code("200").message("成功").build();
- }
- /**
- * 2.发布GET请求
- * 入参注解: @RequestParam
- * 返回注解: @ResponseBody(@RestController包含此注解)
- * */
- @GetMapping ("/f2")
- public Object f2(@RequestParam("obj") String obj) {
- log.info("CommonController->f2,接收参数,obj = " + obj.toString());
- log.info("CommonController->f2,处理业务.");
- log.info("CommonController->f2,返回.");
- return ResultObj.builder().code("200").message("成功").build();
- }
- /**
- * 3.发布GET请求
- * 入参注解: @PathVariable
- * 返回注解: @ResponseBody(@RestController包含此注解)
- * */
- @GetMapping ("/f3/{obj}")
- public Object f3(@PathVariable("obj") String obj) {
- log.info("CommonController->f3,接收参数,obj = " + obj.toString());
- log.info("CommonController->f3,处理业务.");
- log.info("CommonController->f3,返回.");
- return ResultObj.builder().code("200").message("成功").build();
- }
- }
1.3 服务端辅助对象
服务端辅助对象。
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- @Builder
- public class ResultObj {
- private String code;
- private String message;
- }
二、Java调用http请求的6种方式
1.使用HttpURLConnection调用http请求
(1)Jar包位置
HttpURLConnection,全称:java.net.HttpURLConnection。
JDK 1.8中自带的rt.jar包中的java.net包内的类。
(2)客户端代码
- public class Utils01JdkClient {
- public static void main(String[] args) throws Exception {
- f1();
- f2();
- f3();
- }
- /**
- * 1.使用HttpURLConnection调用服务端的POST请求
- * 服务端入参注解: @RequestBody
- */
- public static void f1() throws Exception {
- // 1.请求URL
- String postUrl = "http://127.0.0.1:19091/server/comm/f1";
- // 2.请求参数JSON格式
- Map
map = new HashMap<>(); - map.put("userName", "HangZhou20220718");
- map.put("tradeName", "Vue进阶教程");
- String json = JSON.toJSONString(map);
- // 3.创建连接与设置连接参数
- URL urlObj = new URL(postUrl);
- HttpURLConnection httpConn = (HttpURLConnection) urlObj.openConnection();
- httpConn.setRequestMethod("POST");
- httpConn.setRequestProperty("Charset", "UTF-8");
- // POST请求且JSON数据,必须设置
- httpConn.setRequestProperty("Content-Type", "application/json");
- // 打开输出流,默认是false
- httpConn.setDoOutput(true);
- // 打开输入流,默认是true,可省略
- httpConn.setDoInput(true);
- // 4.从HttpURLConnection获取输出流和写数据
- OutputStream oStream = httpConn.getOutputStream();
- oStream.write(json.getBytes());
- oStream.flush();
- // 5.发起http调用(getInputStream触发http请求)
- if (httpConn.getResponseCode() != 200) {
- throw new Exception("调用服务端异常.");
- }
- // 6.从HttpURLConnection获取输入流和读数据
- BufferedReader br = new BufferedReader(
- new InputStreamReader(httpConn.getInputStream()));
- String resultData = br.readLine();
- System.out.println("从服务端返回结果: " + resultData);
- // 7.关闭HttpURLConnection连接
- httpConn.disconnect();
- }
- /**
- * 2.使用HttpURLConnection调用服务端的GET请求
- * 服务端入参注解: @RequestParam
- */
- public static void f2() throws Exception {
- // 1.请求URL与组装请求参数
- String getUrl = "http://127.0.0.1:19091/server/comm/f2";
- String obj = "Vue进阶教程";
- String para = "?obj=" + URLEncoder.encode(obj, "UTF-8");
- getUrl = getUrl + para;
- // 2.创建连接与设置连接参数
- URL urlObj = new URL(getUrl);
- HttpURLConnection httpConn = (HttpURLConnection) urlObj.openConnection();
- httpConn.setRequestMethod("GET");
- httpConn.setRequestProperty("Charset", "UTF-8");
- // 3.发起http调用(getInputStream触发http请求)
- if (httpConn.getResponseCode() != 200) {
- throw new Exception("调用服务端异常.");
- }
- // 4.从HttpURLConnection获取输入流和读数据
- BufferedReader br = new BufferedReader(
- new InputStreamReader(httpConn.getInputStream()));
- String resultData = br.readLine();
- System.out.println("从服务端返回结果: " + resultData);
- // 5.关闭HttpURLConnection连接
- httpConn.disconnect();
- }
- /**
- * 3.使用HttpURLConnection调用服务端的GET请求
- * 服务端入参注解: @PathVariable
- */
- public static void f3() throws Exception {
- // 1.请求URL与组装请求参数
- String getUrl = "http://127.0.0.1:19091/server/comm/f3/";
- String obj = "Vue进阶教程";
- obj = URLEncoder.encode(obj, "UTF-8");
- getUrl = getUrl + obj;
- URL urlObj = new URL(getUrl);
- // 2.创建连接与设置连接参数
- HttpURLConnection httpConn = (HttpURLConnection) urlObj.openConnection();
- httpConn.setRequestMethod("GET");
- httpConn.setRequestProperty("charset", "UTF-8");
- // 3.发起http调用(getInputStream触发http请求)
- if (httpConn.getResponseCode() != 200) {
- throw new Exception("调用服务端异常.");
- }
- // 4.从HttpURLConnection获取输入流和读数据
- BufferedReader br = new BufferedReader(
- new InputStreamReader(httpConn.getInputStream()));
- String resultData = br.readLine();
- System.out.println("从服务端返回结果: " + resultData);
- // 5.关闭HttpURLConnection连接
- httpConn.disconnect();
- }
- }
2.使用commons-httpclient调用http请求
(1)Jar包位置
commons-httpclient,比较早的Jar包,在MVNRepository仓库中,查看的最新维护时间是:2007年8月。
- <dependency>
- <groupId>commons-httpclientgroupId>
- <artifactId>commons-httpclientartifactId>
- <version>3.1version>
- dependency>
(2)客户端代码
- public class Utils02CommonsHttpClient {
-
- public static void main(String[] args) throws Exception {
- f1();
- f2();
- f3();
- }
- /**
- * 1.使用commons-httpclient调用服务端的POST请求
- * 服务端入参注解: @RequestBody
- */
- public static void f1() throws Exception {
- // 1.请求URL
- String postUrl = "http://127.0.0.1:19091/server/comm/f1";
- // 2.请求参数
- Map
map = new HashMap<>(); - map.put("userName", "HangZhou20220718");
- map.put("tradeName", "Vue进阶教程");
- String json = JSON.toJSONString(map);
- // 3.创建连接与设置连接参数
- HttpClient httpClient = new HttpClient();
- PostMethod postMethod = new PostMethod(postUrl);
- postMethod.addRequestHeader("Content-Type", "application/json");
- RequestEntity entity = new StringRequestEntity(json, "application/json", "UTF-8");
- postMethod.setRequestEntity(entity);
- //解决返回值中文乱码
- postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
- String resultData = "";
- // 4.发起请求
- int code = httpClient.executeMethod(postMethod);
- if (code != 200) {
- throw new Exception("调用服务端异常.");
- }
- // 5.接收返回值
- resultData = postMethod.getResponseBodyAsString();
- System.out.println("从服务端返回结果: " + resultData);
- // 6.关闭连接
- postMethod.releaseConnection();
- }
- /**
- * 2.使用commons-httpclient调用服务端的GET请求
- * 服务端入参注解: @RequestParam
- */
- public static void f2() throws Exception {
- // 1.请求URL与组装请求参数
- String getUrl = "http://127.0.0.1:19091/server/comm/f2";
- String obj = "Vue进阶教程";
- //入参有中文需要编码
- String para = "?obj=" + URLEncoder.encode(obj, "UTF-8");
- getUrl = getUrl + para;
- // 2.创建连接与设置连接参数
- HttpClient httpClient = new HttpClient();
- GetMethod getMethod = new GetMethod(getUrl);
- //解决返回值中文乱码
- getMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
- // 3.发起请求
- int code = httpClient.executeMethod(getMethod);
- String resultData = "";
- if (code != 200) {
- throw new Exception("调用服务端异常.");
- }
- // 4.接收返回值
- resultData = getMethod.getResponseBodyAsString();
- System.out.println("从服务端返回结果: " + resultData);
- // 5.关闭连接
- getMethod.releaseConnection();
- }
- /**
- * 3.使用commons-httpclient调用服务端的GET请求
- * 服务端入参注解: @PathVariable
- */
- public static void f3() throws Exception {
- // 1.请求URL与组装请求参数
- String getUrl = "http://127.0.0.1:19091/server/comm/f3/";
- String obj = "Vue进阶教程";
- //入参有中文需要编码
- obj = URLEncoder.encode(obj, "UTF-8");
- getUrl = getUrl + obj;
- // 2.创建连接与设置连接参数
- HttpClient httpClient = new HttpClient();
- GetMethod getMethod = new GetMethod(getUrl);
- //解决返回值中文乱码
- getMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
- // 3.发起请求
- int code = httpClient.executeMethod(getMethod);
- String resultData = "";
- if (code != 200) {
- throw new Exception("调用服务端异常.");
- }
- // 4.接收返回值
- resultData = getMethod.getResponseBodyAsString();
- System.out.println("从服务端返回结果: " + resultData);
- // 5.关闭连接
- getMethod.releaseConnection();
- }
- }
3.使用org.apache.httpcomponents调用http请求
(1)Jar包位置
httpcomponents,在MVNRepository仓库中,查看的最新维护时间是:2020年10月。
- <dependency>
- <groupId>org.apache.httpcomponentsgroupId>
- <artifactId>httpclientartifactId>
- <version>4.5.13version>
- dependency>
(2)客户端代码
- public class Utils03HttpComponentsClient {
- public static void main(String[] args) throws Exception {
- f1();
- f2();
- f3();
- }
- /**
- * 1.使用org.apache.httpcomponents调用服务端的POST请求
- * 服务端入参注解: @RequestBody
- */
- public static void f1() throws Exception {
- // 1.请求URL
- String postUrl = "http://127.0.0.1:19091/server/comm/f1";
- // 2.请求参数
- Map
map = new HashMap<>(); - map.put("userName", "HangZhou20220718");
- map.put("tradeName", "Vue进阶教程");
- String json = JSON.toJSONString(map);
- // 3.创建连接与设置连接参数
- CloseableHttpClient httpClient = HttpClientBuilder.create().build();
- HttpPost httpPost = new HttpPost(postUrl);
- StringEntity entity = new StringEntity(json);
- entity.setContentEncoding("UTF-8");
- entity.setContentType("application/json");
- httpPost.setEntity(entity);
- // 4.发起请求与接收返回值
- HttpResponse response = httpClient.execute(httpPost);
- if (response.getStatusLine().getStatusCode() != 200) {
- throw new Exception("调用服务端异常.");
- }
- HttpEntity res = response.getEntity();
- String resultData = EntityUtils.toString(res);
- System.out.println("从服务端返回结果: " + resultData);
- // 5.关闭连接
- httpClient.close();
- }
- /**
- * 2.使用org.apache.httpcomponents调用服务端的GET请求
- * 服务端入参注解: @RequestParam
- */
- public static void f2() throws Exception {
- // 1.请求URL与组装请求参数
- String getUrl = "http://127.0.0.1:19091/server/comm/f2";
- String obj = "Vue进阶教程";
- String para = "?obj=" + URLEncoder.encode(obj, "UTF-8");
- getUrl = getUrl + para;
- // 2.创建连接与设置连接参数
- CloseableHttpClient httpClient = HttpClientBuilder.create().build();
- HttpGet httpGet = new HttpGet(getUrl);
- // 3.发起请求与接收返回值
- HttpResponse response = httpClient.execute(httpGet);
- if (response.getStatusLine().getStatusCode() != 200) {
- throw new Exception("调用服务端异常.");
- }
- HttpEntity res = response.getEntity();
- String resultData = EntityUtils.toString(res);
- System.out.println("从服务端返回结果: " + resultData);
- // 4.关闭连接
- httpClient.close();
- }
-
- /**
- * 3.使用org.apache.httpcomponents调用服务端的GET请求
- * 服务端入参注解: @PathVariable
- */
- public static void f3() throws Exception {
- // 1.请求URL与组装请求参数
- String getUrl = "http://127.0.0.1:19091/server/comm/f3/";
- String obj = "Vue进阶教程";
- //入参有中文需要编码
- obj = URLEncoder.encode(obj, "UTF-8");
- getUrl = getUrl + obj;
- // 2.创建连接与设置连接参数
- CloseableHttpClient httpClient = HttpClientBuilder.create().build();
- HttpGet httpGet = new HttpGet(getUrl);
- // 3.发起请求与接收返回值
- HttpResponse response = httpClient.execute(httpGet);
- if (response.getStatusLine().getStatusCode() != 200) {
- throw new Exception("调用服务端异常.");
- }
- HttpEntity res = response.getEntity();
- String resultData = EntityUtils.toString(res);
- System.out.println("从服务端返回结果: " + resultData);
- // 4.关闭连接
- httpClient.close();
- }
- }
4.使用OkHttp调用http请求
(1)Jar包位置
com.squareup.okhttp3,本例使用版本。
- <dependency>
- <groupId>com.squareup.okhttp3groupId>
- <artifactId>okhttpartifactId>
- <version>4.10.0version>
- <exclusions>
- <exclusion>
- <groupId>com.google.androidgroupId>
- <artifactId>androidartifactId>
- exclusion>
- exclusions>
- dependency>
(2)客户端代码
- public class Utils04OkHttpClient {
- public static void main(String[] args) throws Exception {
- f1();
- f2();
- f3();
- }
- /**
- * 1.使用okhttp调用服务端的POST请求
- * 服务端入参注解: @RequestBody
- * */
- public static void f1() throws Exception {
- // 1.请求URL
- String postUrl = "http://127.0.0.1:19091/server/comm/f1";
- // 2.请求参数
- Map
map = new HashMap<>(); - map.put("userName", "HangZhou20220718");
- map.put("tradeName", "Vue进阶教程");
- String json = JSON.toJSONString(map);
- // 3.创建连接与设置连接参数
- MediaType mediaType = MediaType.parse("application/json; charset=UTF-8");
- RequestBody requestBody = RequestBody.Companion.create(json, mediaType);
- Request request = new Request.Builder().url(postUrl).post(requestBody).build();
- OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
- // 4.发起请求与接收返回值
- Response response = okHttpClient.newCall(request).execute();
- String resultData = response.body().string();
- System.out.println("从服务端返回结果: " + resultData);
- }
- /**
- * 2.使用okhttp调用服务端的GET请求
- * 服务端入参注解: @RequestParam
- * */
- public static void f2() throws Exception {
- // 1.请求URL与组装请求参数
- String getUrl = "http://127.0.0.1:19091/server/comm/f2";
- String obj = "Vue进阶教程";
- String para = "?obj=" + URLEncoder.encode(obj, "UTF-8");
- getUrl = getUrl + para;
- // 2.创建连接与设置连接参数
- Request request = new Request.Builder().url(getUrl).build();
- OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
- // 3.发起请求与接收返回值
- Response response = okHttpClient.newCall(request).execute();
- String resultData = response.body().string();
- System.out.println("从服务端返回结果: " + resultData);
- }
- /**
- * 3.使用okhttp调用服务端的GET请求
- * 服务端入参注解: @PathVariable
- * */
- public static void f3() throws Exception {
- // 1.请求URL与组装请求参数
- String getUrl = "http://127.0.0.1:19091/server/comm/f3/";
- String obj = "Vue进阶教程";
- obj = URLEncoder.encode(obj, "UTF-8");
- getUrl = getUrl + obj;
- // 2.创建连接与设置连接参数
- Request request = new Request.Builder().url(getUrl).build();
- OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
- // 3.发起请求与接收返回值
- Response response = okHttpClient.newCall(request).execute();
- String resultData = response.body().string();
- System.out.println("从服务端返回结果: " + resultData);
- }
- }
5.使用RestTemplate调用http请求
(1)Jar包位置
RestTemplate,全称org.springframework.web.client.RestTemplate。
本例使用版本。
- dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-webartifactId>
- <version>5.3.15version>
- <scope>compilescope>
- dependency>
(2)客户端代码
- public class Utils05RestTemplateClient {
- public static void main(String[] args) throws Exception {
- f1();
- f2();
- f3();
- }
- /**
- * 1.使用RestTemplate调用服务端的POST请求
- * 服务端入参注解: @RequestBody
- */
- public static void f1() throws Exception {
- // 1.请求URL
- String postUrl = "http://127.0.0.1:19091/server/comm/f1";
- // 2.请求参数JSON格式
- Map
map = new HashMap<>(); - map.put("userName", "HangZhou20220718");
- map.put("tradeName", "Vue进阶教程");
- String json = JSON.toJSONString(map);
- // 3.创建RestTemplate
- RestTemplate restTemplate = new RestTemplate();
- // 4.设置RestTemplate参数(请求头和body)
- HttpHeaders headers = new HttpHeaders();
- MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
- headers.setContentType(mediaType);
- headers.add("Accept", "application/json");
- HttpEntity
entity = new HttpEntity<>(json, headers); - // 5.使用RestTemplate发起请求与接收返回值
- String resultData = restTemplate.postForObject(postUrl, entity, String.class);
- System.out.println("从服务端返回结果: " + resultData);
- }
- /**
- * 2.使用RestTemplate调用服务端的GET请求
- * 服务端入参注解: @RequestParam
- */
- public static void f2() throws Exception {
- // 1.请求URL与组装请求参数
- String getUrl = "http://127.0.0.1:19091/server/comm/f2";
- String obj = "Vue进阶教程";
- String para = "?obj=" + obj;
- getUrl = getUrl + para;
- // 2.创建RestTemplate
- RestTemplate restTemplate = new RestTemplate();
- // 3.使用RestTemplate发起请求与接收返回值
- String resultData = restTemplate.getForObject(getUrl, String.class);
- System.out.println("从服务端返回结果: " + resultData);
- }
- /**
- * 3.使用RestTemplate调用服务端的GET请求
- * 服务端入参注解: @PathVariable
- */
- public static void f3() throws Exception {
- // 1.请求URL与组装请求参数
- String getUrl = "http://127.0.0.1:19091/server/comm/f3/";
- String obj = "Vue进阶教程";
- getUrl = getUrl + obj;
- // 2.创建RestTemplate
- RestTemplate restTemplate = new RestTemplate();
- // 3.使用RestTemplate发起请求与接收返回值
- String resultData = restTemplate.getForObject(getUrl, String.class);
- System.out.println("从服务端返回结果: " + resultData);
- }
- }
6.使用OpenFeign调用http请求
(1)Jar包位置
Spring Cloud OpenFeign是Spring Cloud全家桶组件成员。
本例版本:Spring Cloud 2021.0.1;spring-cloud-openfeign 3.1.1
- <dependency>
- <groupId>org.springframework.cloudgroupId>
- <artifactId>spring-cloud-starter-openfeignartifactId>
- dependency>
- <dependency>
- <groupId>org.springframework.cloudgroupId>
- <artifactId>spring-cloud-starter-loadbalancerartifactId>
- dependency>
(2)客户端代码(Feign接口)
- @FeignClient(contextId = "utils06OpenFeign",
- value = "example-server")
- public interface Utils06OpenFeignClient {
- /**
- * 1.使用openfeign调用服务端的POST请求
- * 服务端入参注解: @RequestBody
- * */
- @ResponseBody
- @PostMapping("/server/comm/f1")
- Object f1(@RequestBody Object obj);
- /**
- * 2.使用openfeign调用服务端的GET请求
- * 服务端入参注解: @RequestParam
- * */
- @ResponseBody
- @GetMapping("/server/comm/f2")
- Object f2(@RequestParam("obj") String obj);
- /**
- * 3.使用openfeign调用服务端的GET请求
- * 服务端入参注解: @PathVariable
- * */
- @ResponseBody
- @GetMapping("/server/comm/f3/{obj}")
- Object f3(@PathVariable("obj") String obj);
- }
(3)客户端代码(调用Feign接口)
- /**
- * 触发请求:
- * http://127.0.0.1:19092/client/exam/f
- * */
- @Slf4j
- @RestController
- @RequestMapping("/exam")
- public class ExampleController {
- /**
- * 1.注入Feign接口
- * */
- @Autowired
- private Utils06OpenFeignClient feignClient;
-
- /**
- * 2.调用Feign接口
- * */
- @GetMapping("/f")
- public void f() throws Exception {
-
- log.info("使用Feign调用服务端f1: ");
- Map
map = new HashMap<>(); - map.put("userName", "HangZhou20220718");
- map.put("tradeName", "Vue进阶教程");
- Object resultDataF1 = feignClient.f1(map);
- log.info("使用Feign调用服务端f1,返回结果: " + resultDataF1);
-
- log.info("使用Feign调用服务端f2: ");
- String obj = "Vue进阶教程";
- Object resultDataF2 = feignClient.f2(obj);
- log.info("使用Feign调用服务端f2,返回结果: " + resultDataF2);
-
- log.info("使用Feign调用服务端f3: ");
- String obj2 = "Vue进阶教程";
- Object resultDataF3 = feignClient.f3(obj2);
- log.info("使用Feign调用服务端f3,返回结果: " + resultDataF3);
- }
- }
(4)本例使用基础
Spring Cloud OpenFeign是Spring Cloud 组件,搭建的微服务都是基于Spring Cloud架构。本例两个微服务:
服务端:example-server
客户端:example-feign-client
服务端和客户端都使用Nacos作为服务注册和发现中心,在客户端example-feign-client中整合Spring Cloud OpenFeign,服务端不需要修改。在启动类中加@EnableFeignClients注解,在使用OpenFeign的接口上加@FeignClient注解。
以上,感谢。
2022年7月20日