flutter json_serializable數據模型的建立和封裝


為了方便數據使用,我們將服務器拿到的數據轉換為map類型,但是在使用是大量的數據會讓使用map時頭大,比如每個map都key都需要手動輸入,很是麻煩。

本文使用了json_serializable將map數據轉換為類類型,創建我們自己的實體類。使用時,將轉換的對象(點)屬性就可以了,方便許多。

下文將模型轉換進行了封裝,包括單個模型以及List嵌套模型,創建BaseEntity泛型模型。

 

使用:

  在配置文件中添加json_serializable包。

dependencies:
  flutter:
    sdk: flutter

    json_serializable: ^3.5.1 #json序列化

       在配置文件中添加

dev_dependencies:
  flutter_test:
    sdk: flutter
  integration_test:
    sdk: flutter

  build_runner: ^1.11.0 #用於生成g文件

 

在以往的配置中需要配置json_annotation類庫,但是我發現在最新的json_serializable庫中已經存在json_annotation庫,可能是已經集成進去了,所以咱們就不寫了。

首先准備json數據,我使用的是fastmock在線接口平台,可以寫測試數據,挺方便。

例如數據為:

 {
    "userImg":"https://img2.woyaogexing.com/2021/01/23/0e945e70341f4626b2f4a7c48991ea9e!400x400.jpeg",
    "nickName":"靜怡學姐",
    "date":"2013-5-12",
    "tuijieContent":"為你推薦·19542人已關注ta·獲得35124贊同",
    "isGuanzhu":false,
    "title":"毛孔粗大之后真的不可逆嗎?",
    "content":"可逆!可逆!可逆!重要的事情說三遍!如果你看完還不清楚自己什么毛孔,可以發私信問我哦,科可以想我付費咨詢,記得帶自己的簡歷哦",
    "zanCount":1231,
    "pinglunCount":55252,
    "contentImg":"http://pic.5tu.cn/uploads/allimg/201003/010P0000109240-1.jpg"
  }

然后使用這個牛逼工具。將json數據轉換為dart實體類數據。點我點我

 

 

 將json代碼拷貝到左邊,右邊寫上實體類名稱,下方紅色字體為實體類對應的文件名,全小寫格式。

 

 

 復制生成的代碼到創建的.dart文件當中,此時程序就報錯,找不到

 

 

 這個文件。這是需要用到剛才帶入的類庫build_runner中的文件生成命令。

 執行build_runner命令

 Terminal運行:flutter packages pub run build_runner build,自動生成g.dart
在工程的Terminal下運行代碼: 這是一個實時監控bean中類型變化的。主要依賴庫build_runner.

這樣文件生成完成。

使用

 

 

 這樣就可以正常使用了。

 

封裝:

如果你這樣做了,開發過程中你會發現一個頭疼的問題。json轉list集合問題。

我們上面用的是單獨一個json對象的列子。所以不存在集合,那么接下來我要准備一個集合代碼。

 

List   Json數據。

{
  "code":1,
  "msg":"成功",
  "data":[
  {
    "userImg":"https://img2.woyaogexing.com/2021/01/23/0e945e70341f4626b2f4a7c48991ea9e!400x400.jpeg",
    "nickName":"靜怡學姐",
    "date":"2013-5-12",
    "tuijieContent":"為你推薦·19542人已關注ta·獲得35124贊同",
    "isGuanzhu":false,
    "title":"毛孔粗大之后真的不可逆嗎?",
    "content":"可逆!可逆!可逆!重要的事情說三遍!如果你看完還不清楚自己什么毛孔,可以發私信問我哦,科可以想我付費咨詢,記得帶自己的簡歷哦",
    "zanCount":1231,
    "pinglunCount":55252,
    "contentImg":"http://pic.5tu.cn/uploads/allimg/201003/010P0000109240-1.jpg"
  },
  {
    "userImg":"https://img2.woyaogexing.com/2021/01/23/a8fba61a2ff840ac8722d80b57c74cbc!400x400.jpeg",
    "nickName":"靜怡學姐",
    "date":"2013-5-12",
    "tuijieContent":"為你推薦·19542人已關注ta·獲得35124贊同",
    "isGuanzhu":false,
    "title":"毛孔粗大之后真的不可逆嗎?",
    "content":"可逆!可逆!可逆!重要的事情說三遍!如果你看完還不清楚自己什么毛孔,可以發私信問我哦,科可以想我付費咨詢,記得帶自己的簡歷哦",
    "zanCount":1231,
    "pinglunCount":55252,
    "contentImg":"http://pic.5tu.cn/uploads/allimg/201407/010P000040I52Q011-1.jpg"
  }
]
}

