Flutter网络请求:Retrofit使用指南
Retrofit是Android平台上广受欢迎的HTTP客户端库,在Flutter中可以通过retrofit
包实现类似的网络请求功能。下面是完整的使用指南:
1. 添加依赖
首先在pubspec.yaml
中添加所需依赖:
dependencies:
retrofit: ^4.0.1
dio: ^5.3.2
json_annotation: ^4.8.1
dev_dependencies:
retrofit_generator: ^4.0.1
build_runner: ^2.4.4
2. 创建API接口
定义一个抽象类来描述你的API接口:
import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';
import 'package:json_annotation/json_annotation.dart';
part 'api_service.g.dart';
(baseUrl: "https://jsonplaceholder.typicode.com/")
abstract class ApiService {
factory ApiService(Dio dio, {String baseUrl}) = _ApiService;
("/posts")
Future<List<Post>> getPosts();
("/posts/{id}")
Future<Post> getPost(("id") int id);
("/posts")
Future<Post> createPost(() Post post);
}
()
class Post {
final int id;
final String title;
final String body;
final int userId;
Post({
required this.id,
required this.title,
required this.body,
required this.userId,
});
factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
Map<String, dynamic> toJson() => _$PostToJson(this);
}
3. 生成代码
运行以下命令生成实现代码:
flutter pub run build_runner build
这会生成api_service.g.dart
文件。
4. 使用API服务
void main() async {
final dio = Dio();
final apiService = ApiService(dio);
try {
// 获取所有帖子
final posts = await apiService.getPosts();
print(posts);
// 获取单个帖子
final post = await apiService.getPost(1);
print(post);
// 创建新帖子
final newPost = await apiService.createPost(
Post(id: 101, title: 'New Post', body: 'Content', userId: 1),
);
print(newPost);
} catch (e) {
print(e);
}
}
5. 高级功能
添加请求头
("/posts")
({'Content-Type': 'application/json'})
Future<List<Post>> getPosts();
查询参数
("/posts")
Future<List<Post>> getPostsByUser(("userId") int userId);
表单数据
("/login")
()
Future<User> login(
("username") String username,
("password") String password,
);
拦截器
final dio = Dio()
..interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) {
// 添加认证token
options.headers['Authorization'] = 'Bearer token';
return handler.next(options);
},
onError: (DioError e, handler) {
// 错误处理
return handler.next(e);
},
),
);
6. 完整配置示例
import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';
part 'api_service.g.dart';
(baseUrl: "https://api.example.com/v1/")
abstract class ApiService {
factory ApiService(Dio dio, {String baseUrl}) {
dio.options = BaseOptions(
receiveTimeout: const Duration(seconds: 30),
connectTimeout: const Duration(seconds: 30),
);
return _ApiService(dio, baseUrl: baseUrl);
}
("users")
Future<List<User>> getUsers();
("users/{id}")
Future<User> getUser(("id") String id);
("users")
Future<User> createUser(() User user);
("users/{id}")
Future<User> updateUser(("id") String id, () User user);
("users/{id}")
Future<void> deleteUser(("id") String id);
}
7. 错误处理
try {
final response = await apiService.getUser('123');
} on DioError catch (e) {
if (e.response != null) {
print(e.response?.statusCode);
print(e.response?.data);
} else {
print(e.message);
}
}
8. 测试API服务
test('getPosts returns List<Post>', () async {
final dio = DioAdapterMock();
final apiService = ApiService(dio);
when(dio.get('/posts')).thenAnswer((_) async => Response(
data: [
{'id': 1, 'title': 'Test', 'body': 'Content', 'userId': 1}
],
statusCode: 200,
requestOptions: RequestOptions(path: '/posts'),
));
final posts = await apiService.getPosts();
expect(posts, isA<List<Post>>());
expect(posts.first.title, 'Test');
});
Retrofit为Flutter提供了类型安全的HTTP客户端实现,通过代码生成简化了网络请求的编写,同时保持了Dio的强大功能。