# Java 使用代码调用接口 (HttpClient 详细使用实例)

了解什么是 HttpClient

Java 中的 HttpClient 是用于进行 HTTP 请求和响应的类库。它提供了一种简单,灵活,可扩展的方式来发送 HTTP 请求 ==,并处理 HTTP 响应 ==。HttpClient 的核心功能包括创建 HTTP 请求,设置请求参数,发送请求,接收响应,处理响应数据以及处理异常情况。它使得在 Java 应用程序中实现 HTTP 通信变得更加方便和高效

HttpClient 的主要功能

实现了所有 HTTP 的方法 (GET,POST,PUT,DELETE,HEAD,OPTIONS) 等

支持 HTTPS 协议

支持自动 (跳转) 转向

. . .

# 1 引入依赖

# 1.1 引入 HttpClient 的依赖

<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.5.5</version>
</dependency>

# 1.2 引入 fastjson 依赖

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.47</version>
</dependency>

PS:本人引入依赖的目的是,在后续实例中,会用到 "将对象转化为 json 字符串的功能",也可以引其它有此功能的依赖

PS:使用的是 SpringBoot 工程通过 HttpClient 发送请求到 controller 接口,并将 controller 接口的响应返回到 HttpClient 中来接收。

# 2 详细使用示例

声明:此示例中,以 Java 发送 HttpClient (在 test 里面单元测试发送的);也是以 Java 接收的 (在 controller 里面接收的)

# 2.1 GET 无参

HttpClient 发送示例:

@Test
void contextLoads() {
   // 通过建造者模式 获取 HttpClient 对象
   CloseableHttpClient httpClient = HttpClientBuilder.create().build();
   // 创建 Get 请求指定请求路径
   HttpGet httpGet = new HttpGet("http://localhost/doGetControllerOne");
   CloseableHttpResponse response = null;
   try {
      // 发送 Get 请求 得到响应对象
      response = httpClient.execute(httpGet);
      // 从响应对象中后去响应实体
      HttpEntity responseEntity = response.getEntity();
      System.out.println("响应状态为:" + response.getStatusLine());
      if (responseEntity != null) {
         System.out.println("响应内容长度为:" + responseEntity.getContentLength());
         System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
      }
   } catch (IOException e) {
      throw new RuntimeException(e);
   } finally {
      // 释放资源
      try {
         if (response != null) {
            response.close();
         }
         if (httpClient != null) {
            httpClient.close();
         }
      } catch (IOException e) {
         throw new RuntimeException(e);
      }
   }
}

对应接收示例:

@RestController
public class TestDemo {
    @GetMapping("doGetControllerOne")
    public String doGetControllerOne() {
        return "hello";
    }
}

打印结果:

响应状态为:HTTP/1.1 200 
响应内容长度为:5
响应内容为:hello

# 2.2 GET 有参 (方式一:直接拼接 URL)

HttpClient 发送示例:

@Test
public void test1() {
   // 通过建造者模式 获取 HttpClient 对象
   CloseableHttpClient httpClient = HttpClientBuilder.create().build();
   // 使用 SpringBuffer 来进行参数的拼接
   StringBuffer params = new StringBuffer();
   try {
      // 使用 URLEncoder 进行编码防止中文乱码
      params.append("name=" + URLEncoder.encode("Xxx", "utf-8"));
      params.append("&");
      params.append("age=24");
   } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
   }
   // 创建 Get 请求
   HttpGet httpGet = new HttpGet("http://localhost/doGetControllerTwo?" + params);
   CloseableHttpResponse response = null;
   try {
      // 配置请求信息
      RequestConfig requestConfig = RequestConfig.custom()
         // 链接超时时间
         .setConnectTimeout(5000)
         // 请求超时时间
         .setConnectionRequestTimeout(5000)
         //socket 读写超时时间
         .setSocketTimeout(5000)
         // 是否允许重定向
         .setRedirectsEnabled(true)
         .build();
      // 将配置信息添加到 Get 请求中
      httpGet.setConfig(requestConfig);
      // 执行 Get 请求获取响应对象
      response = httpClient.execute(httpGet);
      // 获取响应实体
      HttpEntity entity = response.getEntity();
      System.out.println("响应状态为:" + response.getStatusLine());
      if (entity != null) {
         System.out.println("响应内容长度为:" + entity.getContentLength());
         System.out.println("响应内容为:" + EntityUtils.toString(entity));
      }
   } catch (IOException e) {
      throw new RuntimeException(e);
   } finally {
      try {
         // 释放资源
         if (response != null) {
            response.close();
         }
         if (httpClient != null) {
            httpClient.close();
         }
      } catch (IOException e) {
         throw new RuntimeException(e);
      }
   }
}

对应接收示例:

@GetMapping("doGetControllerTwo")
public String doGetControllerOne(String name, Integer age) {
   return "今年" + name + ", 已经" + age + " 岁了";
}

打印结果:

响应状态为:HTTP/1.1 200 
响应内容长度为:26
响应内容为:今年Xxx, 已经24 岁了

