1. 程式人生 > >Flutter網路請求與JSON解析

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 GETPOSTPUTDELETE.

處理非同步

注意,HTTP API 在返回值中使用了Dart Futures。 我們建議使用async/await語法來呼叫API。

網路呼叫通常遵循如下步驟:

  1. 建立 client.
  2. 構造 Uri.
  3. 發起請求, 等待請求,同時您也可以配置請求headers、 body。
  4. 關閉請求, 等待響應.
  5. 解碼響應的內容.

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>,這意味著我們直到執行時才知道值的型別。 通過這種方法,我們失去了大部分靜態型別語言特性:型別安全、自動補全和最重要的編譯時異常。這樣一來,我們的程式碼可能會變得非常容易出錯。

例如,當我們訪問nameemail欄位時,我們輸入的很快,導致欄位名打錯了。但由於這個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