Flutter網路請求與JSON解析
本文介紹如何在Flutter中建立HTTP網路請求和對請求的json string進行型別解析.
-
網路請求
官方使用的是用dart io中的HttpClient
發起的請求,但HttpClient
本身功能較弱,很多常用功能都不支援。
建議使用dio 來發起網路請求,它是一個強大易用的dart http請求庫,支援Restful API、FormData、攔截器、請求取消、Cookie管理、檔案上傳/下載……
dart:io
發起HTTP請求
http支援位於dart:io
,所以要建立一個HTTP client, 我們需要新增一個匯入:
import 'dart:io';
var httpClient = new HttpClient();
該 client 支援常用的HTTP操作, such as GET
, POST
, PUT
, DELETE
.
處理非同步
注意,HTTP API 在返回值中使用了Dart Futures。 我們建議使用async
/await
語法來呼叫API。
網路呼叫通常遵循如下步驟:
- 建立 client.
- 構造 Uri.
- 發起請求, 等待請求,同時您也可以配置請求headers、 body。
- 關閉請求, 等待響應.
- 解碼響應的內容.
Several of these steps use Future based APIs. Sample APIs calls for each step above are: 其中的幾個步驟使用基於Future的API。上面步驟的示例:
get() async { var httpClient = new HttpClient(); var uri = new Uri.http( 'example.com', '/path1/path2', {'param1': '42', 'param2': 'foo'}); var request = await httpClient.getUrl(uri); var response = await request.close(); var responseBody = await response.transform(UTF8.decoder).join(); }
dio
新增依賴
dependencies:
dio: ^x.x.x // latest version
發起一個 GET
請求 :
Response response; response=await dio.get("/test?id=12&name=wendu") print(response.data.toString()); // 請求引數也可以通過物件傳遞,上面的程式碼等同於: response=await dio.get("/test",data:{"id":12,"name":"wendu"}) print(response.data.toString());
發起一個 POST
請求:
response=await dio.post("/test",data:{"id":12,"name":"wendu"})
發起多個併發請求:
response= await Future.wait([dio.post("/info"),dio.get("/token")]);
下載檔案:
response=await dio.download("https://www.google.com/","./xx.html")
傳送 FormData:
FormData formData = new FormData.from({ "name": "wendux", "age": 25, }); response = await dio.post("/info", data: formData)
通過FormData上傳多個檔案:
FormData formData = new FormData.from({ "name": "wendux", "age": 25, "file1": new UploadFileInfo(new File("./upload.txt"), "upload1.txt") "file2": new UploadFileInfo(new File("./upload.txt"), "upload2.txt") }); response = await dio.post("/info", data: formData)
-
JSON解析
使用 dart:convert手動序列化JSON
Flutter中基本的JSON序列化非常簡單。Flutter有一個內建dart:convert
庫,其中包含一個簡單的JSON編碼器和解碼器。
以下是一個簡單的user model的示例JSON。
{
"name": "John Smith",
"email": "[email protected]"
}
有了dart:convert
,我們可以用兩種方式來序列化這個JSON model。我們來看看這兩種方法:
內連序列化JSON
通過檢視dart:轉換JSON文件,我們發現可以通過呼叫JSON.decode
方法來解碼JSON ,使用JSON字串作為引數。
Map<String, dynamic> user = JSON.decode(json);
print('Howdy, ${user['name']}!');
print('We sent the verification link to ${user['email']}.');
不幸的是,JSON.decode()僅返回一個Map<String, dynamic>
,這意味著我們直到執行時才知道值的型別。 通過這種方法,我們失去了大部分靜態型別語言特性:型別安全、自動補全和最重要的編譯時異常。這樣一來,我們的程式碼可能會變得非常容易出錯。
例如,當我們訪問name
或email
欄位時,我們輸入的很快,導致欄位名打錯了。但由於這個JSON在map結構中,所以編譯器不知道這個錯誤的欄位名(譯者語:所以編譯時不會報錯)。
在模型類中序列化JSON
我們可以通過引入一個簡單的模型類(model class)來解決前面提到的問題,我們稱之為User
。在User類內部,我們有:
- 一個
User.fromJson
建構函式, 用於從一個map構造出一個User
例項 map structure - 一個
toJson
方法, 將User
例項轉化為一個map.
這樣,呼叫程式碼現在可以具有型別安全、自動補全欄位(name和email)以及編譯時異常。如果我們將拼寫錯誤或欄位視為int
型別而不是String
, 那麼我們的應用程式就不會通過編譯,而不是在執行時崩潰。
user.dart
class User {
final String name;
final String email;
User(this.name, this.email);
User.fromJson(Map<String, dynamic> json)
: name = json['name'],
email = json['email'];
Map<String, dynamic> toJson() =>
{
'name': name,
'email': email,
};
}
現在,序列化邏輯移到了模型本身內部。採用這種新方法,我們可以非常容易地反序列化user。
Map userMap = JSON.decode(json);
var user = new User.fromJson(userMap);
print('Howdy, ${user.name}!');
print('We sent the verification link to ${user.email}.');
要序列化一個user,我們只是將該User
物件傳遞給該JSON.encode
方法。我們不需要手動呼叫toJson
這個方法,因為JSON.encode
已經為我們做了。
String json = JSON.encode(user);
Json對映到物件
首先要藉助一個工具jsonformat 工具下載地址
舉一個例子 json檔案,來自玩安卓網站
這是一個相對很複雜的json檔案
用jsonview開啟檢視,這個json檔案包含一個data的陣列和兩個變數,然後陣列的每一項又包含一個數組和6個變數,然後下一級陣列的每一項又包含一個數組和6個變數
下面使用jsonformat 轉換成dart bean檔案
開啟下載的jsonformat ,將json檔案copy進去點選格式化
右邊的紅色是我們要填寫的類名稱,對應關係像這樣,這裡分別填寫 tree children children ,後兩個相同,點選生成bean
生成程式碼如下
import 'dart:convert' show json;
class tree {
int errorCode;
String errorMsg;
List<children> data;
tree(jsonStr) {
var jsonRes = json.decode(jsonStr);
errorCode = jsonRes['errorCode'];
errorMsg = jsonRes['errorMsg'];
data = [];
for (var dataItem in jsonRes['data']){
data.add(new children(dataItem));
}
}
@override
String toString() {
return '{"errorCode": $errorCode,"errorMsg": ${errorMsg != null?'${json.encode(errorMsg)}':'null'},"data": $data}';
}
}
class children {
int courseId;
int id;
int order;
int parentChapterId;
int visible;
String name;
List<children> children;
children(jsonRes) {
courseId = jsonRes['courseId'];
id = jsonRes['id'];
order = jsonRes['order'];
parentChapterId = jsonRes['parentChapterId'];
visible = jsonRes['visible'];
name = jsonRes['name'];
children = [];
for (var childrenItem in jsonRes['children']){
children.add(new children(childrenItem));
}
}
@override
String toString() {
return '{"courseId": $courseId,"id": $id,"order": $order,"parentChapterId": $parentChapterId,"visible": $visible,"name": ${name != null?'${json.encode(name)}':'null'},"children": $children}';
}
}
class children {
int courseId;
int id;
int order;
int parentChapterId;
int visible;
String name;
List<dynamic> children;
children(jsonRes) {
courseId = jsonRes['courseId'];
id = jsonRes['id'];
order = jsonRes['order'];
parentChapterId = jsonRes['parentChapterId'];
visible = jsonRes['visible'];
name = jsonRes['name'];
children = [];
for (var childrenItem in jsonRes['children']){
children.add(childrenItem);
}
}
@override
String toString() {
return '{"courseId": $courseId,"id": $id,"order": $order,"parentChapterId": $parentChapterId,"visible": $visible,"name": ${name != null?'${json.encode(name)}':'null'},"children": $children}';
}
}
接下來就是在APP中請求網路,將其轉換成dart bean
///封裝的get請求 _networkUtil,可以替換成自己的請求方式
///發起get網路請求並且轉換json
Future<dynamic> requestGet(String url) {
return http.get(url)
.then((http.Response response) {
final String res = response.body;
final int statusCode = response.statusCode;
if (statusCode < 200 || statusCode > 400 || json == null) {
throw new Exception("Error while fetching data");
}
///有值
return _decoder.convert(res);
});
}
///這裡返回的就是 Future<Tree> 物件,(fillUrl(TREE_LIST)是請求的url
Future<Tree> fetchTree() {
return _networkUtil.requestGet(fillUrl(TREE_LIST)).then((dynamic res) {
///可以這樣取值
return new Tree.map(res);
});
}
相關推薦
Flutter網路請求與JSON解析
本文介紹如何在Flutter中建立HTTP網路請求和對請求的json string進行型別解析. 網路請求 官方使用的是用dart io中的HttpClient發起的請求,但HttpClient本身功能較弱,很多常用功能都不支援。 建議使用dio 來發起網路請求,它是一個強大易用的dart http請求庫
Android okHttp網路請求之Json解析
前言: 前面兩篇文章介紹了基於okHttp的post、get請求,以及檔案的上傳下載,今天主要介紹一下如何和Json解析一起使用?如何才能提高開發效率? okHttp相關文章地址: 關於Json解析: 本文的Json解析採用阿里巴巴的FastJson 解析,也可以採用Gso
iOS 自己封裝的網路請求,json解析的類
基本上所有的APP都會涉及網路這塊,不管是用AFNetWorking還是自己寫的http請求,整個網路框架的搭建很重要。 樓主封裝的網路請求類,包括自己寫的http請求和AFNetWorking的請求,程式碼簡單,主要是框架搭建。簡單來說,就是一個請求類,一個
flutter網路請求json
import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart';//使用網路請求json c
ajax請求與json數據處理
[ ] data 引入 img mil scrip get 總結 url 一,ajax使用配置 1)使用ajax之前先引入jquery <script type="text/javascript" src="js/jquery-1.8.2.js"><
Javascript中的Array(陣列) 、{}(對映) 與JSON解析
下面是總結: 1.將javascript中的Array和{}轉化為json字串可以使用json2.js,原始碼地址https://github.com/douglascrockford/JSON-js。 2.將json字串轉為javascript物件,可以使用javascript自帶的eva
Get請求與Gson解析
MyActivity頁面 package com.example.lx_two; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity;
dio+json_serializable從網路請求到資料解析
前言 網路請求到資料解析是一個app必不可少的流程之一,在flutter官網中目前主要是介紹 自帶的Http請求+Json解析 但是也推薦了更好的網路請求到組合的方式 dio 和 json_serializable,本篇文章主要介紹這兩個方式的使用,原始碼在結尾 本文同步更新於我的gitpage x
python網路請求將json字元轉為物件
class CreateOrder: def __init__(self): self.code self.data self.msg # 做多(0)、做空(1) def reqCreateOrderAndEdit
json字串轉為map結構,用於處理遠端請求獲得json解析,自動解析多成結構
很實用的工具類 import net.sf.json.JSONArray; import net.sf.json.JSONObject public class Json2Map { /** * 將json字串轉為Map結構 * 如果json
axios 網路請求與資料下載
axios 一、先引入js 第一種:通過cdn載入 <script src="https://unpkg.com/axios/dist/axios.min.js"></script> 第二種:通過npm或者cnpm載入 $
解決利用Okhttp+Retrofit 傳送網路請求得到json是unicode
我們在用Okhttp和Retrofit傳送網路請求時,得到的json中漢子是unicode編碼,如圖 此時我們需要在Okhttp初始化的時候設定它的網路編輯器,同時將返回值的編碼改成UTF-8. 之前設定的OKhttp HttpLoggingInte
Kotlin簡單網路請求及資料解析
一,網路請求 以下是在Android下用最基礎的進行網路請求方法,但獲取的資料量大的話就不能用這個方法了 1,定義網路連線地址 val url = " ",因為地址不需要改變,所以可以設定為常量,如果需要變的話請用 var 定義變數 2,Kotlin
XML的三種解析方式與JSON解析方式
XML的三種原生解析方式 DOM,SAX,PULL DOM:記憶體消耗大 但是便於遍歷.開啟文件,將其轉化為節點樹,然後在其用迴圈的方式,遍歷節點,一一查詢. SAX:速度快,戰記憶體少.但是檔案結構資訊會丟失,採用的是流的處理方式.從起始標籤開始一一
網路請求與Fragment的使用
ackage com.ljn.myapplication.Utils; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android
requests進行網路請求與urllib2進行網路請求進行比較
同一臺計算機,同一個環境下,獲取LOL貼吧前二十頁內容,urllib2用時18.8280000687,而採用requests進行網路請求耗14.8680000305。綜上來講,選用第三方的requests進行網路請求效率比較高。但是,依然不夠好,如果我們採用,多
使用OkHttp3網路請求的錯誤解析
使用OkHttp3網路請求時出現如下錯誤: 12-26 17:27:24.942: E/AndroidRuntime(12089): FATAL EXCEPTION: OkHttp Dispatcher 12-26 17:27:24.942: E/AndroidRunti
android http post 請求與 json字串
List<Entry> items = new ArrayList<Entry>(); // 從response中讀取所有字元格式的返回值 String entityString = EntityUtils.toString(resp
Flutter -------- 網路請求之HttpClient
今天來說說Flutter中的網路請求,HttpClient網路請求,包含get,post get var d
爬蟲記(一) - 傳送網路請求,解析JSON與靜態HTML
1.傳送網路請求 import requests r = requests.Session() headers = {'user-agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:59.0) Gecko/20100101