d2admin 请求成功走的catch_Flutter 网络请求 & JSON 解析

fd05a3980f98ee404f67b65aa9110642.png

使用 Dio 请求数据,json_serializable 解析 json 数据

可以创建 flutter 项目,也可以创建 dart 项目。因为只是数据解析,不需要用到 flutter 视图组件。

添加 Dio 依赖 https://pub.flutter-io.cn/packages/dio

name: dartlearn # 项目名字
version: 0.0.1
description: A sample command-line application for dart
dependencies:
  dio: ^3.0.9 # dio 依赖
  #flutter packages pub run build_runner build
  json_annotation: ^3.0.1 # json 解析依赖

dev_dependencies:
  build_runner: ^1.0.0 # json 解析依赖
  json_serializable: ^3.2.5 # json 解析依赖

创建 simple_demo.dart

请求 https://api.apiopen.top/getJoke?page=1&count=2&type=video 接口

4b61c9dd0d73ff4df4601c9dd9418f30.png
import 'package:dio/dio.dart';

main(List<String> args) async {
  try {
    const url = "https://api.apiopen.top/getJoke?page=1&count=2&type=video";
    Dio dio = Dio();
    Response response = await dio.get(url);
    print(response);
  } catch (e) {
    print(e);
  }
}

运行 dart 文件 输出

1a12525bf8ae31bf74cde2bcfc7a6017.png

使用 dio 请求 springboot 接口,获取令牌;不清楚的可以看下。

江景:SpringBoot OAuth2.0 封装登录、刷新令牌接口​zhuanlan.zhihu.com
0054db2fbc44b10eae4dd884fd16c37c.png

POST 请求 localhost:7000/api/v1/account/login

main(List<String> args) async {
  try {
    // const url = "https://api.apiopen.top/getJoke?page=1&count=2&type=video";
    // const url = 'https://api.apiopen.top/videoCategory';
    Dio dio = Dio();
    final String loginUrl = "http://localhost:7000/api/v1/account/login";
    Map<String, dynamic> params = Map();
    params["accountName"] = "李白";
    params["password"] = "123456";
    params["loginType"] = "password";
    Response response = await dio.post(loginUrl, queryParameters: params);
    print(response);
  } catch (e) {
    print(e);
  }
}

37dbf62fe87804084d0dd3ea3ccde947.png

携带 access token 获取用户信息

main(List<String> args) async {
  try {
    Dio dio = Dio();

    // final String loginUrl = "http://localhost:7000/api/v1/account/login";
    // Map<String, dynamic> params = Map();
    // params["accountName"] = "李白";
    // params["password"] = "123456";
    // params["loginType"] = "password";
    // Response response = await dio.post(loginUrl, queryParameters: params);
    // print(response);

    final String info_url = "http://localhost:7000/api/v1/user/info";
    dio.post(info_url, queryParameters: {
      "access_token": 'ade59299-5833-496b-b5ab-42a8e3a84af1'
    }).then((response) {
      AccountInfo accountInfo = AccountInfo.fromJson(response.data);
      print(accountInfo.data.toJson());
    });
  } catch (e) {
    print(e);
  }
}

32cec16eebf58da8c83d55e809042165.png

在通常情况下服务端返回的数据格式都是有规则的,例如请求的 请求 https://api.apiopen.top/getJoke?page=1&count=2&type=video 接口

返回数据格式,可以封装一个最外层数据模型, BaseResponse, 再根据 result 返回的具体结果进行模型解析

{
    code: 200,
    message: "成功!",
    result: {}
}

BaseResponse.dart

import 'package:json_annotation/json_annotation.dart';

part 'base_response.g.dart';

@JsonSerializable()
class BaseResponse {
  // 后台返回的错误码
  int code;

  // 返回的信息
  String message;

  BaseResponse(this.code, this.message);

  factory BaseResponse.fromJson(Map<String, dynamic> json) =>
      _$BaseResponseFromJson(json);

