第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.pswp.cn/diannao/93553.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/93553.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/93553.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速分页实现热点功能-索引和order by

需求:分页求出进三天的发布视频的权重热度 权重 / 衰减时间 衰减时间 当前时间 - 视频发布时间 小根堆来实现这个公式可以很好的利用半衰期来进行解决难点:如果一次性加载太多到springBoot服务器里面会造成堆内存占用过多&#xff0c;分页又有可能造成深分页问题&#xff0c;…

HAProxy(高可用性代理)

1 HAProxy 简介 HAProxy&#xff08; High Availability Proxy&#xff09;是一个高性能的负载均衡器和代理服务器&#xff0c;为基于 TCP 和 HTTP 的应用程序提供高可用性、负载平衡和代理&#xff0c;广泛应用于提高 web 应用程序的性能和可靠性。它支持多种协议&#xff0c…

Vulnhub靶场:ica1

一、信息收集nmap扫描一下IP。&#xff08;扫不出来的可以看一下前面几篇找ip的步骤&#xff09;下面给了框架的版本是9.2的&#xff0c;我们去kali里搜一下有没有已经公开的漏洞。searchsploit qdPM 9.2 locate 50176.txt more /usr/share/exploitdb/exploits/php/webapps/50…

【Dv3admin】ORM数据库无法查询的问题

Django 运行过程中&#xff0c;数据库连接的健康状态直接影响应用的稳定性和数据访问准确性。长时间空闲的数据库连接经常因外部机制被回收&#xff0c;进而引发数据查询异常和返回无效结果。 本文围绕 Django 中数据库连接长时间空闲导致的连接失效问题&#xff0c;介绍相关的…

使用 Flownex 对机械呼吸机进行建模

当患者无法独立呼吸时&#xff0c;机械呼吸机通过气管插管将富氧空气输送到患者的肺部。肺是敏感而复杂的器官&#xff0c;因此在无法忍受的压力和体积范围内提供空气&#xff0c;根据每分钟所需的呼吸次数计时&#xff0c;并适当加湿和加热。机械呼吸机的精确建模对于其安全有…

力扣刷题日常(7-8)

力扣刷题日常(7-8) 第7题: 整数反转(难度: 中等) 原题: 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果. 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0. 假设环境不允许存储 64 位整数&#xff08;有符号或无符号&#xff09;.…

串口接收数据包(协议带帧头帧尾)的编程实现方法:1、数据包格式定义结构体2、使用队列进行数据接收、校验解包

这种带帧头帧尾的数据包处理流程可以简单概括为 “识别边界→提取有效数据→验证完整性” 三个核心步骤&#xff0c;具体操作如下&#xff1a;1. 数据包格式定义&#xff08;先约定规则&#xff09;首先明确一个 “合格数据包” 的结构&#xff0c;比如&#xff1a; 帧头&#…

JSON 对象封装教程

JSON 对象封装方法在 Java 中封装 JSON 对象通常使用第三方库&#xff0c;如 org.json、Gson 或 Jackson。以下是几种常见的方法&#xff1a;使用 org.json 库添加 Maven 依赖&#xff1a;<dependency><groupId>org.json</groupId><artifactId>json<…

【WRF-Chem】EDGAR 排放数据处理:分部门合并转化为二进制(Python全代码)

目录 process.py process_biofl.py process_fossil.py process_micro.py process_sector.py 参考 process.py 读取 EDGAR 排放数据库中 2000 至 2023 年间不同行业的甲烷(CH₄)排放数据,进行合并处理,并将总排放以二进制格式保存到文件中。 导入必要的库 import numpy as n…

【学习过程记录】【czsc】1、安装

文章目录 背景 安装 安装python 安装czsc 功能测试 附录 奇葩的报错 背景 详见: https://github.com/waditu/czsc 安装 安装python !重要!作者强调,python必须是大于等于3.8 为此呢,我也是花了一点时间装了一个python3.13。 安装czsc 关于czsc的安装呢,官方也是给出…

