本文目录导读:

- 使用 HttpClient (JDK 11+)
- 使用 RestTemplate (Spring)
- 使用 WebClient (Spring WebFlux)
- 使用 Retrofit (Square)
- 通用接口调用工具类
- 使用示例
- 最佳实践建议
我来详细介绍Java中封装接口调用工具的几种常用方式。
使用 HttpClient (JDK 11+)
基础封装
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.time.Duration;
import com.fasterxml.jackson.databind.ObjectMapper;
public class HttpUtil {
private static final HttpClient httpClient;
private static final ObjectMapper objectMapper;
static {
httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
objectMapper = new ObjectMapper();
}
// GET请求
public static <T> T doGet(String url, Class<T> responseType) {
try {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.ofSeconds(30))
.GET()
.build();
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
return objectMapper.readValue(response.body(), responseType);
} catch (Exception e) {
throw new RuntimeException("HTTP GET请求失败", e);
}
}
// POST请求
public static <T, R> R doPost(String url, T requestBody, Class<R> responseType) {
try {
String jsonBody = objectMapper.writeValueAsString(requestBody);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
return objectMapper.readValue(response.body(), responseType);
} catch (Exception e) {
throw new RuntimeException("HTTP POST请求失败", e);
}
}
}
使用 RestTemplate (Spring)
RestTemplate配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(clientHttpRequestFactory());
}
private ClientHttpRequestFactory clientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000);
factory.setReadTimeout(5000);
factory.setBufferRequestBody(false);
return factory;
}
}
封装的工具类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
@Component
public class RestTemplateUtil {
@Autowired
private RestTemplate restTemplate;
// GET请求
public <T> T get(String url, Class<T> responseType) {
return restTemplate.getForObject(url, responseType);
}
// GET请求带参数
public <T> T get(String url, Map<String, Object> params, Class<T> responseType) {
return restTemplate.getForObject(url, responseType, params);
}
// POST请求
public <T> T post(String url, Object requestBody, Class<T> responseType) {
return restTemplate.postForObject(url, requestBody, responseType);
}
// 完整的请求
public <T> T exchange(String url, HttpMethod method,
Object requestBody, Class<T> responseType,
HttpHeaders headers) {
HttpEntity<Object> entity = new HttpEntity<>(requestBody, headers);
ResponseEntity<T> response = restTemplate.exchange(url, method, entity, responseType);
return response.getBody();
}
}
使用 WebClient (Spring WebFlux)
基础封装
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;
import java.time.Duration;
public class WebClientUtil {
private static final WebClient webClient = WebClient.builder()
.baseUrl("https://api.example.com")
.defaultHeader("Accept", "application/json")
.codecs(config -> config
.defaultCodecs()
.maxInMemorySize(16 * 1024 * 1024))
.build();
public static <T, R> Mono<R> post(String path, T requestBody, Class<R> responseType) {
return webClient.post()
.uri(path)
.bodyValue(requestBody)
.retrieve()
.bodyToMono(responseType)
.timeout(Duration.ofSeconds(30))
.onErrorResume(WebClientResponseException.class,
ex -> {
// 错误处理
return Mono.error(new RuntimeException("API调用失败: " + ex.getMessage()));
});
}
public static <T> Mono<T> get(String path, Class<T> responseType) {
return webClient.get()
.uri(path)
.retrieve()
.bodyToMono(responseType)
.timeout(Duration.ofSeconds(30));
}
}
使用 Retrofit (Square)
接口定义
import retrofit2.Call;
import retrofit2.http.*;
public interface ApiService {
@GET("users/{id}")
Call<User> getUser(@Path("id") Long id);
@POST("users")
Call<User> createUser(@Body User user);
@PUT("users/{id}")
Call<User> updateUser(@Path("id") Long id, @Body User user);
@DELETE("users/{id}")
Call<Void> deleteUser(@Path("id") Long id);
}
封装成工具类
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import java.io.IOException;
public class RetrofitClient {
private static final String BASE_URL = "https://api.example.com/";
private static Retrofit retrofit;
private static ApiService apiService;
static {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(ApiService.class);
}
// 同步调用
public static <T> T execute(Call<T> call) {
try {
Response<T> response = call.execute();
if (response.isSuccessful()) {
return response.body();
} else {
throw new RuntimeException("请求失败: " + response.code());
}
} catch (IOException e) {
throw new RuntimeException("网络请求异常", e);
}
}
// 异步调用
public static <T> void enqueue(Call<T> call, ApiCallback<T> callback) {
call.enqueue(new Callback<T>() {
@Override
public void onResponse(Call<T> call, Response<T> response) {
if (response.isSuccessful()) {
callback.onSuccess(response.body());
} else {
callback.onError(500, response.message());
}
}
@Override
public void onFailure(Call<T> call, Throwable t) {
callback.onError(500, t.getMessage());
}
});
}
public interface ApiCallback<T> {
void onSuccess(T data);
void onError(int code, String message);
}
}
通用接口调用工具类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
public class ApiClient {
private static final Logger log = LoggerFactory.getLogger(ApiClient.class);
private final HttpUtil httpUtil;
private final Map<String, Object> defaultHeaders;
public ApiClient(HttpUtil httpUtil) {
this.httpUtil = httpUtil;
this.defaultHeaders = new HashMap<>();
initDefaultHeaders();
}
private void initDefaultHeaders() {
defaultHeaders.put("Content-Type", "application/json");
defaultHeaders.put("Accept", "application/json");
defaultHeaders.put("User-Agent", "ApiClient/1.0");
}
// 带重试机制的调用
public <T, R> R callWithRetry(String url, T request,
Class<R> responseType,
int maxRetries) {
Exception lastException = null;
for (int i = 0; i < maxRetries; i++) {
try {
return doCall(url, request, responseType);
} catch (Exception e) {
lastException = e;
log.warn("调用失败,重试次数: {}/{}", i + 1, maxRetries);
sleep(1000 * (i + 1)); // 递增延迟
}
}
throw new RuntimeException("接口调用失败,已重试" + maxRetries + "次", lastException);
}
// 异步调用
public <T, R> CompletableFuture<R> callAsync(String url,
T request,
Class<R> responseType) {
return CompletableFuture.supplyAsync(() -> doCall(url, request, responseType));
}
// 带缓存的调用
public <T, R> R callWithCache(String url, T request,
Class<R> responseType,
Cache<String, R> cache) {
String cacheKey = generateCacheKey(url, request);
R cachedResult = cache.get(cacheKey);
if (cachedResult != null) {
log.debug("从缓存获取数据: {}", cacheKey);
return cachedResult;
}
R result = doCall(url, request, responseType);
cache.put(cacheKey, result);
return result;
}
private <T, R> R doCall(String url, T request, Class<R> responseType) {
try {
log.debug("调用API: {}, 请求参数: {}", url, request);
long startTime = System.currentTimeMillis();
R result = httpUtil.doPost(url, request, responseType);
long duration = System.currentTimeMillis() - startTime;
log.debug("API调用完成,耗时: {}ms, 结果: {}", duration, result);
return result;
} catch (Exception e) {
log.error("API调用异常: {}", url, e);
throw new ApiException("API调用失败: " + e.getMessage(), e);
}
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private <T> String generateCacheKey(String url, T request) {
return url + ":" + request.hashCode();
}
// 自定义异常
public static class ApiException extends RuntimeException {
public ApiException(String message, Throwable cause) {
super(message, cause);
}
}
}
使用示例
// 1. 基础使用
User user = HttpUtil.doPost("https://api.example.com/users",
new CreateUserRequest("张三"),
User.class);
// 2. Spring RestTemplate
User user = restTemplateUtil.post("https://api.example.com/users",
requestBody,
User.class);
// 3. 带重试机制
User user = apiClient.callWithRetry("https://api.example.com/users",
request,
User.class,
3);
// 4. 异步调用
CompletableFuture<User> future = apiClient.callAsync(url, request, User.class);
future.thenAccept(user -> {
System.out.println("获取到用户: " + user.getName());
});
最佳实践建议
- 统一异常处理:封装统一的异常类,便于上层处理
- 日志记录:记录请求和响应信息,便于问题排查
- 超时控制:设置合理的连接和读取超时时间
- 重试机制:关键接口添加重试逻辑
- 线程安全:确保工具类是线程安全的
- 配置化:将API地址、超时等参数配置化
- 监控集成:集成APM或监控系统,跟踪调用性能
选择合适的封装方式应根据项目需求、团队技术栈和框架来决定。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播