0

0

如何在Java中发送HTTP请求 Java实现HTTP通信的方法

蓮花仙者

蓮花仙者

发布时间:2025-07-19 19:01:01

|

613人浏览过

|

来源于php中文网

原创

java中发送http请求的主流方式有四种,分别是:1. 使用 java.net.httpurlconnection(适用于简单请求或无法引入第三方库的项目);2. 使用 java 11 引入的 java.net.http.httpclient(推荐用于java 11及以上版本,支持http/2和异步请求);3. 使用 apache httpclient(功能强大,适合复杂企业级场景);4. 使用 okhttp(高效简洁,适合android或微服务项目)。每种方式各有优劣,选择取决于项目需求、java版本及开发偏好。

如何在Java中发送HTTP请求 Java实现HTTP通信的方法

在Java中发送HTTP请求,核心在于选择合适的API或库来构建、发送请求并处理响应。这并不是一个单一的“最佳”方案,更多的是根据项目需求、Java版本以及个人偏好来权衡。你可以使用Java自带的HttpURLConnection(虽然有点老旧但依然可用),Java 11引入的HttpClient(现代且功能强大),或者Apache HttpClient、OkHttp这类业界广泛使用的第三方库。选择哪种,往往决定了你代码的简洁性、可维护性和功能丰富度。

如何在Java中发送HTTP请求 Java实现HTTP通信的方法

解决方案

要在Java中实现HTTP通信,我通常会根据项目所用的Java版本和对功能复杂度的需求来决定。

1. 使用 java.net.HttpURLConnection (Java SE 1.1 及更高版本)

立即学习Java免费学习笔记(深入)”;

如何在Java中发送HTTP请求 Java实现HTTP通信的方法

