Flutter网络请求实战:Retrofit+Dio完美解决方案

Flutter网络请求:Retrofit使用指南

Retrofit是Android平台上广受欢迎的HTTP客户端库,在Flutter中可以通过retrofit包实现类似的网络请求功能。下面是完整的使用指南:

1. 添加依赖

首先在pubspec.yaml中添加所需依赖:

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接口:

dart 复制代码
import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';
import 'package:json_annotation/json_annotation.dart';

part 'api_service.g.dart';

@RestApi(baseUrl: "https://jsonplaceholder.typicode.com/")
abstract class ApiService {
  factory ApiService(Dio dio, {String baseUrl}) = _ApiService;

  @GET("/posts")
  Future<List<Post>> getPosts();

  @GET("/posts/{id}")
  Future<Post> getPost(@Path("id") int id);

  @POST("/posts")
  Future<Post> createPost(@Body() Post post);
}

@JsonSerializable()
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. 生成代码

运行以下命令生成实现代码:

bash 复制代码
flutter pub run build_runner build

这会生成api_service.g.dart文件。

4. 使用API服务

dart 复制代码
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. 高级功能

添加请求头

dart 复制代码
@GET("/posts")
@Headers({'Content-Type': 'application/json'})
Future<List<Post>> getPosts();

查询参数

dart 复制代码
@GET("/posts")
Future<List<Post>> getPostsByUser(@Query("userId") int userId);

表单数据

dart 复制代码
@POST("/login")
@FormUrlEncoded()
Future<User> login(
  @Field("username") String username,
  @Field("password") String password,
);

拦截器

dart 复制代码
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. 完整配置示例

dart 复制代码
import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';

part 'api_service.g.dart';

@RestApi(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);
  }

  @GET("users")
  Future<List<User>> getUsers();

  @GET("users/{id}")
  Future<User> getUser(@Path("id") String id);

  @POST("users")
  Future<User> createUser(@Body() User user);

  @PUT("users/{id}")
  Future<User> updateUser(@Path("id") String id, @Body() User user);

  @DELETE("users/{id}")
  Future<void> deleteUser(@Path("id") String id);
}

7. 错误处理

dart 复制代码
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服务

dart 复制代码
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的强大功能。

相关推荐
书弋江山2 小时前
flutter 跨平台编码库 protobuf 工具使用
android·flutter
程序员老刘·2 小时前
Flutter 3.35 更新要点解析
flutter·ai编程·跨平台开发·客户端开发
tangweiguo030519872 小时前
Flutter vs Android:页面生命周期对比详解
flutter
来来走走5 小时前
Flutter开发 webview_flutter的基本使用
android·flutter
落魄的Android开发6 小时前
Flutter以模块化适配 HarmonyOS方案的实现步骤
flutter
tangweiguo030519877 小时前
Flutter GetX 全面指南:状态管理、路由与依赖注入的最佳实践
flutter
来来走走11 小时前
Flutter Form组件的基本使用
android·flutter
fouryears_234171 天前
Flutter InheritedWidget 详解:从生命周期到数据流动的完整解析
开发语言·flutter·客户端·dart
LinXunFeng1 天前
Flutter - 详情页 TabBar 与模块联动?秒了!
前端·flutter·开源