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

发布于:2025-08-17 ⋅ 阅读:(11) ⋅ 点赞:(0)

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的强大功能。


网站公告

今日签到

点亮在社区的每一天
去签到