这是Java内置的API,无需额外依赖。它功能完备,但用起来确实有点啰嗦,尤其是在处理复杂的请求头、参数或响应体时。我个人觉得,如果只是发个简单的GET请求,或者项目环境限制不能引入第三方库,它还能勉强用用。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpUrlConnectionExample {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://jsonplaceholder.typicode.com/posts/1");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000); // 5秒连接超时
            connection.setReadTimeout(5000);    // 5秒读取超时

            int responseCode = connection.getResponseCode();
            System.out.println("GET Response Code :: " + responseCode);

            if (responseCode == HttpURLConnection.HTTP_OK) { // success
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
                System.out.println(response.toString());
            } else {
                System.out.println("GET request not worked");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2. 使用 java.net.http.HttpClient (Java 11 及更高版本)

如何在Java中发送HTTP请求 Java实现HTTP通信的方法

Java 11引入的HttpClient是现代Java HTTP客户端的首选。它支持HTTP/2、WebSocket,并且提供了同步和异步两种API。用起来比HttpURLConnection舒服太多了,链式调用让代码可读性大大提升。如果你的项目能用Java 11及以上版本,我强烈推荐这个。

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class JavaHttpClientExample {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_2)
                .followRedirects(HttpClient.Redirect.NORMAL)
                .connectTimeout(Duration.ofSeconds(5))
                .build();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
                .GET() // 默认就是GET,也可以不写
                .build();

        try {
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            System.out.println("Status Code: " + response.statusCode());
            System.out.println("Response Body: " + response.body());

            // 异步请求示例
            client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                  .thenApply(HttpResponse::body)
                  .thenAccept(body -> System.out.println("Async Body: " + body))
                  .join(); // 等待异步完成,实际应用中通常不阻塞
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3. 使用 Apache HttpClient (第三方库)

Apache HttpClient是Java世界里非常成熟且功能强大的HTTP客户端库,它提供了丰富的特性,比如连接池、认证、代理、重试机制等。对于需要处理复杂HTTP场景的企业级应用来说,它依然是一个非常可靠的选择。需要引入Maven或Gradle依赖。

<!-- Maven -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version>
</dependency>
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class ApacheHttpClientExample {
    public static void main(String[] args) {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet request = new HttpGet("https://jsonplaceholder.typicode.com/posts/1");

            // 可以添加请求头
            request.addHeader("User-Agent", "Apache HttpClient Demo");

            try (CloseableHttpResponse response = httpClient.execute(request)) {
                System.out.println("Status Code: " + response.getStatusLine().getStatusCode());
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    System.out.println("Response Body: " + EntityUtils.toString(entity));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4. 使用 OkHttp (第三方库)

OkHttp是Square公司开源的一个高效HTTP客户端,在Android开发中尤为流行,但在后端服务中也常被使用。它支持HTTP/2、连接池、响应缓存等,API设计非常简洁流畅。

<!-- Maven -->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.9.3</version>
</dependency>
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;

public class OkHttpExample {
    public static void main(String[] args) {
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts/1")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            System.out.println("Status Code: " + response.code());
            System.out.println("Response Body: " + response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Java中HTTP请求的几种主流实现方式有哪些?

谈到Java里发HTTP请求,选择确实不少,各有各的特点和适用场景。我个人在不同的项目里都用过,也踩过一些坑,所以对它们的优劣多少有些体会。

首先是 java.net.HttpURLConnection。这玩意儿是Java标准库自带的,你不需要引入任何第三方依赖就能用。它的好处是“开箱即用”,对于一些简单的GET或POST请求,比如请求一个静态资源或者提交一个简单的表单,它完全够用。但它的API设计确实比较老旧,用起来很“命令式”,代码会显得比较冗长,尤其是在你需要设置很多请求头、处理重定向、或者管理连接池的时候,你会发现它力不从心,写起来很费劲。在我看来,它更适合那些对依赖有严格限制的老项目,或者只是想快速验证一个HTTP请求的场景。

接着是 java.net.http.HttpClient,这是Java 11之后的新宠。我得说,Sun/Oracle终于在这方面做了些现代化改进。它的API设计非常符合现代编程习惯,支持链式调用,而且原生支持HTTP/2和WebSocket,这是很大的优势。它既能同步阻塞地发请求,也能异步非阻塞地发,这对于构建响应式服务非常有用。如果你正在开发基于Java 11或更高版本的新项目,或者有机会升级现有项目的Java版本,我强烈建议优先考虑它。它自带连接池管理,性能也相当不错,而且不用引入第三方依赖,很“干净”。

然后是 Apache HttpClient。这几乎是Java企业级应用中HTTP客户端的“老牌劲旅”了。在HttpClient出现之前,Apache HttpClient几乎是处理复杂HTTP请求的不二之选。它提供了非常丰富的功能,比如强大的连接池管理、多种认证机制、代理支持、请求重试策略等等。如果你需要对HTTP请求有非常精细的控制,或者你的应用场景非常复杂(比如需要处理大量的并发请求、复杂的认证流程),那么Apache HttpClient依然是一个非常稳健的选择。虽然它需要引入外部依赖,API也相对Java 11的HttpClient略显复杂,但它的稳定性和功能丰富度是经过时间考验的。

Android配合WebService访问远程数据库 中文WORD版
Android配合WebService访问远程数据库 中文WORD版

采用HttpClient向服务器端action请求数据,当然调用服务器端方法获取数据并不止这一种。WebService也可以为我们提供所需数据,那么什么是webService呢?,它是一种基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合到一起。 实现Android与服务器端数据交互,我们在PC机器java客户端中,需要一些库,比如XFire,Axis2,CXF等等来支持访问WebService,但是这些库并不适合我们资源有限的android手机客户端,

下载

最后是 OkHttp。这个库在Android开发社区里非常流行,但它在后端服务中也越来越受欢迎。OkHttp的设计理念是高效和简洁。它默认支持HTTP/2,有非常优秀的连接池管理,并且提供了拦截器(Interceptor)机制,这让你可以非常方便地对请求和响应进行修改、日志记录、认证添加等操作。它的API非常简洁直观,用起来很舒服。如果你的项目追求性能、简洁的API设计,并且乐于引入一个高质量的第三方库,OkHttp是一个非常棒的选择。我个人在一些微服务项目里,因为它的简洁和高效,也倾向于使用它。

总结一下,如果你的项目是Java 11+,并且对依赖有洁癖,java.net.http.HttpClient是首选。如果需要处理非常复杂的企业级HTTP场景,或者项目Java版本较低,Apache HttpClient依然是可靠的伙伴。而如果追求简洁高效,尤其是在Android或某些微服务场景,OkHttp会让你爱不释手。

处理HTTP响应时常见的坑与解决方案?

在实际开发中,处理HTTP响应远不是拿到字符串那么简单。我踩过不少坑,也总结了一些经验,这里分享几个常见的“雷区”和我的处理方式。

一个最常见的坑是 超时问题。网络请求不是总能立刻得到响应的,如果服务器响应慢或者网络不稳定,你的程序可能会一直等下去,导致线程阻塞,甚至整个服务崩溃。我常遇到的是连接超时(Connect Timeout)和读取超时(Read Timeout)。连接超时是指客户端尝试与服务器建立连接的时间限制,如果超过这个时间还没连上,就放弃。读取超时是指连接建立后,客户端等待服务器发送数据的时间限制,如果数据传输中断或太慢,也会超时。

  • 解决方案: 务必设置合理的超时时间。
    • HttpURLConnection: connection.setConnectTimeout(milliseconds)connection.setReadTimeout(milliseconds)
    • HttpClient (Java 11+): HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5))HttpRequest.newBuilder().timeout(Duration.ofSeconds(10))。注意,HttpRequest上的timeout是整个请求的超时,包括连接和读取。
    • Apache HttpClient: 可以通过 RequestConfig 来设置,比如 RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(10000).build()
    • OkHttp: OkHttpClient.newBuilder().connectTimeout(5, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).build()

第二个大坑是 错误处理和HTTP状态码。很多人拿到响应后,只看有没有数据,不关心状态码。但HTTP状态码(2xx、3xx、4xx、5xx)是服务器告诉你的“语言”,它说明了请求的成功与否,以及失败的原因。比如404是资源未找到,500是服务器内部错误。不处理这些,你的程序可能会在不应该继续执行的时候继续,导致逻辑错误。

  • 解决方案: 总是检查响应状态码。
    • 对于2xx(成功),继续处理响应体。
    • 对于4xx(客户端错误)或5xx(服务器错误),应该抛出自定义异常或记录日志,并根据业务逻辑决定如何回滚或重试。我通常会封装一个方法,如果状态码不是2xx,就抛出 HttpClientErrorExceptionHttpServerErrorException 这样的异常。

第三个是 编码问题。HTTP响应体可能是UTF-8、GBK或者其他编码。如果你的程序没有正确地以服务器声明的编码去读取响应流,就会出现乱码。这在处理中文内容时尤其常见。

  • 解决方案: 优先使用响应头中Content-Type字段声明的编码。如果没有明确声明,或者声明不一致,UTF-8通常是安全的默认选择。
    • HttpURLConnection: new InputStreamReader(connection.getInputStream(), "UTF-8")
    • HttpClient (Java 11+): HttpResponse.BodyHandlers.ofString(Charset.forName("UTF-8"))
    • Apache HttpClient: EntityUtils.toString(entity, "UTF-8")
    • OkHttp: response.body().string() 默认会尝试从响应头中解析编码,如果没有则使用UTF-8。

第四个是 资源泄露。当你打开一个输入流(InputStream)或输出流(OutputStream),或者一个HttpURLConnectionCloseableHttpClient时,用完了一定要关闭它们。否则,连接资源会一直占用,导致系统资源耗尽,最终程序崩溃。

  • 解决方案: 使用 try-with-resources 语句。这是Java 7之后引入的语法糖,可以确保实现了 AutoCloseable 接口的资源在 try 块结束后自动关闭,即使发生异常也一样。
    • 所有现代HTTP客户端库(如Java 11 HttpClient、Apache CloseableHttpClient、OkHttp Response)都推荐或要求使用 try-with-resources 来管理它们的资源。
// 以Apache HttpClient为例,展示try-with-resources
try (CloseableHttpClient httpClient = HttpClients.createDefault();
     CloseableHttpResponse response = httpClient.execute(request)) {
    // 处理响应
    System.out.println("Status Code: " + response.getStatusLine().getStatusCode());
    HttpEntity entity = response.getEntity();
    if (entity != null) {
        System.out.println("Response Body: " + EntityUtils.toString(entity));
    }
} catch (IOException e) {
    e.printStackTrace();
}

这些坑,说起来简单,但实际写代码时一不留神就可能掉进去。养成良好的编程习惯,比如总是设置超时、检查状态码、正确处理编码和关闭资源,能省去你调试时的大量麻烦。

如何在HTTP请求中加入认证、头部信息或处理重定向?

在构建HTTP请求时,很多时候你需要更精细的控制,比如添加自定义头部、进行身份认证,或者处理服务器的重定向。这都是HTTP通信中非常常见的需求。

1. 添加头部信息 (Headers)

HTTP头部是客户端和服务器之间传递元数据的方式。比如User-Agent(标识客户端类型)、Content-Type(请求体类型)、Accept(期望的响应类型)、Authorization(认证凭证)等等。

  • HttpURLConnection: 相对繁琐,需要调用 connection.setRequestProperty("Header-Name", "Header-Value")
    connection.setRequestProperty("User-Agent", "MyJavaApp/1.0");
    connection.setRequestProperty("Content-Type", "application/json");
  • HttpClient (Java 11+): 链式调用非常方便。
    HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://example.com/api/data"))
            .header("User-Agent", "MyJavaHttpClient/1.0")
            .header("Content-Type", "application/json")
            .GET()
            .build();
  • Apache HttpClient: 同样直观。
    HttpGet request = new HttpGet("https://example.com/api/data");
    request.addHeader("User-Agent", "MyApacheHttpClient/1.0");
    request.addHeader("Content-Type", "application/json");
  • OkHttp: Request.Builder提供了header()addHeader()方法。
    Request request = new Request.Builder()
            .url("https://example.com/api/data")
            .header("User-Agent", "MyOkHttp/1.0")
            .addHeader("Content-Type", "application/json") // addHeader可以添加多个同名header
            .build();

2. 加入认证 (Authentication)

常见的认证方式有Basic认证和Bearer Token认证。

  • Basic认证: 这种方式是将用户名和密码用冒号连接,然后进行Base64编码,作为Authorization头部的值。
    String auth = "username:password";
    String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
    // 在请求头中添加
    // .header("Authorization", "Basic " + encodedAuth)
  • Bearer Token认证: 这是OAuth 2.0等现代认证流程中常用的方式,将一个令牌(Token)放在Authorization头部,前面加上Bearer
    String token = "your_access_token_here";
    // 在请求头中添加
    // .header("Authorization", "Bearer " + token)

3. 处理重定向 (Redirects)

当服务器返回3xx状态码时,表示资源已移动或需要客户端重定向到另一个URL。大多数HTTP客户端默认会处理重定向,但有时你需要更精细的控制。

  • HttpURLConnection: 默认是跟随重定向的。你可以通过 connection.setInstanceFollowRedirects(false) 来禁用自动重定向,然后手动处理。
    connection.setInstanceFollowRedirects(false); // 禁用自动重定向
    // int responseCode = connection.getResponseCode();
    // if (responseCode == HttpURLConnection.HTTP_MOVED_TEMP || responseCode == HttpURLConnection.HTTP_MOVED_PERM) {
    //     String newUrl = connection.getHeaderField("Location");
    //     // 然后你就可以用newUrl再发一个请求
    // }
  • HttpClient (Java 11+): HttpClient.Builder提供了followRedirects()方法来控制重定向行为。
    • HttpClient.Redirect.NORMAL: 默认行为,跟随所有重定向。
    • HttpClient.Redirect.ALWAYS: 总是跟随重定向,包括POST到GET的重定向。
    • HttpClient.Redirect.NEVER: 从不跟随重定向。
      HttpClient client = HttpClient.newBuilder()
          .followRedirects(HttpClient.Redirect.NEVER) // 禁用自动重定向
          .build();
      // 如果响应是3xx,你可以从response.headers().firstValue("Location")获取新URL
  • Apache HttpClient: 默认是跟随重定向的。可以通过 RequestConfig 来配置。
    RequestConfig requestConfig

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Java Maven专题
Java Maven专题

本专题聚焦 Java 主流构建工具 Maven 的学习与应用,系统讲解项目结构、依赖管理、插件使用、生命周期与多模块项目配置。通过企业管理系统、Web 应用与微服务项目实战,帮助学员全面掌握 Maven 在 Java 项目构建与团队协作中的核心技能。

0

2025.09.15

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1010

2023.08.02

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6604

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

842

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1091

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

2101

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

220

2023.09.04

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

4

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.3万人学习

Go 教程
Go 教程

共32课时 | 6.1万人学习

MongoDB 教程
MongoDB 教程

共17课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号