Java案例如何发送HTTP请求?从基础到实战的完整指南
目录导读
- 为什么Java开发者需要掌握HTTP请求?
- Java发送HTTP请求的四大主流方式
- 经典案例:用HttpURLConnection发送GET/POST请求
- 企业级实战:Apache HttpClient完整示例
- 现代化方案:OkHttp与Spring RestTemplate
- 常见问题与解决方案(Q&A)
- 性能优化与最佳实践
为什么Java开发者需要掌握HTTP请求?
在当今微服务架构和API经济时代,Java应用常常需要与其他系统交互——无论是调用第三方RESTful API、爬取网页数据,还是构建分布式服务的内部通信,掌握如何用Java发送HTTP请求已成为后端开发的基本功。

根据Stack Overflow 2023开发者调查,超过70%的Java项目涉及HTTP通信,但很多初学者仍停留在“使用浏览器”的思维模式,不知道在代码中如何发起网络请求。
核心场景包括:
- 调用微信支付、支付宝等第三方接口
- 对接企业内部微服务网关
- 实现数据采集(网页爬虫)
- 构建API测试工具
Java发送HTTP请求的四大主流方式
| 方法 | JDK版本要求 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
HttpURLConnection |
JDK 1.1+ | 零依赖,原生支持 | API较底层,代码繁琐 | 简单测试/JDK内置 |
Apache HttpClient |
JDK 1.5+ | 功能全面,支持连接池 | 需导入第三方JAR | 企业级生产环境 |
OkHttp |
JDK 1.7+ | 高效异步,语法简洁 | 需要引入依赖 | Android/高并发场景 |
Spring RestTemplate |
Spring 3+ | 模板化设计,集成方便 | 需Spring框架 | Spring项目首选 |
注意:Java 11后引入了
HttpClient(位于java.net.http包),可视为HttpURLConnection的替代方案。
经典案例:用HttpURLConnection发送GET/POST请求
GET请求示例(获取JSON数据):
public static String sendGet(String urlStr) throws Exception {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
// 读取响应
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
}
POST请求示例(发送JSON数据):
public static String sendPost(String urlStr, String jsonBody) throws Exception {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setDoOutput(true);
// 写入请求体
try (OutputStream os = conn.getOutputStream()) {
byte[] input = jsonBody.getBytes("utf-8");
os.write(input, 0, input.length);
}
// 读取响应
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line.trim());
}
return response.toString();
}
}
案例说明:以上代码展示了最基础的HTTP通信逻辑,适用于JDK自带环境,但需注意资源关闭和异常处理。
企业级实战:Apache HttpClient完整示例
Maven依赖:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
发送GET请求并处理Headers:
public static String doGetWithHeaders(String url) {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet request = new HttpGet(url);
request.addHeader("User-Agent", "Mozilla/5.0");
request.addHeader("Authorization", "Bearer your_token_here");
try (CloseableHttpResponse response = httpClient.execute(request)) {
HttpEntity entity = response.getEntity();
return EntityUtils.toString(entity, "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
POST请求带参数(表单提交):
public static String doPostForm(String url, Map<String, String> params) {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> nvps = new ArrayList<>();
for (Map.Entry<String, String> entry : params.entrySet()) {
nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
return EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (IOException e) {
throw new RuntimeException("POST请求失败", e);
}
}
企业级优势:
- 支持连接池管理(避免频繁创建/销毁连接)
- 自动处理cookie、重定向
- 丰富的拦截器机制
现代化方案:OkHttp与Spring RestTemplate
OkHttp案例(Kotlin/Java双友好)
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.url("https://api.example.com/data")
.post(RequestBody.create(
MediaType.parse("application/json"),
"{\"key\":\"value\"}"
))
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
Spring RestTemplate(需Spring Boot项目)
@Service
public class ApiService {
@Autowired
private RestTemplate restTemplate;
public String callExternalApi() {
// GET请求
String result = restTemplate.getForObject(
"https://api.github.com/users/{username}",
String.class,
"square"
);
// POST请求
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>("{\"name\":\"test\"}", headers);
ResponseEntity<String> response = restTemplate.exchange(
"https://httpbin.org/post",
HttpMethod.POST,
entity,
String.class
);
return response.getBody();
}
}
常见问题与解决方案(Q&A)
Q1:为什么我的POST请求返回400错误?
- 检查Content-Type是否匹配服务器期望格式
- 确认JSON格式是否合法(使用在线验证工具)
- 检查字符编码是否正确
Q2:如何处理HTTPS请求中的证书问题?
// 信任所有证书(仅限开发环境)
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
}
};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
Q3:如何设置超时时间?
- HttpURLConnection:
setConnectTimeout()/setReadTimeout() - HttpClient:
RequestConfig.custom().setConnectTimeout(5000) - OkHttp:
new OkHttpClient.Builder().connectTimeout(...)
Q4:发送请求时出现Connection refused怎么办?
- 确认目标地址IP和端口是否正确
- 检查网络连通性(telnet测试)
- 查看防火墙是否拦截请求
性能优化与最佳实践
-
使用连接池:避免每次请求都创建新连接,支持Keep-Alive
// HttpClient连接池配置 PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(200); cm.setDefaultMaxPerRoute(50);
-
合理设置超时:连接超时一般3-5秒,读取超时15-30秒
-
异步请求:OkHttp支持Call.enqueue()实现非阻塞调用
-
资源关闭:始终在finally块中关闭Response/InputStream
-
日志记录:使用SLF4J记录请求/响应详情,便于排错
-
重试机制:对幂等操作(GET/PUT)实现指数退避重试
延伸阅读:如果你需要处理大型文件上传,推荐使用Apache HttpClient的MultipartEntityBuilder;若用于微服务间调用,可考虑Spring Cloud OpenFeign。
本文通过从原生API到现代框架的完整对比,结合大量可运行代码片段,帮助你快速掌握Java HTTP请求开发的方方面面,无论你是初学者还是经验丰富的开发者,都能从中找到适合自己项目的实现方案。