Flutter Foundation (11) Сетевой запрос (Dio) и анализ данных JSON

Flutter
Flutter Foundation (11) Сетевой запрос (Dio) и анализ данных JSON

Эта статья была впервые опубликована в публичном аккаунте «Лю Ваншу».

Серия «Начало работы с ReactNative»

Базовая серия флаттера

предисловие

В Android-разработке, если мы хотим запросить сеть, мы можем использовать HttpClent и HttpURLConnection, но обычно в проектах используются OkHttp и Retrofit. То же самое верно и во Flutter.Система предоставляет HttpClient, но в проектах обычно используются сторонние библиотеки, такие как http и Dio.Если вы хотите найти больше сторонних библиотек, вы можете найти то, что хотите, на pub.dartlang .org/библиотека. В этой статье в качестве примера используется Dio, а также представлены знания об анализе данных JSON.

1. Начало работы с Дио

DiO - мощный DART HTTP-заявитель, поддерживающий перехватчики, глобальную конфигурацию, FormData, отмену запроса, загрузку файлов, время ожидания и т. Д.

добавить зависимостиДобавьте зависимости в pubspec.yaml.

dependencies:
  dio: 2.1.7  

На официальном сайте приведен простой пример:

import 'package:dio/dio.dart';
void getHttp() async {
  try {
    Response response = await Dio().get("http://liuwangshu.com");
    print(response);
  } catch (e) {
    print(e);
  }
}

Если вы хотите отправить запрос GET:

Response response;
response=await dio.get("/test?id=3&name=liuwangshu")
print(response.data.toString());
// 请求参数也可以通过对象传递,上面的代码等同于:
response=await dio.get("/test",data:{"id":3,"name":"liuwangshu"})
print(response.data.toString());

Отправить POST-запрос:

response=await dio.post("/test",data:{"id":3,"name":"liuwangshu"})

Отправить данные формы:

FormData formData = new FormData.from({
    "name": "liuwangshu",
    "age": 18,
  });
response = await dio.post("/info", data: formData);

Также есть много примеров на github по адресу:GitHub.com/флаттер доение…

2. Пример доступа Dio к сети

import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var _ipAddress = 'Unknown';

  _getIPAddress() async {//1
    var url = 'https://httpbin.org/ip';
    Dio _dio = Dio();
    String result;
    try {
      var response = await _dio.get(url);//2
      if (response.statusCode == HttpStatus.ok) {
        var data= jsonDecode(response.toString());//3
        result = data['origin'];
      } else {
        result =
        'Error getting IP status ${response.statusCode}';
      }
    } catch (exception) {
      result =exception.toString();
    }
    if (!mounted) return;
    setState(() {
      _ipAddress = result;//4
    });
  }

  @override
  Widget build(BuildContext context) {
    var spacer = SizedBox(height: 10.0);
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.all(100.0),
        child: Column(
          children: <Widget>[
            Text('IP地址为:'),
            spacer,
            Text('$_ipAddress'),
            spacer,
           RaisedButton(
              onPressed: _getIPAddress,
              child: Text('请求网络'),
            ),
          ],
        ),
      ),
    );
  }
}

async и await — это ключевые слова, используемые языком Dart для поддержки асинхронного программирования.Ключевое слово async в аннотации 1 делает метод _getIPAddress асинхронным методом.Ключевое слово await в аннотации 2 можно использовать только в асинхронных методах, что делает аннотацию 2. Следующий код выполняется после возврата запроса на получение. Если код состояния, возвращенный сетевым запросом, равен 200, анализ Json выполняется в примечании 3, а результат присваивается переменной результата. Когда мы нажимаем кнопку в интерфейсе, вызывается метод _getIPAddress, и запрошенный результат присваивается _ipAddress в примечании 4 и отображается в текстовом виде. После успешного выполнения сетевого запроса эффект будет таким, как показано ниже.

ZwFBEq.png

3. Парсинг данных JSON

Здесь представлены три часто используемых метода анализа данных JSON.

3.1 Использование метода json.decode()

В примерах подраздела 2 используется метод json.decode(), нам нужно ввести библиотеку dart: convert. Метод JSON.decode() преобразует проанализированные данные карты строкового типа в структуру данных:Map<String, dynamic>, формат данных — объект[ключ]. Данные JOSN, возвращенные в приведенном выше примере:

{
  "origin": "111.193.7.70, 111.193.7.70"
}

Это хороший выбор для использования метода json.decode() для несложных данных JOSN, но данные JOSN в реальном проекте будут более сложными.Если вы используете object[key] каждый раз, когда вы извлекаете данные, это легко сделать ошибки.

3.2 Написание классов сущностей вручную

Используйте модель для сохранения данных и их сериализации. Мы можем создать новый ip.dart:

class Ip {
  String origin;

