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:命令式,需要显式编写请求代码
浙公网安备 33010602011771号