Flutter 聯網和JSON轉換成Bean
Flutter 聯網和JSON轉換成Bean
Flutter的聯網分為HttpClient和dio兩種。HttpClient是dart io中的HttpClient發起的請求,但HttpClient本身功能較弱,很多常用功能都不支援。dart io官網文件.
dio是一個強大的Dart Http請求庫,支援Restful API、FormData、攔截器、請求取消、Cookie管理、檔案上傳/下載、超時等…dio github地址.
JSON型別資料的轉換分為兩種:手動序列化和反序列化 dart:convert和通過程式碼生成自動序列化和反序列化json_serializable。
手動JSON序列化是指使使用dart:convert中內建的JSON解碼器。它將原始JSON字串傳遞給JSON.decode() 方法,然後在返回的Map<String, dynamic>中查詢所需的值。 它沒有外部依賴或其它的設定,對於小專案很方便。
當您的專案變大時,手動編寫序列化邏輯可能變得難以管理且容易出錯。如果您在訪問未提供的JSON欄位時輸入了一個錯誤的欄位,則您的程式碼將會在執行時會引發錯誤。
HttpClient和dart convert序列化資料
String url = "https://httpbin.org/ip";
var httpClient = HttpClient();
String result;
try {
var request = await httpClient.getUrl(Uri.parse(url));
var response = await request.close();
if(response.statusCode == HttpStatus.ok){
var jsonStr = await response.transform(utf8.decoder).join();
var date = json.decode(jsonStr);
result = date['origin'];
}else{
result = 'Error getting IP address:\nHttp status ${response.statusCode}';
}
}catch(Exception){
result = 'Failed getting IP address';
}
這段程式碼用的是HttpClient和內連序列化JSON.
下面介紹。在模型類中序列化JSON:
1.先建立一個IpBean用於接收返回的資料
class IpBean{
String origin;
IpBean({this.origin});
IpBean.fromJson(Map<String, dynamic> json)
: origin = json['origin'];
Map<String, dynamic> toJson() =>
{
'origin': origin,
};
}
2.進行序列化:
var jsonStr = await response.transform(utf8.decoder).join();
IpBean ipBean = new IpBean.fromJson(ipMap);
3.反序列化:
String ipStr = json.encode(ipBean);
dio請求庫和json_serializable序列化資料
1.匯入請求庫
dependencies:
flutter:
sdk: flutter
json_annotation: ^1.2.0
dio: ^1.0.6
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^1.1.1
json_serializable: ^1.3.0
匯入這四個庫就可以開始愉快的聯網請求了
2.建立build.yaml檔案。
在專案的根目錄下新建一個build.yaml的檔案用於構件專案時自動生成程式碼:
build.yaml程式碼
targets:
$default:
builders:
json_serializable:
options:
# Options configure how source code is generated for every
# `@JsonSerializable`-annotated class in the package.
#
# The default value for each is listed.
#
# For usage information, reference the corresponding field in
# `JsonSerializableGenerator`.
any_map: false
checked: false
create_factory: true
create_to_json: true
disallow_unrecognized_keys: false
explicit_to_json: false
field_rename: none
generate_to_json_function: true
include_if_null: true
nullable: true
use_wrappers: false
3.準備好要序列化的Bean類
import 'package:json_annotation/json_annotation.dart';
part 'ImageBean.g.dart';
@JsonSerializable()
class ImageBean{
ImageBean(this.url);
String url;
factory ImageBean.fromJson(Map<String, dynamic> json) => _$ImageBeanFromJson(json);
Map<String, dynamic> toJson() => _$ImageBeanToJson(this);
}
part 'ImageListBean.g.dart';
@JsonSerializable()
class ImageListBean{
ImageListBean(this.results,this.error);
List<ImageBean> results;
bool error;
factory ImageListBean.fromJson(Map<String, dynamic> json) => _$ImageListBeanFromJson(json);
Map<String, dynamic> toJson() => _$ImageListBeanToJson(this);
}
第一次建立類時,您會看到與下圖類似的錯誤
這些錯誤是完全正常的,這是因為model類的生成程式碼還不存在。為了解決這個問題,我們必須執行程式碼生成器來為我們生成序列化模板。
4.執行程式碼生成器
有兩種執行程式碼生成器的方法:
一次性生成
通過在我們的專案根目錄下執行flutter packages pub run build_runner build,我們可以在需要時為我們的model生成json序列化程式碼。 這觸發了一次性構建,它通過我們的原始檔,挑選相關的併為它們生成必要的序列化程式碼。
雖然這非常方便,但如果我們不需要每次在model類中進行更改時都要手動執行構建命令的話會更好。
持續生成
使用_watcher_可以使我們的原始碼生成的過程更加方便。它會監視我們專案中檔案的變化,並在需要時自動構建必要的檔案。我們可以通過flutter packages pub run
build_runner watch在專案根目錄下執行來啟動_watcher_。
只需啟動一次觀察器,然後並讓它在後臺執行,這是安全的。
5.使用dio庫傳送網路請求,並完成序列化
print("------------------------開始請求--------------------------------------");
Dio dio = Dio();
dio.options.baseUrl = "https://gank.io/";
dio.options.connectTimeout = 5000;
dio.options.receiveTimeout = 5000;
dio.options.responseType = ResponseType.JSON;
dio.options.path = "/api/data/福利/10/1";
dio.options.headers = {
'user-agent': 'dio',
'from': "dio"
};
Response response = await dio.get("/api/data/福利/10/1");
var data = response.data;
print(data);
print(response.data is String);
ImageListBean image = ImageListBean.fromJson(data);
print("------------------------請求結束---------------------------------------");
這樣就完成了一次網路請求。
參考文件
Flutter中文網 在Flutter中發起HTTP網路請求
Flutter中文網 JSON和序列化