swagger_generator_flutter/example/dio_retrofit_usage.dart

312 lines
7.6 KiB
Dart

/// Dio + Retrofit 使用示例
/// 展示如何使用生成的 API 代码进行网络请求
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';
// 假设这些是生成的代码
part 'dio_retrofit_usage.g.dart';
/// API 服务接口(生成的代码)
@RestApi(baseUrl: 'https://api.example.com/v1')
abstract class ApiService {
factory ApiService(Dio dio, {String? baseUrl}) = _ApiService;
/// 获取用户信息
@GET('/users/{id}')
Future<UserResponse> getUser(@Path('id') int id);
/// 创建用户
@POST('/users')
Future<UserResponse> createUser(@Body() CreateUserRequest request);
/// 上传头像
@POST('/users/{id}/avatar')
@MultiPart()
Future<UploadResponse> uploadAvatar(
@Path('id') int id,
@Part() MultipartFile avatar,
);
/// 获取用户列表(支持分页)
@GET('/users')
Future<UserListResponse> getUsers(
@Query('page') int page,
@Query('size') int size,
@Query('search') String? search,
);
/// 下载文件
@GET('/files/{id}')
@DioResponseType(ResponseType.bytes)
Future<List<int>> downloadFile(@Path('id') String id);
}
/// 用户响应模型
class UserResponse {
final int id;
final String name;
final String email;
final String? avatar;
UserResponse({
required this.id,
required this.name,
required this.email,
this.avatar,
});
factory UserResponse.fromJson(Map<String, dynamic> json) => UserResponse(
id: json['id'] as int,
name: json['name'] as String,
email: json['email'] as String,
avatar: json['avatar'] as String?,
);
}
/// 创建用户请求模型
class CreateUserRequest {
final String name;
final String email;
final String password;
CreateUserRequest({
required this.name,
required this.email,
required this.password,
});
Map<String, dynamic> toJson() => {
'name': name,
'email': email,
'password': password,
};
}
/// 用户列表响应模型
class UserListResponse {
final List<UserResponse> users;
final int total;
final int page;
final int size;
UserListResponse({
required this.users,
required this.total,
required this.page,
required this.size,
});
factory UserListResponse.fromJson(Map<String, dynamic> json) =>
UserListResponse(
users: (json['users'] as List)
.map((e) => UserResponse.fromJson(e as Map<String, dynamic>))
.toList(),
total: json['total'] as int,
page: json['page'] as int,
size: json['size'] as int,
);
}
/// 上传响应模型
class UploadResponse {
final String url;
final String filename;
final int size;
UploadResponse({
required this.url,
required this.filename,
required this.size,
});
factory UploadResponse.fromJson(Map<String, dynamic> json) => UploadResponse(
url: json['url'] as String,
filename: json['filename'] as String,
size: json['size'] as int,
);
}
/// API 客户端配置和使用示例
class ApiClient {
late final Dio _dio;
late final ApiService _apiService;
ApiClient({String? baseUrl}) {
_dio = Dio();
_setupDio();
_apiService = ApiService(_dio, baseUrl: baseUrl);
}
/// 配置 Dio
void _setupDio() {
// 基础配置
_dio.options.connectTimeout = const Duration(seconds: 30);
_dio.options.receiveTimeout = const Duration(seconds: 30);
_dio.options.sendTimeout = const Duration(seconds: 30);
// 添加拦截器
_dio.interceptors.addAll([
// 日志拦截器
LogInterceptor(
requestBody: true,
responseBody: true,
logPrint: (obj) => print(obj),
),
// 认证拦截器
BearerTokenInterceptor(token: 'your-auth-token'),
// API Key 拦截器
ApiKeyInterceptor(
apiKey: 'your-api-key',
location: ApiKeyLocation.header,
paramName: 'X-API-Key',
),
// 错误处理拦截器
ErrorHandlerInterceptor(),
]);
}
/// 获取用户信息
Future<UserResponse> getUser(int id) async {
try {
return await _apiService.getUser(id);
} catch (e) {
throw _handleError(e);
}
}
/// 创建用户
Future<UserResponse> createUser({
required String name,
required String email,
required String password,
}) async {
try {
final request = CreateUserRequest(
name: name,
email: email,
password: password,
);
return await _apiService.createUser(request);
} catch (e) {
throw _handleError(e);
}
}
/// 上传头像
Future<UploadResponse> uploadAvatar(int userId, String filePath) async {
try {
final file = await FileUploadHandler.createImageFile(filePath: filePath);
return await _apiService.uploadAvatar(userId, file);
} catch (e) {
throw _handleError(e);
}
}
/// 获取用户列表
Future<UserListResponse> getUsers({
int page = 1,
int size = 20,
String? search,
}) async {
try {
return await _apiService.getUsers(page, size, search);
} catch (e) {
throw _handleError(e);
}
}
/// 下载文件
Future<void> downloadFile(String fileId, String savePath) async {
try {
final bytes = await _apiService.downloadFile(fileId);
final file = File(savePath);
await file.writeAsBytes(bytes);
} catch (e) {
throw _handleError(e);
}
}
/// 错误处理
Exception _handleError(dynamic error) {
if (error is DioException) {
switch (error.type) {
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
return TimeoutException('请求超时,请检查网络连接');
case DioExceptionType.badResponse:
final statusCode = error.response?.statusCode;
final message = error.response?.data?['message'] ?? '服务器错误';
return HttpException('HTTP $statusCode: $message');
case DioExceptionType.cancel:
return Exception('请求已取消');
case DioExceptionType.connectionError:
return Exception('网络连接错误,请检查网络设置');
default:
return Exception('未知错误: ${error.message}');
}
}
return Exception('未知错误: $error');
}
/// 释放资源
void dispose() {
_dio.close();
}
}
/// 使用示例
void main() async {
final apiClient = ApiClient(baseUrl: 'https://api.example.com/v1');
try {
// 获取用户信息
final user = await apiClient.getUser(1);
print('用户信息: ${user.name} (${user.email})');
// 创建新用户
final newUser = await apiClient.createUser(
name: 'John Doe',
email: 'john@example.com',
password: 'password123',
);
print('创建用户成功: ${newUser.id}');
// 获取用户列表
final userList = await apiClient.getUsers(page: 1, size: 10);
print('用户总数: ${userList.total}');
// 上传头像(如果有文件的话)
// final uploadResult = await apiClient.uploadAvatar(1, '/path/to/avatar.jpg');
// print('头像上传成功: ${uploadResult.url}');
// 下载文件
// await apiClient.downloadFile('file-id', '/path/to/save/file.pdf');
// print('文件下载完成');
} catch (e) {
print('API 调用失败: $e');
} finally {
apiClient.dispose();
}
}
/// 自定义异常类
class TimeoutException implements Exception {
final String message;
TimeoutException(this.message);
@override
String toString() => 'TimeoutException: $message';
}
class HttpException implements Exception {
final String message;
HttpException(this.message);
@override
String toString() => 'HttpException: $message';
}