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

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

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

  1. name: dartlearn # 项目名字
  2. version: 0.0.1
  3. description: A sample command-line application for dart
  4. dependencies:
  5. dio: ^3.0.9 # dio 依赖
  6. #flutter packages pub run build_runner build
  7. json_annotation: ^3.0.1 # json 解析依赖
  8. dev_dependencies:
  9. build_runner: ^1.0.0 # json 解析依赖
  10. json_serializable: ^3.2.5 # json 解析依赖

创建 simple_demo.dart

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

Flutter 网络请求 & JSON 解析 - 图1

  1. import 'package:dio/dio.dart';
  2. main(List<String> args) async {
  3. try {
  4. const url = "https://api.apiopen.top/getJoke?page=1&count=2&type=video";
  5. Dio dio = Dio();
  6. Response response = await dio.get(url);
  7. print(response);
  8. } catch (e) {
  9. print(e);
  10. }
  11. }

运行 dart 文件 输出

Flutter 网络请求 & JSON 解析 - 图2

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

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

Flutter 网络请求 & JSON 解析 - 图3

携带 access token 获取用户信息

  1. main(List<String> args) async {
  2. try {
  3. // const url = "https://api.apiopen.top/getJoke?page=1&count=2&type=video";
  4. // const url = 'https://api.apiopen.top/videoCategory';
  5. Dio dio = Dio();
  6. // Response response = await dio.get(url);
  7. // VideoResult videoResult = VideoResult.fromJson(response.data);
  8. // for (var item in videoResult.result.itemList) {
  9. // print(item.data.description);
  10. // }
  11. // final String loginUrl = "http://localhost:7000/api/v1/account/login";
  12. // Map<String, dynamic> params = Map();
  13. // params["accountName"] = "李白";
  14. // params["password"] = "123456";
  15. // params["loginType"] = "password";
  16. // Response response = await dio.post(loginUrl, queryParameters: params);
  17. // print(response);
  18. final String info_url = "http://localhost:7000/api/v1/user/info";
  19. dio.post(info_url, queryParameters: {
  20. "access_token": 'ade59299-5833-496b-b5ab-42a8e3a84af1'
  21. }).then((response) {
  22. AccountInfo accountInfo = AccountInfo.fromJson(response.data);
  23. print(accountInfo.data.toJson());
  24. });
  25. } catch (e) {
  26. print(e);
  27. }
  28. }

Flutter 网络请求 & JSON 解析 - 图4

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

  1. {
  2. code: 200,
  3. message: "成功!",
  4. result: {}
  5. }

BaseResponse.dart

  1. import 'package:json_annotation/json_annotation.dart';
  2. part 'base_response.g.dart';
  3. @JsonSerializable()
  4. class BaseResponse {
  5. // 后台返回的错误码
  6. int code;
  7. // 返回的信息
  8. String message;
  9. BaseResponse(this.code, this.message);
  10. factory BaseResponse.fromJson(Map<String, dynamic> json) =>
  11. _$BaseResponseFromJson(json);
  12. Map<String, dynamic> toJson() => _$BaseResponseToJson(this);
  13. }

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

JokeItemModel.dart

  1. import 'package:json_annotation/json_annotation.dart';
  2. part 'joke_item_model.g.dart';
  3. @JsonSerializable()
  4. class JokeItemModel {
  5. /**
  6. * sid: "31577089",
  7. * text: "孩子厉害👍",
  8. * type: "video",
  9. * thumbnail: "http://wimg.spriteapp.cn/picture/2020/1026/5f967bc4e7de2_wpd.jpg",
  10. * video: "http://uvideo.spriteapp.cn/video/2020/1026/5f967bc4e7de2_wpd.mp4",
  11. * images: null,
  12. * up: "114",
  13. * down: "3",
  14. * forward: "0",
  15. * comment: "6",
  16. * uid: "23005857",
  17. * name: "无情无义",
  18. * header: "http://wimg.spriteapp.cn/profile/large/2020/02/09/5e3fc8f551f9a_mini.jpg",
  19. * top_comments_content: "厉害不厉害不知道。反正比我强",
  20. * top_comments_voiceuri: "",
  21. * top_comments_uid: "11981984",
  22. * top_comments_name: "不得姐用户",
  23. * top_comments_header: "http://qzapp.qlogo.cn/qzapp/100336987/D2C67A061C37841FD39E2D6232DE9833/100",
  24. * passtime: "2020-12-24 18:30:05"
  25. */
  26. String sid;
  27. String text;
  28. String type;
  29. String thumbnail;
  30. String video;
  31. String images;
  32. String up;
  33. String down;
  34. String forward;
  35. String comment;
  36. String uid;
  37. String name;
  38. String header;
  39. String top_comments_content;
  40. String top_comments_voiceuri;
  41. String top_comments_uid;
  42. String top_comments_name;
  43. String top_comments_header;
  44. String passtime;
  45. JokeItemModel(
  46. this.sid,
  47. this.text,
  48. this.type,
  49. this.thumbnail,
  50. this.video,
  51. this.images,
  52. this.up,
  53. this.down,
  54. this.forward,
  55. this.comment,
  56. this.uid,
  57. this.name,
  58. this.header,
  59. this.top_comments_content,
  60. this.top_comments_voiceuri,
  61. this.top_comments_uid,
  62. this.top_comments_name,
  63. this.top_comments_header,
  64. );
  65. factory JokeItemModel.fromJson(Map<String, dynamic> json) =>
  66. _$JokeItemModelFromJson(json);
  67. Map<String, dynamic> toJson() => _$JokeItemModelToJson(this);
  68. }

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

