flutter json解析增強

依賴:xxf_json

反序列化兼容特征一覽表

類型\是否兼容

int

double

num

string

bool

int

yes

yes

yes

yes

yes

double

yes

yes

yes

yes

yes

num

yes

yes

yes

yes

yes

string

yes

yes

yes

yes

yes

bool

yes

yes

yes

yes

yes

專業詞語

.g.dart : 是json_annotation生成的中間解析文件

DTO : 網絡傳輸模型,這里泛指json解析模型

中間件

對json提供如下基礎中間件,兩種兼容模式,一種給全日志

  1. JsonConverter 兼容基本類型(int,num,double,string,bool),異常情況解析成對應類型的默認值,達到同級別js,oc等語言層兼容

  2. nullable_converter 兼容基本類型(int,num,double,string,bool),異常情況解析成null,需要DTO聲明字段為可空類型

  3. strict_converter 先兼容解析,解析不了再報錯,解決json解析報錯,不提示具體內容,導致一個一個去比較DTO里聲明的字段,或者打印stack才可以排查具體字段

至于要使用多少類型兼容和什么策略,請自己選,上圖只是模版

用法

  1. DTO層增加注解 通過 @JsonSerializable 注解參數converters 注入!

其中 primitiveConvertors :基本類型解析器,安全處理,如遇到失敗會轉換成默認值 primitiveNullableConvertors:基本類型解析器,安全處理,如遇到失敗變成null,適合聲明可空類型的字段

primitiveStrictConvertors:基本類型解析器,不安全處理,用于提示內容,比原錯誤始信息增加 內容本身到日志里面,解決原始報錯,不提示具體內容,不好分析DTO的那個字段

用法代碼示例:

@JsonSerializable(converters: [...primitiveNullableConvertors, RRuleJsonAdapter()])
class Event{
}

  1. 字段級別增加注解

通過 @JsonKey fromJson 注解增加參數

用法代碼示例:

@JsonSerializable()
class Event  {//類型不對,就解析成""雙引號字符串@JsonKey(fromJson: StringDecoder.decodeOrEmpty)String? eventId; //設備內日程id
}

提供更自由的控制,每種類型都提供三種策略

bool_decoder.dart

double_decoder.dart

int_decoder.dart

num_decoder.dart

string_decoder.dart

class StringDecoder {///策略1 異常情況解析為空static String? decodeOrNull(dynamic json) {if (json == null) return null;return json.toString();}///策略2 異常情況解析默認值,比@JsonKey(defaultValue: "")更健壯static String decodeOrEmpty(dynamic value) {return decodeOrNull(value) ?? "";}///策略3 嘗試解析異常情況報錯并給出錯誤值static String decodeOrException(dynamic value) {return decodeOrNull(value) ??(throw BaseDecoder.createParseError("String", value));}
}

框架的中間件優先級是 @JsonKey(fromJson)>@JsonSerializable(converters)

推薦傾向

1. DTO里字段聲明成可空字段

給DTO增加可空兼容轉換器@JsonSerializable( converters: primitiveNullableConvertors),

具體字段的應用由業務層來處理兼容, 這樣不至于整個頁面出問題,個別字段的問題,交由service層/repo層來校驗參數,

eg.如在版本迭代中 枚舉的類型可能增加,但是之前版本代碼是沒有的,那么非空類型就出問題了

實在要堅持后端一定不會變,其他頁面傳進來的參數也不會變, 那么就選擇primitiveStrictConvertors或者decodeOrException 會嘗試解析之后再報錯出來!

規范

結合convertor和 fromJson,toJson Api 注入到DTO身上,不應該去手寫解析 手寫/或者手改.g.dart 合并代碼和以及兼容性都有些問題

枚舉的兼容

枚舉默認按名字,如按其他值解析,有如下三種方式 1. 在枚舉值上添加@JsonValue(value)

  1. 自定義jsonDecoder 這樣枚舉在其他DTO聲明的地方都可以快速適配,

  2. 在其他DTO 聲明枚舉的字段上增加注解 @JsonKey(fromJson: StatusConverter.fromJson, toJson: StatusConverter.toJson)

不要在其他DTO解析的地方(其他DTO有聲明這個枚舉類型字段) 來手寫if判斷!


