杰瑞科技汇

Java如何调用RESTful接口?

一个简单的 RESTful API

为了演示,我们首先需要一个简单的 RESTful API,这里我们使用一个免费的公共 API:JSONPlaceholder,它是一个用于测试和原型设计的在线 REST API。

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

我们将调用它的 GET /posts/{id} 接口来获取一篇博客文章,以及 POST /posts 接口来创建一篇新文章。

  • 获取文章: GET https://jsonplaceholder.typicode.com/posts/1
  • 创建文章: POST https://jsonplaceholder.typicode.com/posts
    • 请求体 (JSON):
      {
        "title": "foo",
        "body": "bar",
        "userId": 1
      }

使用 HttpURLConnection (Java 内置,无需额外依赖)

这是 Java 标准库自带的、最基础的方式,它功能强大,但代码比较冗长,手动处理连接、流和异常。

特点

  • 优点: 无需任何第三方库,是 Java 标准的一部分。
  • 缺点: 代码繁琐,易出错,需要手动管理连接、输入输出流和资源释放。

示例代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpURLConnectionExample {
    public static void main(String[] args) {
        // 1. 调用 GET 请求
        String getResponse = sendGetRequest("https://jsonplaceholder.typicode.com/posts/1");
        System.out.println("--- GET 请求响应 ---");
        System.out.println(getResponse);
        // 2. 调用 POST 请求
        String postResponse = sendPostRequest("https://jsonplaceholder.typicode.com/posts");
        System.out.println("\n--- POST 请求响应 ---");
        System.out.println(postResponse);
    }
    // GET 请求方法
    private static String sendGetRequest(String urlString) {
        StringBuilder response = new StringBuilder();
        try {
            URL url = new URL(urlString);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Accept", "application/json");
            // 检查响应码
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                try (BufferedReader in = new BufferedReader(
                        new InputStreamReader(connection.getInputStream()))) {
                    String inputLine;
                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                }
            } else {
                return "GET request failed. Code: " + connection.getResponseCode();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response.toString();
    }
    // POST 请求方法
    private static String sendPostRequest(String urlString) {
        String jsonInputString = "{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}";
        StringBuilder response = new StringBuilder();
        try {
            URL url = new URL(urlString);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json; utf-8");
            connection.setRequestProperty("Accept", "application/json");
            connection.setDoOutput(true); // 允许输出
            // 写入请求体
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = jsonInputString.getBytes("utf-8");
                os.write(input, 0, input.length);
            }
            // 读取响应
            if (connection.getResponseCode() == HttpURLConnection.HTTP_CREATED) { // POST 成功通常是 201
                try (BufferedReader in = new BufferedReader(
                        new InputStreamReader(connection.getInputStream()))) {
                    String inputLine;
                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                }
            } else {
                return "POST request failed. Code: " + connection.getResponseCode();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response.toString();
    }
}

使用 Apache HttpClient (经典、功能强大)

Apache HttpClient 是一个久经考验的、功能非常丰富的 HTTP 客户端库,它比 HttpURLConnection 更易用,性能也更好。

特点

  • 优点: 功能全面,性能好,连接池管理,社区活跃。
  • 缺点: 需要添加第三方依赖。

依赖配置 (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.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;
import java.io.IOException;
public class ApacheHttpClientExample {
    public static void main(String[] args) {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 1. GET 请求
            HttpGet requestGet = new HttpGet("https://jsonplaceholder.typicode.com/posts/1");
            requestGet.addHeader("accept", "application/json");
            try (CloseableHttpResponse responseGet = httpClient.execute(requestGet)) {
                HttpEntity entityGet = responseGet.getEntity();
                if (entityGet != null) {
                    String resultGet = EntityUtils.toString(entityGet);
                    System.out.println("--- GET 请求响应 ---");
                    System.out.println(resultGet);
                }
            }
            // 2. POST 请求
            HttpPost requestPost = new HttpPost("https://jsonplaceholder.typicode.com/posts");
            String jsonInputString = "{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}";
            requestPost.addHeader("Content-Type", "application/json");
            requestPost.addHeader("Accept", "application/json");
            requestPost.setEntity(new StringEntity(jsonInputString));
            try (CloseableHttpResponse responsePost = httpClient.execute(requestPost)) {
                HttpEntity entityPost = responsePost.getEntity();
                if (entityPost != null) {
                    String resultPost = EntityUtils.toString(entityPost);
                    System.out.println("\n--- POST 请求响应 ---");
                    System.out.println(resultPost);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用 OkHttp (现代、高效、推荐)

OkHttp 是目前 Android 开发和 Java 后端中非常流行的 HTTP 客户端,它支持同步和异步请求,拥有出色的性能和简单的 API。

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

特点

  • 优点: API 简洁高效,支持异步请求,自动处理重试,现代网络库。
  • 缺点: 需要添加第三方依赖。

依赖配置 (Maven)

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.10.0</version> <!-- 使用较新的稳定版本 -->
</dependency>

示例代码

import okhttp3.*;
import java.io.IOException;
public class OkHttpExample {
    private static final OkHttpClient client = new OkHttpClient();
    public static void main(String[] args) {
        // 1. GET 请求
        String getResponse = sendGetRequest("https://jsonplaceholder.typicode.com/posts/1");
        System.out.println("--- GET 请求响应 ---");
        System.out.println(getResponse);
        // 2. POST 请求
        String postResponse = sendPostRequest("https://jsonplaceholder.typicode.com/posts");
        System.out.println("\n--- POST 请求响应 ---");
        System.out.println(postResponse);
    }
    // GET 请求方法
    private static String sendGetRequest(String url) {
        Request request = new Request.Builder()
                .url(url)
                .header("Accept", "application/json")
                .build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    // POST 请求方法
    private static String sendPostRequest(String url) {
        String jsonBody = "{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}";
        MediaType JSON = MediaType.get("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(jsonBody, JSON);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .header("Content-Type", "application/json")
                .header("Accept", "application/json")
                .build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

使用 Spring RestTemplate (Spring 生态首选)

如果你的项目是基于 Spring Boot 或 Spring 框架的,RestTemplate 是调用 RESTful API 的标准工具,它提供了模板化的方法,极大地简化了 HTTP 交互。

特点

  • 优点: 与 Spring 生态无缝集成,支持对象到 JSON/XML 的自动转换(Jackson/JAXB),代码非常简洁。
  • 缺点: 仅限 Spring 项目。

依赖配置 (Spring Boot 项目通常已包含)

如果你的 pom.xml 中有 spring-boot-starter-web 依赖,RestTemplate 已经包含了,如果没有,可以单独添加:

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

示例代码

创建一个与 JSON 结构对应的 Java 类(POJO)。

// Post.java
public class Post {
    private int userId;
    private int id;
    private String title;
    private String body;
    // Getters and Setters
    public int getUserId() { return userId; }
    public void setUserId(int userId) { this.userId = userId; }
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    public String getBody() { return body; }
    public void setBody(String body) { this.body = body; }
    @Override
    public String toString() {
        return "Post{" +
                "userId=" + userId +
                ", id=" + id +
                ", title='" + title + '\'' +
                ", body='" + body + '\'' +
                '}';
    }
}

在主程序或配置类中配置并使用 RestTemplate

Java如何调用RESTful接口?-图3
(图片来源网络,侵删)
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.util.UriComponentsBuilder;
@SpringBootApplication
public class RestTemplateApplication {
    public static void main(String[] args) {
        SpringApplication.run(RestTemplateApplication.class, args);
    }
    // 定义一个 RestTemplate Bean
    @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 PostService {
    @Autowired
    private RestTemplate restTemplate;
    // GET 请求
    public Post getPostById(int id) {
        String url = "https://jsonplaceholder.typicode.com/posts/{id}";
        // 使用 URI 变量,可以自动替换 {id}
        Post post = restTemplate.getForObject(url, Post.class, id);
        return post;
    }
    // POST 请求
    public Post createPost(Post newPost) {
        String url = "https://jsonplaceholder.typicode.com/posts";
        // restTemplate 会自动将 Post 对象序列化为 JSON
        Post createdPost = restTemplate.postForObject(url, newPost, Post.class);
        return createdPost;
    }
}

使用 Spring WebClient (响应式、现代 Spring 5+)

WebClient 是 Spring 5 引入的、基于响应式编程模型(如 Project Reactor)的 HTTP 客户端,它是 RestTemplate 的现代替代品,功能更强大,非阻塞,性能更高,特别适合微服务架构。

特点

  • 优点: 响应式、非阻塞、性能高、流式 API、链式调用。
  • 缺点: 学习曲线稍陡峭(需要了解响应式编程),仅限 Spring 5+ 项目。

示例代码

WebClient 是无状态的,每次调用时创建即可。

import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
public class WebClientExample {
    public static void main(String[] args) {
        // 创建 WebClient 实例
        WebClient webClient = WebClient.create();
        // 1. GET 请求 (响应式)
        Mono<Post> postMono = webClient.get()
                .uri("https://jsonplaceholder.typicode.com/posts/1")
                .retrieve() // 发出请求并获取响应
                .bodyToMono(Post.class); // 将响应体转换为 Mono<Post>
        // 订阅 Mono 并打印结果
        postMono.subscribe(post -> System.out.println("--- GET 请求响应 ---\n" + post));
        // 2. POST 请求 (响应式)
        Post newPost = new Post();
        newPost.setUserId(1);
        newPost.setTitle("WebClient Title");
        newPost.setBody("This is a post created by WebClient.");
        Mono<Post> createdPostMono = webClient.post()
                .uri("https://jsonplaceholder.typicode.com/posts")
                .bodyValue(newPost) // 设置请求体
                .retrieve()
                .bodyToMono(Post.class);
        createdPostMono.subscribe(post -> System.out.println("\n--- POST 请求响应 ---\n" + post));
    }
}

总结与选择

方法 易用性 性能 功能 依赖 适用场景
HttpURLConnection 中等 基础 简单脚本、无依赖环境、学习原理
Apache HttpClient 全面 httpclient 传统 Java 项目,需要高级功能
OkHttp 现代 okhttp Android、新 Java 项目,推荐首选
RestTemplate 极高 与 Spring 集成 spring-web Spring/Spring Boot 项目
WebClient 中 (需学响应式) 极高 (非阻塞) 响应式、流式 spring-webflux Spring 5+ 微服务、高并发场景

如何选择?

  • 新手或简单任务: 如果只是偶尔调用一两个 API,不想引入复杂依赖,OkHttp 是最佳选择,代码简洁,性能好。
  • Spring/Spring Boot 项目: 必须使用 RestTemplateWebClient,对于绝大多数传统 Spring Boot 应用,RestTemplate 已经足够且非常方便,如果你在构建响应式微服务,或者需要非阻塞 I/O 的高性能应用,请选择 WebClient
  • 企业级 Java 项目 (非 Spring): Apache HttpClient 是一个非常稳定和强大的选择。
  • 零依赖环境: 如果项目限制不能添加任何第三方库,只能使用 HttpURLConnection,但要做好处理繁琐代码的准备。
分享:
扫描分享到社交APP
上一篇
下一篇