深浅模式
HttpClient 介绍与作用
HttpClient 是 Apache 提供的一个功能完善的 HTTP 协议客户端编程工具包,能让 Java 程序主动发送 HTTP 请求、接收响应数据。
它的定位不是“服务器”,而是一个“客户端请求发起者”。

核心作用:让 Java 程序去访问其他 Web 服务,主动发起请求并处理返回结果。
为什么要用 Java 发送请求?
我们平时写的 Web 项目,大多是由 前端 → Java 服务端 发请求,然后返回响应。
但在很多业务场景下,Java 程序本身也需要 向外部第三方服务器发送请求,因为:
某些服务(如短信、支付、地图定位等)我们自己没有权限直接实现,只能通过官方平台提供的接口调用来实现功能。
比如:
- 地图定位功能 → 调用百度、高德开放 API
- 短信验证 → 调用运营商短信网关
- 微信登录、支付 → 调用微信开放平台接口
这时,Java 代码就必须扮演「客户端」的角色,构造 HTTP 请求、携带参数,去调用这些第三方接口。
示例:百度地图地理编码服务
百度地图提供了一个地理编码接口,根据地址换取经纬度:
https://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号&output=json&ak=已申请的访问密钥我们打开浏览器访问这条 URL,就能看到百度返回的 JSON 数据。