JokeModel.dart

  1. import 'package:json_annotation/json_annotation.dart';
  2. import 'base_response.dart';
  3. import 'joke_item_model.dart';
  4. part 'joke_model.g.dart';
  5. @JsonSerializable()
  6. class JokeModel extends BaseResponse {
  7. List<JokeItemModel> result;
  8. JokeModel(int code, String message) : super(code, message) {
  9. this.result = result;
  10. }
  11. factory JokeModel.fromJson(Map<String, dynamic> json) =>
  12. _$JokeModelFromJson(json);
  13. Map<String, dynamic> toJson() => _$JokeModelToJson(this);
  14. }

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

flutter packages pub run build_runner build

Flutter 网络请求 & JSON 解析 - 图5

Flutter 网络请求 & JSON 解析 - 图6

解析数据

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

Flutter 网络请求 & JSON 解析 - 图7

解析复杂一些数据

https://api.apiopen.top/videoCategory

Flutter 网络请求 & JSON 解析 - 图8

定义模型

VideoResult.dart

  1. import 'package:json_annotation/json_annotation.dart';
  2. import 'base_response.dart';
  3. import 'video_category.dart';
  4. part 'video_result.g.dart';
  5. @JsonSerializable()
  6. class VideoResult extends BaseResponse {
  7. VideoCategory result;
  8. VideoResult(int code, String message, this.result) : super(code, message);
  9. factory VideoResult.fromJson(Map<String, dynamic> json) =>
  10. _$VideoResultFromJson(json);
  11. Map<String, dynamic> toJson() => _$VideoResultToJson(this);
  12. }

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

VideoCategory.dart

  1. import 'package:dartlearn/src/json_demo/video_category_item.dart';
  2. import 'package:json_annotation/json_annotation.dart';
  3. part 'video_category.g.dart';
  4. @JsonSerializable()
  5. class VideoCategory {
  6. bool adExist;
  7. int total;
  8. String nextPageUrl;
  9. int count;
  10. List<VideoCategoryItem> itemList;
  11. VideoCategory(
  12. this.adExist, this.count, this.nextPageUrl, this.total, this.itemList);
  13. factory VideoCategory.fromJson(Map<String, dynamic> json) =>
  14. _$VideoCategoryFromJson(json);
  15. Map<String, dynamic> toJson() => _$VideoCategoryToJson(this);
  16. }

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

VideoCategoryItem.dart

  1. import 'package:dartlearn/src/json_demo/category_item.dart';
  2. import 'package:json_annotation/json_annotation.dart';
  3. part 'video_category_item.g.dart';
  4. @JsonSerializable()
  5. class VideoCategoryItem {
  6. int adIndex;
  7. dynamic tag;
  8. int id;
  9. String type;
  10. CategoryItem data;
  11. VideoCategoryItem(this.adIndex, this.tag, this.id, this.type);
  12. factory VideoCategoryItem.fromJson(Map<String, dynamic> json) =>
  13. _$VideoCategoryItemFromJson(json);
  14. Map<String, dynamic> toJson() => _$VideoCategoryItemToJson(this);
  15. }

VideoCategoryItem data 为对象类型

CategoryItem.dart

  1. import 'package:json_annotation/json_annotation.dart';
  2. import 'package:dartlearn/src/json_demo/follow_item.dart';
  3. part 'category_item.g.dart';
  4. @JsonSerializable()
  5. class CategoryItem {
  6. bool ifShowNotificationIcon;
  7. bool expert;
  8. String dataType;
  9. String icon;
  10. String actionUrl;
  11. String description;
  12. String title;
  13. int uid;
  14. String subTitle;
  15. String iconType;
  16. bool ifPgc;
  17. int id;
  18. String adTrack;
  19. FollowItem follow;
  20. CategoryItem(
  21. this.actionUrl,
  22. this.adTrack,
  23. this.dataType,
  24. this.description,
  25. this.expert,
  26. this.icon,
  27. this.iconType,
  28. this.id,
  29. this.ifPgc,
  30. this.ifShowNotificationIcon,
  31. this.subTitle,
  32. this.title,
  33. this.uid,
  34. this.follow);
  35. factory CategoryItem.fromJson(Map<String, dynamic> json) =>
  36. _$CategoryItemFromJson(json);
  37. Map<String, dynamic> toJson() => _$CategoryItemToJson(this);
  38. }

follow 字段为一个对象

FollowItem.dart

  1. import 'package:json_annotation/json_annotation.dart';
  2. part 'follow_item.g.dart';
  3. @JsonSerializable()
  4. class FollowItem {
  5. int itemId;
  6. String itemType;
  7. bool followed;
  8. FollowItem(this.followed, this.itemId, this.itemType);
  9. factory FollowItem.fromJson(Map<String, dynamic> json) =>
  10. _$FollowItemFromJson(json);
  11. Map<String, dynamic> toJson() => _$FollowItemToJson(this);
  12. }

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

![](https://g.yuque.com/gr/latex?XXXXToJson%20%20#card=math&code=XXXXToJson%20%20_)XXXXFromJson 为 JsonSerializableGenerator 生成器生成的方法

使用

  1. main(List<String> args) async {
  2. try {
  3. // const url = "https://api.apiopen.top/getJoke?page=1&count=2&type=video";
  4. const url = 'https://api.apiopen.top/videoCategory';
  5. Dio dio = Dio();
  6. Response response = await dio.get(url);
  7. VideoResult videoResult = VideoResult.fromJson(response.data);
  8. for (var item in videoResult.result.itemList) {
  9. print(item.data.description);
  10. }
  11. } catch (e) {
  12. print(e);
  13. }
  14. }

Flutter 网络请求 & JSON 解析 - 图9