使用 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 接口
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 文件 输出
使用 dio 请求 springboot 接口,获取令牌;不清楚的可以看下。
江景:SpringBoot OAuth2.0 封装登录、刷新令牌接口zhuanlan.zhihu.comPOST 请求 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);
}
}
携带 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);
}
}
在通常情况下服务端返回的数据格式都是有规则的,例如请求的 请求 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
解析数据
Response response = await dio.get(url);
JokeModel jokeModel = JokeModel.fromJson(response.data);
for (var item in jokeModel.result) {
print(item.text);
}
解析复杂一些数据
https://api.apiopen.top/videoCategory
定义模型
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);
}
}
总结: 只要把接口返回的数据格式定义好,嵌套的数据格式是集合类型还是对象类型,都定义好,再通过 JsonSerializableGenerator 生成对应文件就可以了。