当前位置: 首页 > news >正文

Flutter开发实战之网络请求与数据处理

第6章:网络请求与数据处理

“数据是应用的血液,网络是连接世界的桥梁。”

在移动应用开发中,与服务器进行数据交互是必不可少的功能。无论是获取用户信息、提交表单数据,还是上传图片、下载文件,都离不开网络请求。本章将带你深入掌握Flutter中的网络编程技巧。

6.1 网络请求基础概念

6.1.1 什么是HTTP请求?

想象一下,你走进一家餐厅点餐的过程:

  1. 你告诉服务员想要什么(发送请求)
  2. 服务员把你的需求传达给厨房(请求到达服务器)
  3. 厨房准备你的餐点(服务器处理请求)
  4. 服务员把餐点端给你(接收响应)

HTTP请求就是这样一个过程,只不过是应用与服务器之间的"点餐"过程。

6.1.2 常见的HTTP方法

// GET:获取数据,就像询问菜单
// POST:提交数据,就像下订单
// PUT:更新数据,就像修改订单
// DELETE:删除数据,就像取消订单
// PATCH:部分更新,就像只修改订单中的某个菜品

6.2 HTTP请求的封装与配置

6.2.1 使用原生http库

Flutter提供了基础的http库,但直接使用会让代码变得复杂:

import 'package:http/http.dart' as http;
import 'dart:convert';class BasicHttpClient {static const String baseUrl = 'https://api.example.com';// 基础GET请求static Future<Map<String, dynamic>> get(String endpoint) async {try {final response = await http.get(Uri.parse('$baseUrl$endpoint'),headers: {'Content-Type': 'application/json','Accept': 'application/json',},);if (response.statusCode == 200) {return json.decode(response.body);} else {throw Exception('请求失败: ${response.statusCode}');}} catch (e) {throw Exception('网络错误: $e');}}
}

6.2.2 为什么选择dio库?

dio库就像是一个功能强大的"网络请求管家",它帮我们处理了很多繁琐的工作:

  • 更简洁的API:写更少的代码做更多的事
  • 强大的拦截器:统一处理请求和响应
  • 自动错误处理:智能的错误重试机制
  • 文件操作支持:轻松上传下载文件
  • 请求取消:避免内存泄漏
  • 缓存支持:提升用户体验

6.3 dio库的高级用法

6.3.1 dio的基本配置

import 'package:dio/dio.dart';class HttpClient {static late Dio _dio;// 初始化dio实例static void init() {_dio = Dio(BaseOptions(baseUrl: 'https://api.example.com',connectTimeout: const Duration(seconds: 10),receiveTimeout: const Duration(seconds: 10),sendTimeout: const Duration(seconds: 10),headers: {'Content-Type': 'application/json','Accept': 'application/json',},));_setupInterceptors();}static Dio get dio => _dio;
}

6.3.2 创建一个优雅的网络请求封装类

class ApiClient {late Dio _dio;ApiClient() {_dio = Dio();_setupDio();}void _setupDio() {_dio.options = BaseOptions(baseUrl: 'https://jsonplaceholder.typicode.com',connectTimeout: const Duration(seconds: 10),receiveTimeout: const Duration(seconds: 10),headers: {'Content-Type': 'application/json',},);}// 通用请求方法Future<T> request<T>(String path, {String method = 'GET',Map<String, dynamic>? queryParameters,dynamic data,Map<String, dynamic>? headers,required T Function(dynamic) fromJson,}) async {try {final options = Options(method: method,headers: headers,);final response = await _dio.request(path,queryParameters: queryParameters,data: data,options: options,);return fromJson(response.data);} on DioException catch (e) {throw _handleDioError(e);}}// 错误处理String _handleDioError(DioException e) {switch (e.type) {case DioExceptionType.connectionTimeout:return '连接超时,请检查网络';case DioExceptionType.receiveTimeout:return '接收数据超时,请重试';case DioExceptionType.badResponse:return '服务器错误:${e.response?.statusCode}';case DioExceptionType.cancel:return '请求已取消';default:return '网络错误:${e.message}';}}
}

6.4 RESTful API接口调用

6.4.1 理解RESTful API

RESTful API就像是一套标准的"服务规范":

  • 资源导向:把数据看作资源,每个资源都有唯一的URL
  • HTTP方法语义化:用不同的HTTP方法表示不同的操作
  • 状态码标准化:用HTTP状态码表示操作结果

6.4.2 实现完整的CRUD操作

