杰瑞科技汇

Java request有哪些常用方法?

Java 发送 HTTP 请求的方式随着 Java 版本和生态的发展,经历了从繁琐到便捷的演变,主要可以分为以下几类:

Java request有哪些常用方法?-图1
(图片来源网络,侵删)
  1. JDK 内置原生方式:不依赖任何第三方库。
    • HttpURLConnection (Java 1.1+) - 传统、繁琐,但无需额外依赖。
    • HttpClient (Java 11+) - 现代、高效、功能强大,是 Java 官方推荐的方式。
  2. 第三方流行库:提供了更简洁、更强大的 API。
    • Apache HttpClient - 长期以来是事实上的标准,功能非常全面。
    • OkHttp - 在 Android 和 Java 后端都非常流行,以其高效和易用性著称。
    • Spring RestTemplate - Spring 生态中的经典工具,与 Spring 框架无缝集成。
    • Spring WebClient - Spring 5 引入的响应式、非阻塞式 HTTP 客户端,是 RestTemplate 的现代化替代品。

下面我们逐一介绍这些方法,并提供代码示例。


JDK 内置方式

a. HttpURLConnection (Java 1.1+)

这是最古老、最基础的方式,它非常繁琐,需要手动处理流、连接状态、编码等,不推荐在新项目中使用,但了解它有助于理解底层原理。

特点

  • 优点:无需任何外部依赖。
  • 缺点:API 陈旧,代码冗长,功能有限(如异步支持差)。

示例代码 (GET 请求)

Java request有哪些常用方法?-图2
(图片来源网络,侵删)
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) throws Exception {
        String urlString = "https://jsonplaceholder.typicode.com/posts/1";
        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 设置请求方法
        connection.setRequestMethod("GET");
        // 设置请求头
        connection.setRequestProperty("User-Agent", "MyJavaApp/1.0");
        // 获取响应码
        int responseCode = connection.getResponseCode();
        System.out.println("Response Code: " + responseCode);
        if (responseCode == HttpURLConnection.HTTP_OK) { // 200
            // 读取响应数据
            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 Body: " + response.toString());
        } else {
            System.out.println("GET request failed");
        }
    }
}

b. HttpClient (Java 11+)

这是 Java 11 引入的现代 HTTP 客户端,旨在取代老旧的 HttpURLConnection,它功能强大、API 设计现代、支持异步和非阻塞请求。

特点

  • 优点:现代、高效、功能全面(异步、WebSocket、HTTP/2)、官方推荐。
  • 缺点:需要 Java 11 或更高版本。

示例代码 (同步 GET 请求)

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 JavaHttpClientSyncExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_2) // 可选,优先使用 HTTP/2
                .connectTimeout(Duration.ofSeconds(10))
                .build();
        HttpRequest request = HttpRequest.newBuilder()
                .GET()
                .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
                .header("User-Agent", "MyJavaApp/1.0")
                .build();
        // 发送请求并获取响应 (同步方式)
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println("Status Code: " + response.statusCode());
        System.out.println("Response Body: " + response.body());
    }
}

示例代码 (异步 GET 请求)

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
public class JavaHttpClientAsyncExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
                .build();
        // 发送请求并获取响应 (异步方式)
        CompletableFuture<HttpResponse<String>> futureResponse = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
        // 使用 thenAccept 处理响应结果
        futureResponse.thenAccept(response -> {
            System.out.println("Status Code: " + response.statusCode());
            System.out.println("Response Body: " + response.body());
        });
        // 主线程需要等待,否则程序会立即退出
        System.out.println("Request sent, waiting for response...");
        futureResponse.join(); // 阻塞直到异步任务完成
    }
}

第三方流行库

a. Apache HttpClient

曾长期是 Java HTTP 客户端的王者,功能极其强大和稳定,在企业级应用中广泛使用。

Maven 依赖:

<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3.1</version> <!-- 请使用最新版本 -->
</dependency>

示例代码:

import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.io.entity.EntityUtils;
public class ApacheHttpClientExample {
    public static void main(String[] args) throws Exception {
        // 创建 HttpClient 实例
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 创建 HTTP GET 请求
            HttpGet request = new HttpGet("https://jsonplaceholder.typicode.com/posts/1");
            // 发送请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(request)) {
                // 打印响应状态码
                System.out.println("Status Code: " + response.getCode());
                // 获取响应实体并转换为字符串
                String responseBody = EntityUtils.toString(response.getEntity());
                System.out.println("Response Body: " + responseBody);
            }
        }
    }
}

b. OkHttp

由 Square 公司开发,以其高效、简洁的 API 而闻名,是 Android 开发和许多 Java 项目的首选。