/// 日歷賬號類型
enum CalDavTypeEnum {google("google"),iCloud("iCloud"),calDAV("CalDAV");final String value;const CalDavTypeEnum(this.value);
}/// 枚舉值和 JSON 數據的映射關系
Map<String, CalDavTypeEnum> _stringToEnum =CalDavTypeEnum.values.associateBy((e) => e.value);
Map<CalDavTypeEnum, String> _enumToString =CalDavTypeEnum.values.associate((e) => MapEntry(e, e.value));class CalDavTypeEnumDecoder {static CalDavTypeEnum decode(dynamic json) {return _stringToEnum["$json"] ??(throw ArgumentError('Unknown enum value: $json'));}static CalDavTypeEnum? decodeOrNull(dynamic json) {return _stringToEnum["$json"];}
}class CalDavTypeEnumEncoder {static String encode(CalDavTypeEnum? myEnum) {return _enumToString[myEnum] ??(throw ArgumentError('Unknown enum: $myEnum'));}static String? encodeOrNull(CalDavTypeEnum? myEnum) {return _enumToString[myEnum];}
}///解析轉換器
class CalDavTypeEnumJsonConverterextends JsonConverter<CalDavTypeEnum, dynamic> {const CalDavTypeEnumJsonConverter();@overrideCalDavTypeEnum fromJson(json) {return CalDavTypeEnumDecoder.decode(json);}@overridetoJson(CalDavTypeEnum object) {return CalDavTypeEnumEncoder.encode(object);}
}///解析轉換器 可空
class CalDavTypeEnumNullableJsonConverterextends JsonConverter<CalDavTypeEnum?, dynamic> {const CalDavTypeEnumNullableJsonConverter();@overrideCalDavTypeEnum? fromJson(json) {return CalDavTypeEnumDecoder.decodeOrNull(json);}@overridetoJson(CalDavTypeEnum? object) {return CalDavTypeEnumEncoder.encodeOrNull(object);}
}

json_annotation使用指引
?

  1. 模型增加 @JsonSerializable注解

  2. 在模型聲明文件頭部增加 part 'xxx.g.dart'; 其中xxx 一般是模型名字,當然也可以是其他名字

  3. 字段如有必要增加@JsonKey

  4. 在命令行 cd 到模型對應的目錄

  5. 在命令行執行 flutter pub run build_runner build

  6. 那么就能看到生成 xxx.g.dart文件的生成,將這個文件添加到git

  7. 然后再模型里面聲明方法引用

