HTTP客户端技术对比

技术 语言/平台 类型 主要特点
Feign Java/Spring 声明式微服务客户端 注解驱动,集成Spring Cloud生态
RestTemplate Java/Spring 同步HTTP客户端 Spring原生,简单易用但已过时
WebClient Java/Spring 响应式HTTP客户端 非阻塞,函数式API,性能优秀
Retrofit Java/Android 类型安全HTTP客户端 接口定义,支持RxJava/协程
axios JavaScript Promise-based客户端 浏览器/Node.js通用,支持拦截器

Feign

// Feign - 声明式、接口驱动
@FeignClient(name = "user-service")
public interface UserClient {
    @GetMapping("/users/{id}")
    User getUserById(@PathVariable Long id);
}
// 使用时直接调用方法,Feign自动生成HTTP请求
User user = userClient.getUserById(1);

Feign是Netflix开源的声明式HTTP客户端,后被Spring Cloud集成,成为微服务间调用的标准方案。

RestTemplate

import org.springframework.web.client.RestTemplate;

// 1. 创建实例
RestTemplate restTemplate = new RestTemplate();

// 2. 发起 GET 请求
String url = "https://api.example.com/users/1";
User user = restTemplate.getForObject(url, User.class);

// 3. 发起 POST 请求
User newUser = new User("张三", "zhangsan@example.com");
User createdUser = restTemplate.postForObject(url, newUser, User.class);

// 4. 使用 URI 模板
String result = restTemplate.getForObject(
    "https://api.example.com/users/{id}/orders/{orderId}",
    String.class,
    1,  // 对应 {id}
    100 // 对应 {orderId}
);

RestTemplate 是 Spring Framework 原生提供的 HTTP 客户端组件,属于 spring-web 模块的一部分。

WebClient

@Service
public class UserService {
    private final WebClient webClient;
    
    public UserService(WebClient.Builder builder) {
        this.webClient = builder
            .baseUrl("https://api.example.com")
            .defaultHeader("User-Agent", "MyApp")
            .build();
    }
    
    // 同步调用
    public User getUserByIdSync(Long id) {
        return webClient
            .get()
            .uri("/users/{id}", id)
            .retrieve()
            .bodyToMono(User.class)
            .block();  // 阻塞获取结果
    }
    
    // 异步调用(推荐)
    public Mono<User> getUserByIdAsync(Long id) {
        return webClient
            .get()
            .uri("/users/{id}", id)
            .retrieve()
            .bodyToMono(User.class)
            .doOnSuccess(user -> 
                System.out.println("获取用户成功: " + user.getName()))
            .doOnError(error -> 
                System.err.println("获取用户失败: " + error.getMessage()));
    }
    
    // 多个并行请求
    public Mono<List<User>> getMultipleUsers(List<Long> ids) {
        List<Mono<User>> monos = ids.stream()
            .map(id -> webClient.get()
                .uri("/users/{id}", id)
                .retrieve()
                .bodyToMono(User.class))
            .collect(Collectors.toList());
        
        return Flux.merge(monos).collectList();
    }
}

WebClient是Spring 5引入的响应式HTTP客户端,支持非阻塞IO,适合高并发场景。

Retrofit

// 1. 定义接口
public interface GitHubService {
    @GET("users/{user}/repos")
    Call<List<Repo>> listRepos(@Path("user") String user);
    
    @POST("users/new")
    Call<User> createUser(@Body User user);
}

// 2. 创建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

// 3. 生成接口实现
GitHubService service = retrofit.create(GitHubService.class);

// 4. 发起请求
Call<List<Repo>> call = service.listRepos("octocat");
call.enqueue(new Callback<List<Repo>>() {
    @Override
    public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
        // 处理响应
    }
    
    @Override
    public void onFailure(Call<List<Repo>> call, Throwable t) {
        // 处理失败
    }
});

Retrofit是Square公司开源的类型安全HTTP客户端,主要用于Android和Java应用。

axios

// 1. 基础使用
import axios from 'axios';

// 创建实例
const apiClient = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  headers: {'X-Custom-Header': 'foobar'}
});

// GET请求
async function getUserById(id) {
  try {
    // 方式1:Promise风格
    const response = await apiClient.get(`/users/${id}`);
    return response.data;
    
    // 方式2:回调风格
    // apiClient.get(`/users/${id}`)
    //   .then(response => console.log(response.data))
    //   .catch(error => console.error(error));
  } catch (error) {
    console.error('请求失败:', error);
    throw error;
  }
}

// 2. 并发请求
async function getMultipleUsers(ids) {
  try {
    const requests = ids.map(id => apiClient.get(`/users/${id}`));
    const responses = await Promise.all(requests);
    return responses.map(response => response.data);
  } catch (error) {
    console.error('批量请求失败:', error);
    throw error;
  }
}

// 3. 带参数的GET请求
async function getUsers(page = 1, size = 10) {
  const params = { page, size };
  return apiClient.get('/users', { params });
}

// 4. 拦截器
// 请求拦截器
apiClient.interceptors.request.use(
  config => {
    // 添加token
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => Promise.reject(error)
);

// 响应拦截器
apiClient.interceptors.response.use(
  response => response.data,  // 直接返回data
  error => {
    if (error.response?.status === 401) {
      // 跳转到登录页
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

axios运行在浏览器

Python requests

response = requests.get('http://user-service/users/1')
user = response.json()

requests:命令式,需要显式编写请求代码

 

posted @ 2026-01-25 19:42  雨花阁  阅读(0)  评论(0)    收藏  举报