Maven 依赖:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.12.0</version> <!-- 请使用最新版本 -->
</dependency>

示例代码:

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class OkHttpExample {
    public static void main(String[] args) throws IOException {
        // 创建 OkHttpClient 实例
        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());
        }
    }
}

c. Spring RestTemplate (Spring Framework)

如果你在使用 Spring 框架,RestTemplate 是进行同步 HTTP 调用的传统工具,它非常方便,能与 Spring 的其他特性(如 JSON 自动转换、错误处理)无缝集成。

Maven 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

注意:spring-boot-starter-web 会自动包含 RestTemplate 的依赖。

示例代码:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class RestTemplateApplication {
    public static void main(String[] args) {
        SpringApplication.run(RestTemplateApplication.class, args);
    }
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
// 另一个类中调用
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class MyApiService {
    @Autowired
    private RestTemplate restTemplate;
    public String getPost() {
        String url = "https://jsonplaceholder.typicode.com/posts/1";
        // 直接将响应映射为 Java 对象,非常方便
        Post post = restTemplate.getForObject(url, Post.class);
        System.out.println("Fetched Post: " + post);
        return post != null ? post.toString() : "null";
    }
}
// 假设的 Post 类
class Post {
    private int userId;
    private int id;
    private String title;
    private String body;
    // Getters and Setters
    @Override
    public String toString() {
        return "Post{" +
                "userId=" + userId +
                ", id=" + id +
                ", title='" + title + '\'' +
                ", body='" + body + '\'' +
                '}';
    }
}

d. Spring WebClient (Spring Framework 5+)

WebClient 是 Spring 5 引入的响应式、非阻塞式 HTTP 客户端,是 RestTemplate 的现代化替代品,它基于 Project Reactor,性能更高,特别适合高并发场景。

Maven 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

示例代码:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@SpringBootApplication
public class WebClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebClientApplication.class, args);
    }
    @Bean
    public WebClient webClient() {
        return WebClient.create();
    }
}
// 另一个类中调用
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Service
public class MyWebApiService {
    @Autowired
    private WebClient webClient;
    public Mono<Post> getPostAsync() {
        String url = "https://jsonplaceholder.typicode.com/posts/1";
        return webClient.get()
                .uri(url)
                .retrieve() // 发出请求并接收响应
                .bodyToMono(Post.class); // 将响应体解码为 Post 对象
    }
    public void callGetPost() {
        getPostAsync()
                .subscribe(post -> { // 订阅 Mono,处理结果
                    System.out.println("Fetched Post (Async): " + post);
                });
        System.out.println("Request sent, but not necessarily received yet.");
        // 主线程不能立即退出,否则异步任务可能无法完成
        // 在实际应用中,通常是一个持续运行的服务器
        try {
            Thread.sleep(2000); // 简单等待
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
// Post 类同上

总结与选择建议

方法 优点 缺点 适用场景
HttpURLConnection 无需依赖 API陈旧,代码繁琐,功能弱 学习、极简单脚本、无法引入第三方库的环境
HttpClient (Java 11+) 现代、高效、功能全、官方推荐 需要 Java 11+ 新项目的首选,特别是非 Spring 项目
Apache HttpClient 功能强大、稳定、企业级成熟 依赖较大,API 相对较旧 需要高级特性或已在使用它的遗留项目
OkHttp API简洁、高效、流行 依赖第三方库 Android 应用、对性能和易用性要求高的 Java 项目
RestTemplate 与 Spring 生态集成完美,使用方便 已标记为不推荐 (deprecated in Spring 6.0) 旧版 Spring 项目,或必须使用同步阻塞方式的场景
WebClient 响应式、非阻塞、高性能 基于 Reactor,有学习曲线 新版 Spring 项目,特别是微服务、高并发场景

如何选择?

  • 新项目,不使用 Spring 框架:优先选择 HttpClient (Java 11+),它是官方的、现代的,无需额外依赖。
  • 新项目,使用 Spring Boot 3.x:优先选择 WebClient,它是未来的方向,性能更好。
  • 新项目,使用 Spring Boot 2.x:仍然可以使用 RestTemplate,但建议开始向 WebClient 迁移。RestTemplate 依然稳定可靠。
  • Android 开发OkHttp 是不二之选。
  • 维护遗留企业级项目:如果项目已经在用 Apache HttpClient,继续使用它是稳妥的选择。
  • 快速原型或学习HttpURLConnection 可以让你了解底层,但实际开发不推荐。RestTemplateOkHttp 能让你更快地实现功能。
分享:
扫描分享到社交APP
上一篇
下一篇