class UserService {final ApiClient _apiClient = ApiClient();// 获取用户列表 (GET)Future<List<User>> getUsers() async {return await _apiClient.request<List<User>>('/users',fromJson: (data) => (data as List).map((item) => User.fromJson(item)).toList(),);}// 获取单个用户 (GET)Future<User> getUser(int id) async {return await _apiClient.request<User>('/users/$id',fromJson: (data) => User.fromJson(data),);}// 创建用户 (POST)Future<User> createUser(User user) async {return await _apiClient.request<User>('/users',method: 'POST',data: user.toJson(),fromJson: (data) => User.fromJson(data),);}// 更新用户 (PUT)Future<User> updateUser(int id, User user) async {return await _apiClient.request<User>('/users/$id',method: 'PUT',data: user.toJson(),fromJson: (data) => User.fromJson(data),);}// 删除用户 (DELETE)Future<void> deleteUser(int id) async {await _apiClient.request<void>('/users/$id',method: 'DELETE',fromJson: (data) => null,);}
}

6.5 JSON数据序列化与反序列化

6.5.1 理解JSON序列化

JSON序列化就像是"翻译官"的工作:

  • 序列化:把Dart对象翻译成JSON字符串,方便网络传输
  • 反序列化:把JSON字符串翻译回Dart对象,方便程序使用

6.5.2 手动序列化(适合简单场景)

class User {final int id;final String name;final String email;final String? avatar;User({required this.id,required this.name,required this.email,this.avatar,});// 从JSON创建对象(反序列化)factory User.fromJson(Map<String, dynamic> json) {return User(id: json['id'] as int,name: json['name'] as String,email: json['email'] as String,avatar: json['avatar'] as String?,);}// 转换为JSON(序列化)Map<String, dynamic> toJson() {return {'id': id,'name': name,'email': email,if (avatar != null) 'avatar': avatar,};}String toString() {return 'User{id: $id, name: $name, email: $email}';}
}

6.5.3 使用json_annotation(推荐方式)

首先添加依赖:

dependencies:json_annotation: ^4.8.1dev_dependencies:json_serializable: ^6.7.1build_runner: ^2.4.7

然后创建模型类:

import 'package:json_annotation/json_annotation.dart';part 'user.g.dart';()
class User {final int id;final String name;final String email;(name: 'avatar_url')final String? avatarUrl;(name: 'created_at')final DateTime? createdAt;User({required this.id,required this.name,required this.email,this.avatarUrl,this.createdAt,});factory User.fromJson(Map<String, dynamic> json) =&
http://www.dtcms.com/a/300168.html

相关文章:

  • bmp280的压力数据采集(i2c设备驱动+设备树编写)
  • ACO-OFDM 的**频带利用率**(单位:bit/s/Hz)计算公式
  • 建筑施工场景下漏检率↓76%!陌讯多模态融合算法在工程安全监控的落地实践
  • OpHReda精准预测酶最佳PH
  • 进制间的映射关系
  • 2025牛客暑期多校第4场——G
  • Polyhedral Approaches in Combinatorial Optimization组合优化中的多面体方法(下)
  • Java实现大根堆与小根堆详解
  • 每日面试题15:如何解决堆溢出?
  • 如何检查服务器数据盘是否挂载成功?
  • Android-三种持久化方式详解
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-32,(知识点:模数转换器,信噪比,计算公式,)
  • 深入理解C语言快速排序与自省排序(Introsort)
  • 【每天一个知识点】GAN(生成对抗网络,Generative Adversarial Network)
  • Compose笔记(三十八)--CompositionLocal
  • 安卓学习记录1——持续更新ing
  • React组件中的this指向问题
  • 三防平板支持DMR对讲有什么用?实现高效集群调度
  • 如何理解“测试场景”与“测试要点”的区别和联系?
  • Linux系统架构核心全景详解
  • 从0到1学Pandas(六):Pandas 与数据库交互
  • KiCad 与 CircuitMaker 使用方法分享:从零开始学电子设计
  • JavaWeb(苍穹外卖)--学习笔记11(Filter(过滤器) 和 Interceptor(拦截器))
  • Windows开发,制作开发软件安装程序(一)
  • MySQL的底层原理--InnoDB数据页结构
  • 关于GateWay网关
  • 基于HMM的词性标注方法详解(HMM+Viterbi,例题分析)
  • 【专业扫盲】电压/电流反馈和串联/并联反馈
  • CSP2025模拟赛2(2025.7.26)
  • 机器人仿真(2)Ubuntu24.04下RTX5090配置IsaacSim与IsaacLab