part 'account_xxx.g.dart';@JsonSerializable()
class AccountInfo {int? id;//聲明反序列化方法factory AccountInfo.fromJson(Map<String, dynamic> json) =>_$AccountInfoFromJson(json);///聲明序列化方法Map<String, dynamic> toJson() => _$AccountInfoToJson(this);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/902037.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/902037.shtml
英文地址,請注明出處:http://en.pswp.cn/news/902037.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Neo4j初解

Neo4j 是目前應用非常廣泛的一款高性能的 NoSQL 圖數據庫&#xff0c;其設計和實現專門用于存儲、查詢和遍歷由節點&#xff08;實體&#xff09;、關系&#xff08;邊&#xff09;以及屬性&#xff08;鍵值對&#xff09;構成的圖形數據模型。它的核心優勢在于能夠以一種自然且…

學習MySQL的第十天

一、MySQL的數據類型 1.MySQL的數據類型 2.常見的數據類型的屬性 二、整數類型 三、浮點類型 REAL默認就是DOUBLE。如果你把SQL模式設定為啟用“REAL_AS_FLOAT”,那么,MySQL就認為REAL是FLOAT。如果要啟用“REAL_AS_FLOAT”,可以通過以下SQL語句實現: SET sql_mode &…

ubuntu24.04上使用qemu+buildroot+uboot+linux+tftp+nfs模擬搭建vexpress-ca9嵌入式linux開發環境

1 準備工作 1.1 安裝依賴工具 sudo apt-get update && sudo apt-get install build-essential git bc flex libncurses5-dev libssl-dev device-tree-compiler1.2 安裝arm交叉編譯工具鏈 sudo apt install gcc-arm-linux-gnueabihf安裝之后&#xff0c;在終端輸入ar…

ubuntu 22.04 使用ssh-keygen創建ssh互信賬戶

現有兩臺ubuntu 22.04服務器&#xff0c;ip分別為192.168.66.88和192.168.88.66。需要將兩臺服務器創建新用戶并將新用戶做互信。 創建賬戶 adduser user1 # 如果此用戶不想使用密碼&#xff0c;直接一直回車就行&#xff0c;創建的用戶是沒法使用用戶密碼進行登陸的 su - …

【PCIE配置空間】

1 PCIE配置空間 1.1 軟件如何知道PCIE設備是Swith&#xff0c;RC還是EP&#xff1f; –軟件通過讀取寄存器信息。 PCIE配置空間? PCIE寄存器&#xff1b;--PCIE配置協議規定必須實現的空間。--PCIE存在兩種配置空間Type0/Type1;--Type0配置空間EP設備必須實現&#xff1b;-…

Android 熱點二維碼簡單示例

Android 熱點二維碼簡單示例 一、前言 Android 原生設置有熱點二維碼分享功能&#xff0c;有些系統應用也會有這個需求。 下面看看是如何實現的。 本文是一個比較簡單的內容。 二、熱點二維碼生成實現 1、效果 整個應用就一個普通的Activity&#xff0c;顯示一個按鈕和二維…

uv:重新定義Python開發效率的下一代工具鏈

在Python生態系統中&#xff0c;包管理和項目工具鏈的復雜性一直是開發者面臨的一大挑戰。從依賴管理、虛擬環境創建到多版本Python切換&#xff0c;傳統的工具鏈&#xff08;如pip、virtualenv、poetry等&#xff09;雖然功能強大&#xff0c;但操作繁瑣、性能不足的問題長期存…

T101D加固平板電腦:無人機地面站的高效智能控制核心

隨著無人機技術在應急救援、農業監測、軍事偵察等領域的廣泛應用&#xff0c;對地面控制設備的要求也日益提高。魯成偉業推出的T101D加固平板電腦憑借其高性能、強防護和專業化設計&#xff0c;成為無人機地面站的核心控制終端&#xff0c;為復雜環境下的作業提供了可靠支持。 …

Datawhale AI春訓營】AI + 新能源(發電功率預測)Task1

賽題鏈接 官網 新能源發電功率預測賽題進階方案 下面是ai給的一些建議 新能源發電功率預測賽題進階方案 一、時序特性深度挖掘 1. 多尺度周期特征 # 分鐘級周期編碼 train[15min_index] (train[hour]*4 train[minute]//15)# 周周期特征 train[weekday] pd.to_datetime…

山東科技大學深度學習考試回憶

目錄 一、填空&#xff08;五個空&#xff0c;十分&#xff09; 二、選擇題(五個&#xff0c;十分&#xff09; 三、判斷題&#xff08;五個&#xff0c;五分&#xff09; 四、論述題&#xff08;四個&#xff0c;四十分&#xff09; 五、計算題&#xff08;二個&#xff…

Redis線上操作最佳實踐有哪些?

大家好&#xff0c;我是鋒哥。今天分享關于【Redis線上操作最佳實踐有哪些?】面試題。希望對大家有幫助&#xff1b; Redis線上操作最佳實踐有哪些? 1000道 互聯網大廠Java工程師 精選面試題-Java資源分享網 在使用 Redis 時&#xff0c;尤其是在生產環境中&#xff0c;合理…

mac中的zip文件壓縮與壓縮文件中指定目錄刪除

問題 在使用mac的圖形界面壓縮文件后&#xff0c;往往那個壓縮文件中帶有__MACOSX文件&#xff0c;但是&#xff0c;這個文件夾又是我們不需要的目錄&#xff0c;所有&#xff0c;需要對mac圖形化界面壓縮后的文件目錄進行刪除&#xff0c;改如何做&#xff1f; 檢查壓縮文件…

【記錄】服務器用命令開啟端口號

這里記錄下如何在服務器上開啟適用于外界訪問的端口號。 方法 1 使用防火墻 1 su &#xff0c;命令 輸入密碼 切換到root節點 2 開啟防火墻 systemctl start firewalld3 配置開放端口 firewall-cmd --zonepublic --add-port8282/tcp --permanent4 重啟防火墻 firewall-cmd…

深度學習-torch,全連接神經網路

3. 數據集加載案例 通過一些數據集的加載案例&#xff0c;真正了解數據類及數據加載器。 3.1 加載csv數據集 代碼參考如下 import torch from torch.utils.data import Dataset, DataLoader import pandas as pd ? ? class MyCsvDataset(Dataset):def __init__(self, fil…

C++/Python實現RGB和HSI相互轉換

1--C版本 #include <opencv2/opencv.hpp> #include <iostream> #include <cmath>// RGB to HSI cv::Vec3f RGBtoHSI(cv::Vec3b rgb) {float B rgb[0] / 255.0f;float G rgb[1] / 255.0f;float R rgb[2] / 255.0f;float num 0.5f * ((R - G) (R - B));f…

【Linux我做主】make和makefile自動化構建

make和makefile自動化構建 make和makefile自動化構建github地址前言背景介紹為什么需要make和makefile&#xff1f; make和makefile解析什么是make和makefile依賴關系和依賴方法核心語法結構簡單演示編譯清理 多階段編譯示例 make時執行的順序場景1&#xff1a;clean目標在前(特…

Qt 入門 5 之其他窗口部件

Qt 入門 5 之其他窗口部件 本文介紹的窗口部件直接或間接繼承自 QWidget 類詳細介紹其他部件的功能與使用方法 1. QFrame 類 QFrame類是帶有邊框的部件的基類。它的子類包括最常用的標簽部件QLabel另外還有 QLCDNumber、QSplitter,QStackedWidget,QToolBox 和 QAbstractScrol…

JAVA學習-多線程

線程 線程(Thread)是一個程序內部的一條執行流程。 程序中如果只有一條執行流程&#xff0c;那這個程序就是單線程的程序。 線程的常用方法及構造器&#xff1a; Thread提供的常用方法public void run() 線程的任務方法public void start() 啟動線程public String getName() …

Github 2025-04-19Rust開源項目日報 Top10

根據Github Trendings的統計,今日(2025-04-19統計)共有10個項目上榜。根據開發語言中項目的數量,匯總情況如下: 開發語言項目數量Rust項目10Python項目1Rust: 構建可靠高效軟件的開源項目 創建周期:5064 天開發語言:Rust協議類型:OtherStar數量:92978 個Fork數量:12000…

OpenLayers:視圖變換的方法

一、什么是視圖變換&#xff1f; 視圖變換就是指視圖的 extent&#xff08;范圍&#xff09;、center&#xff08;中心點&#xff09;、zoom&#xff08;縮放級別&#xff09;、 resolution&#xff08;分辨率&#xff09;、rotation&#xff08;旋轉角&#xff09;等參數發生…