当前位置:首页 > 技术 > 正文内容

Java 发送 HTTP 请求的七种实现方案深度对比

访客 技术 2026年9月19日 11

在 Java 后端开发领域,HTTP 接口调用是构建分布式系统的基础能力。本文系统性地梳理了七种主流的 HTTP 客户端实现方案,从使用场景、配置方式到性能特点进行全方位解析,并提供可直接复用的代码模板。

一、RestTemplate:Spring 经典同步客户端

RestTemplate 是 Spring Framework 早期版本提供的 HTTP 客户端模板类,虽然在 Spring 5 之后被标记为废弃,但在存量项目中仍有广泛使用。其设计理念是简化 HTTP 通信流程,提供统一的模板化操作接口。

import org.springframework.web.client.RestTemplate;
import org.springframework.http.*;
import com.fasterxml.jackson.databind.ObjectMapper;

public class RestTemplateDemo {

    private static final RestTemplate restTemplate = new RestTemplate();
    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws Exception {
        String endpoint = "https://api.example.com/v1/upload";
        
        // 构建请求头信息
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.set("X-Access-Token", "demo-token-12345");
        httpHeaders.set("X-Request-Id", "req-" + System.currentTimeMillis());
        
        // 构建请求载荷
        UploadRequest payload = new UploadRequest();
        payload.setFileName("document.pdf");
        payload.setFileSize(1024000);
        payload.setFileType("PDF");
        payload.setOwner("user-001");
        
        String jsonBody = objectMapper.writeValueAsString(payload);
        
        HttpEntity<String> requestEntity = new HttpEntity<>(jsonBody, httpHeaders);
        
        // 发送 POST 请求
        ResponseEntity<String> responseEntity = restTemplate.exchange(
            endpoint,
            HttpMethod.POST,
            requestEntity,
            String.class
        );
        
        System.out.println("状态码: " + responseEntity.getStatusCode());
        System.out.println("响应体: " + responseEntity.getBody());
    }
    
    static class UploadRequest {
        private String fileName;
        private long fileSize;
        private String fileType;
        private String owner;
        
        public String getFileName() { return fileName; }
        public void setFileName(String fileName) { this.fileName = fileName; }
        public long getFileSize() { return fileSize; }
        public void setFileSize(long fileSize) { this.fileSize = fileSize; }
        public String getFileType() { return fileType; }
        public void setFileType(String fileType) { this.fileType = fileType; }
        public String getOwner() { return owner; }
        public void setOwner(String owner) { this.owner = owner; }
    }
}

适用场景:快速原型开发、小型内部系统、与 Spring Boot 1.x 版本兼容的项目。 优势:API 简洁直观,Spring 生态集成度高。 局限:已停止维护,不支持响应式编程模型。

二、WebClient:响应式 HTTP 客户端

WebClient 是 Spring WebFlux 模块提供的非阻塞式 HTTP 客户端,完全兼容响应式流规范。在高并发场景下,它能够以更少的线程处理更多请求,显著提升系统吞吐量。

import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

public class WebClientDemo {

    public static void main(String[] args) {
        WebClient webClient = WebClient.builder()
            .baseUrl("https://api.example.com")
            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .defaultHeader("X-Access-Token", "demo-token-12345")
            .defaultHeader("X-Client-Version", "2.0")
            .build();
        
        String requestBody = """
            {
                "action": "batch-upload",
                "files": [
                    {"name": "report.xlsx", "size": 2048000},
                    {"name": "image.png", "size": 512000}
                ],
                "timestamp": %d
            }
            """.formatted(System.currentTimeMillis());
        
        // 异步非阻塞调用
        Mono<String> responseMono = webClient.post()
            .uri("/v1/batch-process")
            .bodyValue(requestBody)
            .retrieve()
            .bodyToMono(String.class);
        
        // 阻塞等待结果(生产环境建议使用响应式链)
        String result = responseMono.block();
        System.out.println("处理结果: " + result);
    }
}

适用场景:高并发微服务架构、响应式系统集成、流式数据处理。 优势:支持同步/异步双模式,原生集成响应式编程。 局限:学习曲线陡峭,调试难度较高。

三、OkHttp:高性能网络库

OkHttp 由 Square 公司开源,是 Android 平台最流行的 HTTP 客户端。其内部实现了连接池、HTTP/2 协议支持、自动重试等高级特性,性能表现在业界领先。

import okhttp3.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class OkHttpDemo {

    private static final OkHttpClient httpClient = new OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
        .retryOnConnectionFailure(true)
        .build();

    public static void main(String[] args) throws IOException {
        String apiEndpoint = "https://api.example.com/v1/data/sync";
        
        String jsonPayload = """
            {
                "operation": "sync",
                "dataset": "customer_records",
                "records": [
                    {"id": "C001", "name": "张三", "status": "active"},
                    {"id": "C002", "name": "李四", "status": "inactive"}
                ]
            }
            """;
        
        RequestBody body = RequestBody.create(
            jsonPayload,
            MediaType.parse("application/json; charset=utf-8")
        );
        
        Request request = new Request.Builder()
            .url(apiEndpoint)
            .post(body)
            .addHeader("Authorization", "Bearer eyJhbGciOiJIUzI1NiJ9...")
            .addHeader("X-Trace-Id", "trace-" + System.nanoTime())
            .build();
        
        try (Response response = httpClient.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println("同步成功: " + response.body().string());
            } else {
                System.err.println("请求失败,状态码: " + response.code());
            }
        }
    }
}

适用场景:对性能要求严苛的移动端和服务端应用、需要 HTTP/2 多路复用的场景。 优势:连接复用效率高,支持异步回调和协程。 局限:仅支持 HTTP 协议,扩展性有限。

四、Apache HttpClient:企业级 HTTP 解决方案

Apache HttpClient 是 Apache Jakarta 项目的一部分,提供功能完备的 HTTP 客户端实现。该库支持复杂的认证机制、代理配置、连接管理等企业级特性,适合构建大型分布式系统。

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class ApacheHttpClientDemo {

    public static void main(String[] args) throws Exception {
        CloseableHttpClient client = HttpClients.custom()
            .setMaxTotalConnection(100)
            .setDefaultMaxPerRoute(20)
            .build();
        
        String targetUrl = "https://api.example.com/v1/process";
        HttpPost postRequest = new HttpPost(targetUrl);
        
        // 配置请求头
        postRequest.setHeader("Content-Type", "application/json");
        postRequest.setHeader("X-Api-Key", "ak-demo-20240101");
        postRequest.setHeader("X-Correlation-Id", "corr-" + System.currentTimeMillis());
        
        // 设置请求实体
        String requestBody = """
            {
                "task": "data-transformation",
                "source": "raw-data-lake",
                "destination": "warehouse",
                "config": {
                    "parallelism": 4,
                    "retryCount": 3
                }
            }
            """;
        postRequest.setEntity(new StringEntity(requestBody, "UTF-8"));
        
        // 执行请求
        try (CloseableHttpResponse response = client.execute(postRequest)) {
            int statusCode = response.getStatusLine().getStatusCode();
            String responseBody = EntityUtils.toString(response.getEntity());
            
            System.out.println("HTTP 状态: " + statusCode);
            System.out.println("响应内容: " + responseBody);
        } finally {
            client.close();
        }
    }
}

适用场景:企业级后台系统、需要代理认证或多线程并发控制的场景。 优势:功能全面,稳定可靠,支持连接池管理。 局限:API 较为笨重,配置项繁多。

五、Retrofit:声明式 REST 客户端

Retrofit 是基于 OkHttp 封装的类型安全 REST 客户端,通过注解方式定义接口,将 HTTP 调用转化为 Java 接口方法。它的设计哲学是"约定优于配置",大幅简化了 REST API 调用代码。

import retrofit2.*;
import retrofit2.converter.gson.GsonConverterFactory;
import com.google.gson.Gson;

// 定义 API 接口
interface DataService {
    
    @POST("/v1/collections")
    @Headers({
        "Content-Type: application/json",
        "Accept: application/json"
    })
    Call<ApiResponse> createCollection(@Body CollectionRequest request);
}

// 请求数据模型
class CollectionRequest {
    private String name;
    private String description;
    private List<String> tags;
    
    public CollectionRequest(String name, String description, List<String> tags) {
        this.name = name;
        this.description = description;
        this.tags = tags;
    }
}

// 响应数据模型
class ApiResponse {
    private int code;
    private String message;
    private String dataId;
    
    public int getCode() { return code; }
    public String getMessage() { return message; }
    public String getDataId() { return dataId; }
}

public class RetrofitDemo {

    public static void main(String[] args) {
        Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .addConverterFactory(GsonConverterFactory.create(new Gson()))
            .build();
        
        DataService service = retrofit.create(DataService.class);
        
        CollectionRequest request = new CollectionRequest(
            "用户数据集",
            "包含用户行为数据的集合",
            Arrays.asList("analytics", "user-behavior", "q1-2024")
        );
        
        Call<ApiResponse> call = service.createCollection(request);
        
        try {
            Response<ApiResponse> response = call.execute();
            if (response.isSuccessful() && response.body() != null) {
                ApiResponse result = response.body();
                System.out.println("创建成功,数据ID: " + result.getDataId());
            }
        } catch (Exception e) {
            System.err.println("调用异常: " + e.getMessage());
        }
    }
}

适用场景:快速调用第三方 REST API、团队协作的 API 封装层、微服务消费者端。 优势:代码简洁,类型安全,自动序列化/反序列化。 局限:仅支持 HTTP 协议,不适合非 REST 风格接口。

六、HttpURLConnection:JDK 原生方案

HttpURLConnection 是 Java 标准库提供的 HTTP 协议实现类,位于 java.net 包中。由于不需要引入外部依赖,它适合对依赖有严格限制的轻量级应用或嵌入式场景。

import java.net.*;
import java.io.*;

public class HttpUrlConnectionDemo {

    public static void main(String[] args) throws Exception {
        URL urlObj = new URL("https://api.example.com/v1/query");
        HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection();
        
        // 配置连接参数
        connection.setRequestMethod("POST");
        connection.setConnectTimeout(15000);
        connection.setReadTimeout(15000);
        connection.setDoOutput(true);
        connection.setDoInput(true);
        
        // 设置请求头
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setRequestProperty("User-Agent", "Java-HttpClient/1.0");
        
        // 写入请求数据
        String postData = """
            {
                "query": "SELECT * FROM users WHERE status = 'active'",
                "limit": 100,
                "offset": 0
            }
            """;
        
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = postData.getBytes("UTF-8");
            os.write(input, 0, input.length);
        }
        
        // 读取响应
        int responseCode = connection.getResponseCode();
        System.out.println("响应码: " + responseCode);
        
        if (responseCode == HttpURLConnection.HTTP_OK) {
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line).append("\n");
                }
                System.out.println("响应内容:\n" + response);
            }
        }
        
        connection.disconnect();
    }
}

适用场景:无外部依赖约束的简单工具、对包体积敏感的场景、Java 基础学习。 优势:零依赖,JDK 内置,部署简单。 局限:API 设计陈旧,连接管理效率低。

七、OpenFeign:Spring Cloud 声明式客户端

OpenFeign 是 Spring Cloud 生态中的服务调用组件,采用声明式接口方式实现服务间通信。它基于 Retrofit 的设计理念,但与 Spring Cloud 生态深度集成,支持负载均衡、熔断降级等微服务特性。

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

// 定义 Feign 客户端接口
@FeignClient(name = "data-service", url = "https://api.example.com")
interface DataFeignClient {
    
    @PostMapping("/v1/entities")
    EntityResponse createEntity(
        @RequestHeader("X-Auth-Token") String token,
        @RequestHeader("X-Request-Id") String requestId,
        @RequestBody EntityRequest request
    );
    
    @GetMapping("/v1/entities/{id}")
    EntityResponse getEntity(
        @RequestHeader("X-Auth-Token") String token,
        @PathVariable("id") String id
    );
}

// 请求/响应模型
class EntityRequest {
    private String entityName;
    private Map<String, Object> attributes;
    
    public EntityRequest(String entityName, Map<String, Object> attributes) {
        this.entityName = entityName;
        this.attributes = attributes;
    }
}

class EntityResponse {
    private String id;
    private String status;
    private long createdAt;
    
    public String getId() { return id; }
    public String getStatus() { return status; }
    public long getCreatedAt() { return createdAt; }
}

// 业务服务层
@Service
class BusinessService {
    
    @Autowired
    private DataFeignClient feignClient;
    
    public void processEntity() {
        String authToken = "Bearer eyJhbGciOiJIUzI1NiJ9...";
        String requestId = "req-" + System.currentTimeMillis();
        
        Map<String, Object> attrs = new HashMap<>();
        attrs.put("category", "premium");
        attrs.put("tier", 3);
        
        EntityRequest request = new EntityRequest("Customer", attrs);
        
        EntityResponse response = feignClient.createEntity(authToken, requestId, request);
        System.out.println("创建实体成功, ID: " + response.getId() + ", 状态: " + response.getStatus());
    }
}

适用场景:Spring Cloud 微服务架构、服务间调用的抽象层、需要集成服务治理能力的项目。 优势:声明式编程,与 Spring Cloud 无缝集成,支持负载均衡。 局限:强依赖 Spring Cloud 生态,不适合非 Spring 技术栈。

技术选型建议

技术方案 推荐场景 关键优势 主要不足
RestTemplate 遗留系统维护 学习成本低 已废弃,不建议新项目
WebClient 响应式架构 非阻塞高吞吐 调试困难
OkHttp 性能敏感场景 轻量高效 功能相对基础
Apache HttpClient 企业级应用 功能完备 API 笨重
Retrofit REST API 调用 简洁类型安全 协议限制
HttpURLConnection 极简工具 零依赖 功能有限
OpenFeign 微服务调用 声明式服务发现 依赖 Spring Cloud

技术选型应综合考虑项目规模、性能要求、团队技术栈以及长期维护成本等因素。对于新启动的 Spring Boot 3.x 项目,推荐优先选择 WebClient;对于传统项目升级,可保留 RestTemplate 逐步迁移至 WebClient。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。