  Ip(this.origin);

  Ip.fromJson(Map<String, dynamic> json) : origin = json['origin'];

  Map<String, dynamic> toJson() => {
        "origin": origin,
      };
}

Затем измените main.dart:

import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'model/ip.dart';
...
class _MyHomePageState extends State<MyHomePage> {
  var _ipAddress = 'Unknown';
  _getIPAddress() async {
    var url = 'https://httpbin.org/ip';
    Dio _dio = Dio();
    String result;
    try {
      var response = await _dio.get(url);
      if (response.statusCode == HttpStatus.ok) {
        var data= jsonDecode(response.toString());
        var ip=Ip.fromJson(data);//1
        result = ip.origin;
      } 
    ...
  }
...
}

В примечании 1 объект ip можно получить через Ip.fromJson, чтобы можно было выполнить присвоение и другие операции.

3.3 Автоматическая генерация классов сущности

General Project JSON Data будет более многочисленными, каждый класс объекта повторения для записи шаблона кода, по-видимому, бессмысленно скучно, вы можете использовать некоторые инструменты для генерации классов сущности. Например, использование автоматически сгенерированных страниц:app.quicktype.io/. Преобразованный класс сущности показан ниже.

import 'dart:convert';

Ip ipFromJson(String str) => Ip.fromJson(json.decode(str));

String ipToJson(Ip data) => json.encode(data.toJson());

class Ip {
    String origin;

    Ip({
        this.origin,
    });

    factory Ip.fromJson(Map<String, dynamic> json) => new Ip(
        origin: json["origin"],
    );

    Map<String, dynamic> toJson() => {
        "origin": origin,
    };
}

Помимо создания веб-страниц, вы также можете использовать JSONFormat4Flutter с открытым исходным кодом:

использовать json_serializable
В дополнение к упомянутым выше инструментам также можно использовать json_serializable. json_serializable — это автоматический генератор исходного кода, который может легко генерировать классы сущностей JSON. Сначала добавьте следующие зависимости в pubspec.yaml:

dependencies:
  json_annotation: ^2.4.0

dev_dependencies:
  build_runner: ^1.0.0
  json_serializable: ^3.0.0
 

Запустите команду получения пакетов flutter в AS Terminal, чтобы использовать эти новые зависимости в проекте. Затем реализуйте класс сущности ip.

import 'package:json_annotation/json_annotation.dart';

// ip.g.dart 将在我们运行生成命令后自动生成
part 'ip.g.dart';

//告诉生成器,这个类需要生成Model类
@JsonSerializable()
class Ip{
  Ip(this.origin);

  String origin;

  factory Ip.fromJson(Map<String, dynamic> json) => _$IpFromJson(json);
  Map<String, dynamic> toJson() => _$IpToJson(this);
}

Ключом является @JsonSerializable(), который используется, чтобы сообщить генератору, что класс Ip является классом Model, который необходимо сгенерировать. Выполните следующую команду в окне терминала, чтобы сгенерировать файл ip.g.dart.

flutter packages pub run build_runner build

См. раздел 3.2 о том, как его использовать. Использование json_serializable позволяет нам игнорировать любую ручную сериализацию JSON в классе Ip. Генератор исходного кода сгенерирует Ip.g.dart в том же каталоге, как показано ниже.

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'ip.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Ip _$IpFromJson(Map<String, dynamic> json) {
  return Ip(json['origin'] as String);
}

Map<String, dynamic> _$IpToJson(Ip instance) =>
    <String, dynamic>{'origin': instance.origin};

Этот файл имеет необходимую логику сериализации, а официальная рекомендация трепетания является использование json_serializable.

Базовая серия флаттера
Фундамент Flutter (1) Эволюция кроссплатформенных технологий мобильной разработки
Фундамент Flutter (2) Создание среды разработки Flutter и Hello World
Flutter Foundation (3) Быстрый старт в дартс
Основы Flutter (4) Основные виджеты, которые необходимо освоить перед разработкой приложений Flutter.
Flutter Foundation (5) MaterialApp, Scaffold, AppBar компонентов материалов
Flutter Foundation (6) BottomNavigationBar, TabBar, Drawer of Material Components
Flutter Foundation (7) ListView, GridView, PageView виджета прокрутки
Flutter Foundation (8) Виджеты, связанные с жестами: GestureDetector и Dismissible
Основы Flutter (9) ресурсы и изображения
Основы Flutter (10) Быстрый запуск виджета Layout
Flutter Foundation (11) Сетевой запрос (Dio) и анализ данных JSON
Flutter Foundation (12) Маршрутизация (переход на страницу) и передача данных
Flutter Foundation (13) Взаимодействие между Flutter и Android


Здесь не только делятся большим фронтендом, Android, Java и другими технологиями, но и статьи о росте программиста.