  Map<String, dynamic> toJson() => _$BaseResponseToJson(this);
}

数据返回数组,创建与之对应模型

JokeItemModel.dart

import 'package:json_annotation/json_annotation.dart';

part 'joke_item_model.g.dart';

@JsonSerializable()
class JokeItemModel {
  /**
   *  sid: "31577089",
   *  text: "孩子厉害 ",
   *  type: "video",
   *  thumbnail: "http://wimg.spriteapp.cn/picture/2020/1026/5f967bc4e7de2_wpd.jpg",
   *  video: "http://uvideo.spriteapp.cn/video/2020/1026/5f967bc4e7de2_wpd.mp4",
   *  images: null,
   *  up: "114",
   *  down: "3",
   *  forward: "0",
   *  comment: "6",
   *  uid: "23005857",
   *  name: "无情无义",
   *  header: "http://wimg.spriteapp.cn/profile/large/2020/02/09/5e3fc8f551f9a_mini.jpg",
   *  top_comments_content: "厉害不厉害不知道。反正比我强",
   *  top_comments_voiceuri: "",
   *  top_comments_uid: "11981984",
   *  top_comments_name: "不得姐用户",
   *  top_comments_header: "http://qzapp.qlogo.cn/qzapp/100336987/D2C67A061C37841FD39E2D6232DE9833/100",
   *  passtime: "2020-12-24 18:30:05"
   */
  String sid;
  String text;
  String type;
  String thumbnail;
  String video;
  String images;
  String up;
  String down;
  String forward;
  String comment;
  String uid;
  String name;
  String header;
  String top_comments_content;
  String top_comments_voiceuri;
  String top_comments_uid;
  String top_comments_name;
  String top_comments_header;
  String passtime;
  JokeItemModel(
    this.sid,
    this.text,
    this.type,
    this.thumbnail,
    this.video,
    this.images,
    this.up,
    this.down,
    this.forward,
    this.comment,
    this.uid,
    this.name,
    this.header,
    this.top_comments_content,
    this.top_comments_voiceuri,
    this.top_comments_uid,
    this.top_comments_name,
    this.top_comments_header,
  );

  factory JokeItemModel.fromJson(Map<String, dynamic> json) =>
      _$JokeItemModelFromJson(json);

  Map<String, dynamic> toJson() => _$JokeItemModelToJson(this);
}

解析返回 result 字段,可以创建最外层模型 JokeModel 继承 BaseResponse

JokeModel.dart

import 'package:json_annotation/json_annotation.dart';

import 'base_response.dart';
import 'joke_item_model.dart';

part 'joke_model.g.dart';

@JsonSerializable()
class JokeModel extends BaseResponse {
  List<JokeItemModel> result;

  JokeModel(int code, String message) : super(code, message) {
    this.result = result;
  }

  factory JokeModel.fromJson(Map<String, dynamic> json) =>
      _$JokeModelFromJson(json);

  Map<String, dynamic> toJson() => _$JokeModelToJson(this);
}

定义完所有模式之后,可以使用 build_runner 命令生成 json 解析模型

flutter packages pub run build_runner build

4c49e2ad545c1f1ad33ab31e008db149.png

e54916dedf2c62fe5e6b9fa7e2b039e2.png

解析数据

Response response = await dio.get(url);
JokeModel jokeModel = JokeModel.fromJson(response.data);
for (var item in jokeModel.result) {
    print(item.text);
}

9f8e8d8cda2554183024f6f2f37e868b.png

解析复杂一些数据

https://api.apiopen.top/videoCategory

ca9b8724023e1530661ab79586e7333d.png

定义模型

VideoResult.dart

import 'package:json_annotation/json_annotation.dart';

import 'base_response.dart';
import 'video_category.dart';

part 'video_result.g.dart';

@JsonSerializable()
class VideoResult extends BaseResponse {
  VideoCategory result;

  VideoResult(int code, String message, this.result) : super(code, message);

  factory VideoResult.fromJson(Map<String, dynamic> json) =>
      _$VideoResultFromJson(json);