同樣,用工具吧這個代碼拷貝進去自己生成。

還是用這個工具點我點我

得到以下代碼:

import 'package:json_annotation/json_annotation.dart'; 
  
part 'attention_entity.g.dart';


@JsonSerializable()
  class AttentionEntity extends Object {

  @JsonKey(name: 'code')
  int code;

  @JsonKey(name: 'msg')
  String msg;

  @JsonKey(name: 'data')
  List<Data> data;

  AttentionEntity(this.code,this.msg,this.data,);

  factory AttentionEntity.fromJson(Map<String, dynamic> srcJson) => _$AttentionEntityFromJson(srcJson);

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

}

  
@JsonSerializable()
  class Data extends Object {

  @JsonKey(name: 'userImg')
  String userImg;

  @JsonKey(name: 'nickName')
  String nickName;

  @JsonKey(name: 'date')
  String date;

  @JsonKey(name: 'tuijieContent')
  String tuijieContent;

  @JsonKey(name: 'isGuanzhu')
  bool isGuanzhu;

  @JsonKey(name: 'title')
  String title;

  @JsonKey(name: 'content')
  String content;

  @JsonKey(name: 'zanCount')
  int zanCount;

  @JsonKey(name: 'pinglunCount')
  int pinglunCount;

  @JsonKey(name: 'contentImg')
  String contentImg;

  Data(this.userImg,this.nickName,this.date,this.tuijieContent,this.isGuanzhu,this.title,this.content,this.zanCount,this.pinglunCount,this.contentImg,);

  factory Data.fromJson(Map<String, dynamic> srcJson) => _$DataFromJson(srcJson);

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

}

可以看到,代碼生成了兩個類,一個是我們定義的最外層的實例,一個是我們data數據集合的實例。

使用方式:

_getData(){
    ApplicationDioUtils.dioUtil.get(UrlKit.getGuanzhuList,success: (data){
      AttentionEntity attentionEntity = AttentionEntity.fromJson(data);
     
      print(baseEntity.data[0].title);
    },error: (code,message){

    });
  }

我們得到了集合數據。完美。。~·~

but,這不是我想要的,一般來說我們的json數據都是以這樣的方式傳輸給客戶端。

{
  "code":1,
  "msg":"成功",
  "data":{}
}

如果做一個外層實例化,那么也就不用每個實體類中都有這些重復字段了。

先這樣。再那樣,然后這樣。

手動個創建一個baseEntity。內容是這樣的

import 'package:flutter_zhihu/models/attention_entity.dart';
import 'package:json_annotation/json_annotation.dart';

part 'base_entity.g.dart';


@JsonSerializable(createToJson: false)
class BaseEntity<T>{

  @JsonKey(name: 'code')
  int code;

  @JsonKey(name: 'msg')
  String msg;

  @JsonKey(fromJson: _dataFromJson)
  T data;

  BaseEntity(this.code,this.msg,this.data,);

  factory BaseEntity.fromJson(Map<String, dynamic> srcJson) => _$BaseEntityFromJson(srcJson);

  static T _dataFromJson<T>(Object json) {
  //判斷json數據是否是map類型 if (json is Map
<String, dynamic>) {
    //這里是判斷傳入的泛型是那個Entity。由於本人沒有找到更順眼的判斷方法,只能獲取傳入泛型的字符串和實體類字符串是否一樣來判斷了,如果有更好的方式記得告訴我。 if(T.toString() == 'AttentionEntity'){ AttentionEntity.fromJson(json) as T; }
    //創建一個entity實例,記得在這里寫一個 } else if (json is List) {
    //判斷json數據是否是list集合 if(T.toString() == 'List
<AttentionEntity>'){ return json.map((e) => AttentionEntity.fromJson(e as Map<String,dynamic>)).toList() as T; }
    //創建一個entity實例,記得在這里寫一個
}
  //陰陽json,直接一個報錯。 throw ArgumentError.value( json, 'json', 'Cannot convert the provided data.', ); } }

好了 ,很簡單,baseEntity完成。這下創建實體類的時候,我們只復制data中的json就行了。

開始使用:

  _getData(){
    ApplicationDioUtils.dioUtil.get(UrlKit.getGuanzhuList,success: (data){
    //此data已經經過json.decode(response.data)轉換了.
BaseEntity<List<AttentionEntity>> baseEntity = BaseEntity.fromJson(data);
BaseEntity<AttentionEntity> baseEntity1 = BaseEntity.fromJson(data); 
print(baseEntity.data[0].title); },error: (code,message){ });

}

搞定。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM