杰瑞科技汇

Java Socket如何调用接口?

下面我将从基础到高级,分步详细讲解如何使用 Java Socket 调用接口。

Java Socket如何调用接口?-图1
(图片来源网络,侵删)

核心概念

  1. Socket (套接字):是网络通信的端点,它就像是电话机,负责建立连接、发送和接收数据。
  2. IP 地址:网络中设备的唯一标识,就像是服务家的地址。
  3. 端口号:设备上运行的应用程序的标识,就像是房子的门牌号,确保数据被送到正确的服务。
  4. 协议:通信双方约定好的规则,HTTP (超文本传输协议),规定了请求和响应的格式。

第一部分:使用原始 Socket 调用 HTTP 接口

原始 Socket 需要我们自己手动构造符合 HTTP 协议的请求报文,并解析服务器返回的响应报文,这能帮助你深刻理解 Socket 和 HTTP 协议的工作原理。

假设我们要调用一个简单的 HTTP GET 接口:http://example.com/api/getInfo

客户端代码

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
public class RawHttpClient {
    public static void main(String[] args) {
        // 1. 定义服务器的地址和端口
        String host = "example.com"; // 或者 IP 地址,如 "127.0.0.1"
        int port = 80; // HTTP 默认端口是 80,HTTPS 是 443
        // 2. 创建 Socket 对象,尝试连接服务器
        // try-with-resources 语句可以自动关闭资源
        try (Socket socket = new Socket(host, port);
             // 3. 获取输出流,用于向服务器发送请求
             OutputStream out = socket.getOutputStream();
             // 4. 获取输入流,用于读取服务器返回的响应
             InputStream in = socket.getInputStream()) {
            // 5. 构造 HTTP 请求报文
            // 注意:请求行、请求头、空行、请求体(GET请求通常没有请求体)
            String httpRequest = "GET /api/getInfo HTTP/1.1\r\n" + // 请求行
                                "Host: " + host + "\r\n" +         // 请求头 (Host是必须的)
                                "User-Agent: SimpleJavaClient/1.0\r\n" + // 请求头
                                "Accept: */*\r\n" +               // 请求头
                                "Connection: close\r\n" +         // 请求头 (请求结束后关闭连接)
                                "\r\n";                           // 空行,表示请求头结束
            System.out.println("Sending HTTP request:\n" + httpRequest);
            // 6. 发送请求
            out.write(httpRequest.getBytes());
            out.flush(); // 确保数据被立即发送
            // 7. 读取并打印响应
            System.out.println("\nReading HTTP response:");
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line;
            // HTTP响应头和响应体之间也有一个空行
            boolean inBody = false;
            while ((line = reader.readLine()) != null) {
                if (line.isEmpty()) {
                    inBody = true; // 遇到空行,接下来是响应体
                    System.out.println(); // 打印空行
                    continue;
                }
                if (inBody) {
                    System.out.println(line); // 打印响应体(通常是JSON或HTML)
                } else {
                    System.out.println("Header: " + line); // 打印响应头
                }
            }
        } catch (UnknownHostException e) {
            System.err.println("Unknown host: " + host);
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("I/O error occurred while connecting to " + host);
            e.printStackTrace();
        }
    }
}

代码解析

  1. 创建 Socketnew Socket(host, port) 尝试与指定 IP 和端口建立 TCP 连接,这是一个阻塞操作,连接成功后才会继续往下执行。
  2. 获取流
    • OutputStream:用于向服务器写入数据,即发送 HTTP 请求。
    • InputStream:用于从服务器读取数据,即接收 HTTP 响应。
  3. 构造 HTTP 请求:HTTP 请求有严格的格式,一个简单的 GET 请求包括:
    • 请求行GET /api/getInfo HTTP/1.1
    • 请求头Host, User-Agent, Accept 等。Host 是必须的。
    • 空行:一个单独的 \r\n,表示请求头结束。
  4. 发送和接收:通过流对象进行数据的读写。
  5. 解析响应:HTTP 响应也分为响应头和响应体,中间由一个空行隔开,我们逐行读取,直到遇到空行,之后的内容就是服务器返回的数据(JSON 字符串)。

第二部分:使用 HttpURLConnection (更推荐的方式)

手动构造 HTTP 请求非常繁琐且容易出错,Java 标准库提供了 HttpURLConnection 类,它封装了底层的 Socket 操作,让我们能更方便地发送 HTTP 请求。

客户端代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class JdkHttpClient {
    public static void main(String[] args) {
        // 1. 定义接口的 URL
        String urlString = "http://example.com/api/getInfo";
        try {
            // 2. 创建 URL 对象
            URL url = new URL(urlString);
            // 3. 打开连接,获取 HttpURLConnection 实例
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            // 4. 设置请求方法 (GET, POST, PUT, DELETE 等)
            connection.setRequestMethod("GET");
            // 5. 设置请求头
            connection.setRequestProperty("User-Agent", "Java-HttpURLConnection/1.0");
            connection.setRequestProperty("Accept", "application/json"); // 告诉服务器我们期望接收JSON数据
            // 6. 获取响应码 (200表示成功,404表示未找到等)
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);
            if (responseCode == HttpURLConnection.HTTP_OK) { // 200
                // 7. 获取输入流,读取响应数据
                try (BufferedReader in = new BufferedReader(
                        new InputStreamReader(connection.getInputStream()))) {
                    String inputLine;
                    StringBuilder response = new StringBuilder();
                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    // 8. 打印响应结果 (通常是JSON字符串)
                    System.out.println("Response Body:");
                    System.out.println(response.toString());
                }
            } else {
                System.out.println("GET request failed. Response Code: " + responseCode);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代码解析

  • HttpURLConnection:它大大简化了工作,我们只需要设置 URL、请求方法、请求头,然后获取响应码和输入流即可。
  • 优点
    • 简单易用,无需关心底层的 Socket 和 HTTP 协议细节。
    • 是 Java 标准库的一部分,无需额外依赖。
    • 支持 GET、POST、PUT、DELETE 等多种方法。
  • 缺点
    • 功能相对有限,比如对连接池、异步请求的支持不够完善。
    • API 设计有些陈旧。

第三部分:使用第三方 HTTP 客户端库 (业界标准)

对于生产环境,我们更推荐使用功能强大、性能优越的第三方 HTTP 客户端库,目前最流行的是 OkHttpApache HttpClient

Java Socket如何调用接口?-图2
(图片来源网络,侵删)

使用 OkHttp (推荐)

OkHttp 是目前 Android 和 Java 开发中最主流的 HTTP 客户端,它支持同步和异步请求,有高效的连接池,使用起来非常简洁。

添加 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) {
        // 1. 创建 OkHttp 客户端 (推荐使用单例模式)
        OkHttpClient client = new OkHttpClient();
        // 2. 创建 Request 对象
        Request request = new Request.Builder()
                .url("http://example.com/api/getInfo")
                .get() // 显式指定 GET 请求 (默认)
                .addHeader("User-Agent", "OkHttp-Example/1.0")
                .addHeader("Accept", "application/json")
                .build();
        // 3. 发送请求并获取响应 (同步方式)
        try (Response response = client.newCall(request).execute()) {
            // 4. 判断是否成功
            if (response.isSuccessful()) {
                // 5. 获取响应体
                String responseBody = response.body().string();
                System.out.println("Response Code: " + response.code());
                System.out.println("Response Body:");
                System.out.println(responseBody);
            } else {
                System.out.println("Request failed: " + response.code());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

OkHttp 优点:

Java Socket如何调用接口?-图3
(图片来源网络,侵删)
  • API 简洁现代:Builder 模式非常直观。
  • 性能卓越:内置连接池,支持 HTTP/2,减少延迟。
  • 功能强大:支持异步请求、文件上传下载、WebSocket 等。
  • 自动处理重定向和重试

总结与对比

方案 优点 缺点 适用场景
原始 Socket 理解底层原理,控制力最强 代码复杂,易出错,需手动处理协议细节 学习网络编程,或需要实现自定义协议
HttpURLConnection 无需额外依赖,标准库支持 API 陈旧,功能有限,性能一般 简单的、非性能敏感的脚本或工具
OkHttp / HttpClient API 简洁,功能强大,性能优越,生态完善 需要引入第三方依赖 所有生产环境项目,强烈推荐

给你的建议

  1. 如果你是初学者:先尝试用 原始 Socket 调用一个简单的 HTTP 接口,这能让你明白 HTTP 请求和响应的完整结构。
  2. 如果你在做日常开发:直接使用 HttpURLConnection 就足够了,尤其是在不想引入额外依赖的情况下。
  3. 如果你在开发商业级、高性能的应用毫不犹豫地选择 OkHttp,它是目前业界的事实标准,能让你事半功倍,并避免很多坑。
分享:
扫描分享到社交APP
上一篇
下一篇