  Map<String, dynamic> toJson() => _$VideoResultToJson(this);
}

返回的 result 为一个对象模型 需要注意

VideoCategory.dart

import 'package:dartlearn/src/json_demo/video_category_item.dart';
import 'package:json_annotation/json_annotation.dart';

part 'video_category.g.dart';

@JsonSerializable()
class VideoCategory {
  bool adExist;
  int total;
  String nextPageUrl;
  int count;
  List<VideoCategoryItem> itemList;

  VideoCategory(
      this.adExist, this.count, this.nextPageUrl, this.total, this.itemList);

  factory VideoCategory.fromJson(Map<String, dynamic> json) =>
      _$VideoCategoryFromJson(json);

  Map<String, dynamic> toJson() => _$VideoCategoryToJson(this);
}

itemList 字段返回集合类型,定义对象模型

VideoCategoryItem.dart

import 'package:dartlearn/src/json_demo/category_item.dart';
import 'package:json_annotation/json_annotation.dart';

part 'video_category_item.g.dart';

@JsonSerializable()
class VideoCategoryItem {
  int adIndex;
  dynamic tag;
  int id;
  String type;
  CategoryItem data;

  VideoCategoryItem(this.adIndex, this.tag, this.id, this.type);

  factory VideoCategoryItem.fromJson(Map<String, dynamic> json) =>
      _$VideoCategoryItemFromJson(json);

  Map<String, dynamic> toJson() => _$VideoCategoryItemToJson(this);
}

VideoCategoryItem data 为对象类型

CategoryItem.dart

import 'package:json_annotation/json_annotation.dart';
import 'package:dartlearn/src/json_demo/follow_item.dart';

part 'category_item.g.dart';

@JsonSerializable()
class CategoryItem {
  bool ifShowNotificationIcon;
  bool expert;
  String dataType;
  String icon;
  String actionUrl;
  String description;
  String title;
  int uid;
  String subTitle;
  String iconType;
  bool ifPgc;
  int id;
  String adTrack;
  FollowItem follow;

  CategoryItem(
      this.actionUrl,
      this.adTrack,
      this.dataType,
      this.description,
      this.expert,
      this.icon,
      this.iconType,
      this.id,
      this.ifPgc,
      this.ifShowNotificationIcon,
      this.subTitle,
      this.title,
      this.uid,
      this.follow);
  factory CategoryItem.fromJson(Map<String, dynamic> json) =>
      _$CategoryItemFromJson(json);

  Map<String, dynamic> toJson() => _$CategoryItemToJson(this);
}

follow 字段为一个对象

FollowItem.dart

import 'package:json_annotation/json_annotation.dart';

part 'follow_item.g.dart';

@JsonSerializable()
class FollowItem {
  int itemId;
  String itemType;
  bool followed;

  FollowItem(this.followed, this.itemId, this.itemType);

  factory FollowItem.fromJson(Map<String, dynamic> json) =>
      _$FollowItemFromJson(json);

  Map<String, dynamic> toJson() => _$FollowItemToJson(this);
}

执行 flutter packages pub run build_runner build,生成 *.g.dart 文件。

$XXXXToJson $XXXXFromJson 为 JsonSerializableGenerator 生成器生成的方法

使用

main(List<String> args) async {
  try {
    // const url = "https://api.apiopen.top/getJoke?page=1&count=2&type=video";
    const url = 'https://api.apiopen.top/videoCategory';
    Dio dio = Dio();
    Response response = await dio.get(url);
    VideoResult videoResult = VideoResult.fromJson(response.data);

    for (var item in videoResult.result.itemList) {
      print(item.data.description);
    }

  } catch (e) {
    print(e);
  }
}

41da96da80f50e14696596bbe9f6fb22.png

总结: 只要把接口返回的数据格式定义好,嵌套的数据格式是集合类型还是对象类型,都定义好,再通过 JsonSerializableGenerator 生成对应文件就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值