# 2.3 GET 有参 (方式二:使用 URL 获得 HttpGet)

HttpClient 发送示例:

@Test
public void test2() {
   // 通过建造者模式获取 HttpClient 对象
   CloseableHttpClient httpClient = HttpClientBuilder.create().build();
   URI uri = null;
   // 创建 List 集合类型为 用于表示键值对的接口通常用于 HTTP 请求和响应的参数
   List<NameValuePair> params = new ArrayList<>();
   //  设置参数
   params.add(new BasicNameValuePair("name", "Xxx"));
   params.add(new BasicNameValuePair("age", "18"));
   try {
      // 构建 URI 对象的信息
      uri = new URIBuilder()
         .setScheme("http")
         .setHost("localhost")
         .setPath("/doGetControllerTwo")
         .setParameters(params)
         .build();
   } catch (URISyntaxException e) {
      throw new RuntimeException(e);
   }
   // 创建 Get 请求传入请求信息
   HttpGet httpGet = new HttpGet(uri);
   // 配置信息
   RequestConfig requestConfig = RequestConfig.custom()
      .setConnectTimeout(5000)
      .setConnectionRequestTimeout(5000)
      .setSocketTimeout(5000)
      .setRedirectsEnabled(true)
      .build();
   // 将配置信息传入请求中
   httpGet.setConfig(requestConfig);
   CloseableHttpResponse response = null;
   try {
      // 执行请求获得响应对象
      response = httpClient.execute(httpGet);
      // 通过响应对象获取实体
      HttpEntity entity = response.getEntity();
      System.out.println("响应状态为:" + response.getStatusLine());
      if (entity != null) {
         System.out.println("响应内容长度为:" + entity.getContentLength());
         System.out.println("响应内容为:" + EntityUtils.toString(entity));
      }
   } catch (IOException e) {
      throw new RuntimeException(e);
   } finally {
      // 释放资源
      try {
         if (response != null) {
            response.close();
         }
         if (httpClient != null) {
            httpClient.close();
         }
      } catch (IOException e) {
         throw new RuntimeException(e);
      }
   }
}

对应接收示例:

@GetMapping("doGetControllerTwo")
public String doGetControllerOne(String name, Integer age) {
   return "今年" + name + ", 已经" + age + " 岁了";
}

打印结果:

响应状态为:HTTP/1.1 200 
响应内容长度为:26
响应内容为:今年Xxx, 已经18 岁了

# 2.4 POST 无参

HttpClient 发送示例:

@Test
public void test3() {
   CloseableHttpClient httpClient = HttpClientBuilder.create().build();
   HttpPost httpPost = new HttpPost("http://localhost/doPostControllerOne");
   CloseableHttpResponse response = null;
   try {
      response = httpClient.execute(httpPost);
      HttpEntity entity = response.getEntity();
      System.out.println("状态为:" + response.getStatusLine());
      if (entity != null) {
         System.out.println("获取响应长度为:" + entity.getContentLength());
         System.out.println("获取响应内容为:" + EntityUtils.toString(entity));
      }
   } catch (IOException e) {
      throw new RuntimeException(e);
   } finally {
      try {
         if (response != null) {
            response.close();
         }
         if (httpClient != null) {
            httpClient.close();
         }
      } catch (IOException e) {
         throw new RuntimeException(e);
      }
   }
}

对应接收示例:

@PostMapping("doPostControllerOne")
public String doPostControllerOne() {
   return "这个post请求没有任何参数";
}

打印结果:

状态为:HTTP/1.1 200 
获取响应长度为:34
获取响应内容为:这个post请求没有任何参数

# 2.5 POST 有参 (普通参数)

PS:POST 传递普通参数时,方式与 GET 一样即可,这里以直接在 URL 后缀上参数的方式示例

HttpClient 发送示例:

@Test
public void test4() {
   // 通过构造者模式获取 HttpClient 对象
   CloseableHttpClient httpClient = HttpClientBuilder.create().build();
   // 创建字符缓冲区用于拼接参数
   StringBuffer params = new StringBuffer();
   try {
      params.append("name=" + URLEncoder.encode("Xxx", "utf-8"));
      params.append("&");
      params.append("age=24");
   } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
   }
   // 创建 Post 请求
   HttpPost httpPost = new HttpPost("http://localhost/doPostControllerTwo?" + params);
   CloseableHttpResponse response = null;
   try {
      // 执行请求并返回响应对象
      response = httpClient.execute(httpPost);
      // 获取实体
      HttpEntity entity = response.getEntity();
      System.out.println("状态为:" + response.getStatusLine());
      if (entity != null) {
         System.out.println("响应内容长度为:" + entity.getContentLength());
         System.out.println("响应内容为:" + EntityUtils.toString(entity));
      }
   } catch (IOException e) {
      throw new RuntimeException(e);
   } finally {
      // 释放资源
      try {
         if (response != null) {
            response.close();
         }
         if (httpClient != null) {
            httpClient.close();
         }
      } catch (IOException e) {
         throw new RuntimeException(e);
      }
   }
}

对应接收示例:

@PostMapping("doPostControllerTwo")
public String doPostControllerTwo(String name, Integer age) {
   return "今年" + name + ", 已经" + age + " 岁了";
}

打印结果:

状态为:HTTP/1.1 200 
响应内容长度为:26
响应内容为:今年Xxx, 已经24 岁了

# 2.6 POST 有参 (对象参数)

HttpClient 发送示例:

@Test
public void test5() {
   // 通过构建者模式获取 HttpClient 对象
   CloseableHttpClient httpClient = HttpClientBuilder.create().build();
   // 创建 Post 请求
   HttpPost httpPost = new HttpPost("http://localhost/doPostControllerThree");
   // 创建对象并设置属性信息
   User user = new User();
   user.setName("刘桑");
   user.setAge(20);
   // 将对象序列化为 JSON 数据
   String jsonString = JSON.toJSONString(user);
   // 设置 json 数据为 utf-8 返回 json 实体
   StringEntity entity = new StringEntity(jsonString, "utf-8");
   // 设置请求的实体数据
   httpPost.setEntity(entity);
   // 设置请求的请求头信息为 json 数据格式
   httpPost.setHeader("Content-Type", "application/json;charset=utf8");
   CloseableHttpResponse response = null;
   try {
      // 执行请求并返回响应对象
      response = httpClient.execute(httpPost);
      // 获取实体
      HttpEntity responseEntity = response.getEntity();
      System.out.println("响应状态为:" + response.getStatusLine());
      if (responseEntity != null) {
         System.out.println("响应内容长度为:" + responseEntity.getContentLength());
         System.out.println("响应内容为" + EntityUtils.toString(responseEntity));
      }
   } catch (IOException e) {
      throw new RuntimeException(e);
   } finally {
      // 释放资源
      try {
         if (response != null) {
            response.close();
         }
         if (httpClient != null) {
            httpClient.close();
         }
      } catch (IOException e) {
         throw new RuntimeException(e);
      }
   }
}

对应接收示例:

@PostMapping("doPostControllerThree")
public User doPostControllerThree(@RequestBody User user) {
   return user;
}

打印结果:

响应状态为:HTTP/1.1 200 
响应内容长度为:-1
响应内容为{"name":"刘桑","age":20}

# 2.7 POST 有参 (普通参数 + 对象参数)

PS:POST 传递普通参数时,方式与 GET 一样即可,这里以通过 URI 获取 HttpPost 的方式为例

HttpClient 发送示例:

@Test
public void test6() {
   // 通过构造者模式获取 HttpClient 对象
   CloseableHttpClient httpClient = HttpClientBuilder.create().build();
   // 创建 List 集合泛型为 键值对的对象用常用于 HTTP 请求的参数和响应的参数
   List<NameValuePair> params = new ArrayList<>();
   params.add(new BasicNameValuePair("flag", "4"));
   params.add(new BasicNameValuePair("meaning", "这是什么鬼?"));
   URI uri = null;
   try {
      // 创建 URI 对象构建 URI 的请求信息
      uri = new URIBuilder()
         .setScheme("http")
         .setHost("localhost")
         .setPath("doPostControllerFour")
         .setParameters(params)
         .build();
   } catch (URISyntaxException e) {
      throw new RuntimeException(e);
   }
   // 创建 Post 请求对象并传入请求信息
   HttpPost httpPost = new HttpPost(uri);
   // 创建 User 对象并设置属性信息
   User user = new User();
   user.setName("刘桑");
   user.setAge(20);
   // 将 User 对象序列化为 JSON 数据并转换为 utf-8 格式的实体数据
   StringEntity entity = new StringEntity(JSON.toJSONString(user), "utf-8");
   // 将实体数据设置到请求实体中
   httpPost.setEntity(entity);
   // 设置请求头信息为 json 格式
   httpPost.setHeader("Content-Type", "application/json;charset=utf8");
   CloseableHttpResponse response = null;
   try {
      // 执行请求并获取响应对象
      response = httpClient.execute(httpPost);
      // 获取实体
      HttpEntity responseEntity = response.getEntity();
      System.out.println("状态为:" + response.getStatusLine());
      if (responseEntity != null) {
         System.out.println("响应内容长度为:" + responseEntity.getContentLength());
         System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
      }
   } catch (IOException e) {
      throw new RuntimeException(e);
   } finally {
      // 释放资源
      try {
         if (response != null) {
            response.close();
         }
         if (httpClient != null) {
            httpClient.close();
         }
      } catch (IOException e) {
         throw new RuntimeException(e);
      }
   }
}

对应接收示例:

@PostMapping("doPostControllerFour")
public UserDto doPostControllerFour(@RequestBody User user, Integer flag, String meaning) {
   UserDto userDto = new UserDto();
   userDto.setName(user.getName());
   userDto.setAge(user.getAge());
   userDto.setFlag(flag);
   userDto.setMeaning(meaning);
   return userDto;
}

打印结果:

状态为:HTTP/1.1 200 
响应内容长度为:-1
响应内容为:{"name":"刘桑","age":20,"flag":4,"meaning":"这是什么鬼?"}