Python批量生成N天前的多word个文件,并根据excel统计数据,修改word模板,合并多个word文件

1&#xff0c;需求 根据word模板文件&#xff0c;生成多个带日期后缀的word文件根据excel-每日告警统计数量&#xff0c;逐个修改当日的文档2&#xff0c;实现 shell脚本&#xff1a;根据word模板文件&#xff0c;生成多个带日期后缀的word文件 #!/bin/bash # 生成近一年日期 …

基于uni-app的血糖血压刻度滑动控件

想要做一个基于uni-app的血糖血压刻度滑动控件&#xff0c;hbuilder市场没有好的&#xff0c;参照别人的写了一个。如图&#xff1a;源码&#xff0c;自己放入components里面。<!-- 刻度滑动选择 --> <template><view><view class"slide-title"…

C语言(02)——标准库函数大全(持续更新)

想要了解更多的C语言知识&#xff0c;可以订阅下面的专栏&#xff0c;里面也有很多品质好文&#xff1a; 打怪升级之路——C语言之路_ankleless的博客-CSDN博客 还在持续更新中&#xff0c;以下是学习过程中遇到的一些库函数&#xff08;排序不分先后&#xff09;&#xff1a…

永磁同步电机无速度算法--静态补偿电压模型Harnefors观测器

一、原理介绍本文基于Harnefors教授提出的静态补偿电压模型&#xff0c;可以实现带载零速启动、正反转切换等功能&#xff0c;原理清晰&#xff0c;实现简便。二、仿真模型在MATLAB/simulink里面验证所提算法&#xff0c;搭建仿真。采用和实验中一致的控制周期1e-4&#xff0c;…

[SKE]Python gmssl库的C绑定

Python gmssl库的C绑定 摘要:本文展示gmssl库的C绑定,并给出完整代码。将参考模型从Python脚本迁移到纯C代码中使用gmssl库(TongSuo项目,支持国密算法如SM4,同时兼容AES、DES、3DES、RSA等)。这样,UVM(SystemVerilog)可以通过DPI-C直接调用C函数,而无需嵌入Py…

4.方法的使用

方法是指一段具有独立功能的代码块&#xff0c;只有被调用时才会执行方法的主要作用体现在&#xff1a;代码组织&#xff1a;将原本挤在一起的臃肿代码按照功能进行分类管理例如&#xff1a;将用户注册的验证逻辑、数据库操作、结果返回等分离成不同方法提高复用性&#xff1a;…

day21-Excel文件解析

目录 1. 概述 2. Apache POI 3. XSSF解析Excel文件 3.1. 添加Jar包依赖 3.2. Workbook&#xff08;Excel文件&#xff09; 3.2.2. 加载&#xff08;解析&#xff09;Excel文件 3.3. Sheet &#xff08;工作簿&#xff09; 3.3.1. 创建工作簿 3.3.2. 获取工作簿 3.3.3.…

与 TRON (波场) 区块链进行交互的命令行工具 (CLI): tstroncli

源码仓库 一个基于 Node.js 和 TypeScript 构建的&#xff0c;用于与 TRON (波场) 区块链进行交互的命令行工具 (CLI)。 本项目旨在提供一个简单、可扩展的框架&#xff0c;让开发者可以轻松地通过命令行调用 TRON 的 HTTP API&#xff0c;实现查询链上信息、发送交易等操作。…

rabbitmq--默认模式(点对点)

导入包&#xff1a;<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency>application.yml springrabbitmq:host: localhostport: 5672username: guestpassword: gue…

外网访问文档编辑器Docsify(Windows版本),内网穿透技术应用简便方法

如果你正在为项目写文档&#xff0c;但又不想折腾复杂的构建流程&#xff0c;也不想维护一堆静态 HTML 文件&#xff0c;那你一定要试试 docsify。docsify 是一个基于 JavaScript 的开源文档生成工具&#xff0c;它最大的特点就是“无构建”&#xff1a;你只需要写 Markdown 文…