而如果想在 Java 程序中实现同样的效果,就要通过 HttpClient 来发送请求:
- 构造请求地址与参数
- 发送 HTTP 请求
- 接收并解析响应数据
使用方法
在 Java 项目中使用 HttpClient 时,很多第三方 SDK(例如阿里云、微信、百度等)都会自动引入它作为底层依赖。如果没有,也可以单独添加一份,方便自己直接发 HTTP 请求:
xml
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>我们平时在浏览器中访问网站,会经历:
- 构造 URL
- 发出请求
- 等待并接收响应
在 Java 中用 HttpClient 的流程完全类似:
- 创建 HttpClient 对象(相当于打开浏览器)
- 创建请求对象(决定要访问的接口与方式:GET 或 POST)
- 执行请求、获取响应
- 读取响应体内容
- 关闭连接释放资源
整体逻辑很像“浏览器自动化”,只是由 Java 代码来完成。
GET 请求示例
目标:通过 HttpClient 调用 /user/shop/status接口(GET),拿到营业状态。
java
public class HttpGetExample {
public static void main(String[] args) throws Exception {
// 1. 创建 HttpClient 对象(相当于打开浏览器)
CloseableHttpClient httpClient = HttpClients.createDefault();
// 2. 构造 GET 请求对象,指定要访问的接口地址
// `HttpGet` 表示这是一次 GET 请求;
HttpGet httpGet = new HttpGet("http://localhost:8080/user/shop/status");
// 3. 发送请求并获取响应
CloseableHttpResponse response = httpClient.execute(httpGet);
// 4. 解析响应内容
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println("接口响应内容:" + result);
// 5. 关闭连接
response.close();
httpClient.close();
}
}EntityUtils.toString() 将返回的响应数据转成字符串;最后记得关闭连接,避免资源泄露。
POST 请求示例
目标:通过 HttpClient 调用 管理端登录 /admin/employee/login(POST JSON),需要在请求体中带上账号和密码。
java
public class HttpPostExample {
public static void main(String[] args) throws Exception {
// 1. 创建 HttpClient 对象
CloseableHttpClient httpClient = HttpClients.createDefault();
// 2. 构造 POST 请求对象
HttpPost httpPost = new HttpPost("http://localhost:8080/admin/employee/login");
// 3. 设置请求体(JSON 格式)
String json = "{\"username\":\"admin\",\"password\":\"123456\"}";
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 4. 发送请求并获取响应
CloseableHttpResponse response = httpClient.execute(httpPost);
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println("接口响应内容:" + result);
// 5. 关闭连接
response.close();
httpClient.close();
}
}登录接口需要请求体,所以我们使用 StringEntity 携带 JSON 数据;ContentType.APPLICATION_JSON 告诉服务端我们发送的是 JSON 格式;最后读取响应内容即可。
封装 HttpClient 工具类
实际项目中如果多次需要发 HTTP 请求(调用第三方接口、微信 API、百度地图等),我们不可能每次都重新写一段 GET / POST。
这时可以封装一个工具类,统一请求逻辑、超时配置和异常处理。
HttpClient 使用步骤其实很固定:
- 创建 HttpClient 对象
- 创建请求(GET 或 POST)
- 设置请求参数或请求体
- 执行请求,获取响应对象
- 解析响应数据
- 关闭资源
我们把这些通用逻辑提炼出来,写成 HttpClientUtil,以后项目中直接调用即可。
java
/**
* Http 工具类 - 简化 GET / POST 请求
*/
public class HttpClientUtil {
// 统一超时时间(毫秒)
private static final int TIMEOUT = 5000;
/**
* 构造通用的请求配置(连接超时 / 读取超时)
*/
private static RequestConfig buildConfig() {
return RequestConfig.custom()
.setConnectTimeout(TIMEOUT)
.setSocketTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build();
}
/**
* GET 请求(带可选参数)
*/
public static String doGet(String url, Map<String, String> params) {
String result = "";
// 1. 创建 HttpClient
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
// 2. 拼接参数
URIBuilder builder = new URIBuilder(url);
if (params != null) {
for (String key : params.keySet()) {
builder.addParameter(key, params.get(key));
}
}
URI uri = builder.build();
// 3. 创建 GET 请求
HttpGet httpGet = new HttpGet(uri);
httpGet.setConfig(buildConfig());
// 4. 执行请求
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
// 判断状态码是否为200
if (response.getStatusLine().getStatusCode() == 200) {
result = EntityUtils.toString(response.getEntity(), "UTF-8");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* POST 请求(表单方式)
*/
public static String doPost(String url, Map<String, String> params) {
String result = "";
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(buildConfig());
// 1. 封装表单参数
if (params != null) {
List<NameValuePair> list = new ArrayList<>();
for (Map.Entry<String, String> entry : params.entrySet()) {
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8"));
}
// 2. 发送请求并读取结果
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
result = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* POST 请求(JSON 方式)
*/
public static String doPostJson(String url, Map<String, String> paramMap) {
String result = "";
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(buildConfig());
// 1. 构造 JSON 字符串
if (paramMap != null) {
JSONObject json = new JSONObject();
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
json.put(entry.getKey(), entry.getValue());
}
// 设置请求体与类型
StringEntity entity = new StringEntity(json.toString(), "UTF-8");
entity.setContentType("application/json;charset=UTF-8");
httpPost.setEntity(entity);
}
// 2. 发送请求
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
result = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}buildConfig()
设置了统一超时时间,避免网络延迟或无响应导致程序卡死。doGet()- 自动拼接参数(用
URIBuilder自动编码,防止中文乱码) - 适合调用无鉴权的公开接口,如百度地图查询等。
- 自动拼接参数(用
doPost()- 以表单形式提交(
application/x-www-form-urlencoded),常用于登录等接口。
- 以表单形式提交(
doPostJson()- 用 JSON 作为请求体(
application/json),是现代接口主流方式。
- 用 JSON 作为请求体(
资源释放
- 所有网络资源都在 try-with-resources 中自动关闭,避免内存泄露。
示例用法:
java
// GET 请求
Map<String, String> getParams = new HashMap<>();
getParams.put("address", "北京市海淀区上地十街10号");
getParams.put("output", "json");
getParams.put("ak", "你的百度AK");
String result1 = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3/", getParams);
System.out.println(result1);
// POST 请求
Map<String, String> loginParams = new HashMap<>();
loginParams.put("username", "admin");
loginParams.put("password", "123456");
String result2 = HttpClientUtil.doPostJson("http://localhost:8080/admin/employee/login", loginParams);
System.out.println(result2);
评论