Flutter JSON类型定义插件json_typedef_dart的使用

Flutter JSON类型定义插件json_typedef_dart的使用

JSON Type Definition(简称JTD),即RFC 8927,是一种易于学习且标准化的方法来为JSON数据定义一个模式。您可以使用JSON Typedef在不同的编程语言之间便携地验证数据,生成虚拟数据,生成代码等。

本包是一个Dart/Flutter实现的JSON Type Definition。它允许您根据JSON Type Definition模式验证输入数据。

安装

您可以使用pub安装此包:

flutter pub add json_typedef_dart

基本用法

以下是如何使用此包验证JSON数据的例子:

import 'package:json_typedef_dart/json_typedef_dart.dart';

Json schema = <String, dynamic>{
   "properties": {
      "name": {"type": "string"},
      "age": {"type": "uint32"},
      "phones": {
         "elements": {"type": "string"}
      }
   }
};

void main() {
// validate返回一个包含验证错误的数组。如果输入数据没有问题,则返回空数组。

// 输出: []
   print(validate(schema: schema, data: {
      "name": "John Doe",
      "age": 43,
      "phones": ["+44 1234567", "+44 2345678"],
   }));

// 下一个输入有三个问题:
//
// 1. 缺少必需的属性"name"。
// 2. "age" 是字符串,但应该是整数。
// 3. "phones[1]" 是数字,但应该是字符串。
//
// 每个错误都对应于validate返回的错误之一。

// 输出:
//
// [
//   { instancePath: [], schemaPath: [ 'properties', 'name' ] },
//   {
//     instancePath: [ 'age' ],
//     schemaPath: [ 'properties', 'age', 'type' ]
//   },
//   {
//     instancePath: [ 'phones', '1' ],
//     schemaPath: [ 'properties', 'phones', 'elements', 'type' ]
//   }
// ]
   print(validate(schema: schema, data: {
      "age": "43",
      "phones": ["+44 1234567", 442345678],
   }));
}

高级用法:限制返回的错误数量

默认情况下,validate会返回所有找到的错误。如果您只关心是否有任何错误,或者您不能显示超过一定数量的错误,则可以使用maxErrors选项提高validate的性能。

例如,以前面相同的例子为例,但将其限制为最多1个错误,我们得到:

import 'package:json_typedef_dart/json_typedef_dart.dart';

Json schema = <String, dynamic>{
   "properties": {
      "name": {"type": "string"},
      "age": {"type": "uint32"},
      "phones": {
         "elements": {"type": "string"}
      }
   }
};

void main() {
// 输出:
//
// [ { instancePath: [], schemaPath: [ 'properties', 'name' ] } ]
   print(validate(schema: schema, data: {
      "age": "43",
      "phones": ["+44 1234567", "+44 2345678"],
   }, maxErrors: 1));
}

高级用法:处理不受信任的模式

如果您想针对不受信任的模式运行validate,则应:

  1. 使用isValidSchema确保模式格式正确,这会验证诸如确保所有ref都有相应定义之类的事情。
  2. 使用maxDepth选项调用validate。JSON Typedef允许编写递归模式——如果您正在评估不受信任的模式,可能会在评估恶意输入时进入无限循环,例如:
   {
     "ref": "loop",
     "definitions": {
       "loop": {
         "ref": "loop"
       }
     }
   }

maxDepth选项告诉jtd.validate在放弃并抛出MaxDepthExceededError之前递归跟踪多少个ref

以下是如何使用jtd评估不受信任的模式下的数据的例子:

import 'package:json_typedef_dart/json_typedef_dart.dart';

// validateUntrusted 返回true,如果`data`满足`schema`,否则返回false。如果`schema`无效或验证陷入无限循环,则抛出错误。
bool validateUntrusted(Json schema, dynamic data) {
   if (!isValidSchema(schema)) {
      throw Exception("invalid schema");
   }

// 您应该将maxDepth调整到足够高,以使大多数合法模式无需错误即可评估,但也要足够低,防止攻击者导致拒绝服务攻击。
   return validate(schema: schema, data: data, maxDepth: 32).isEmpty;
}

void main() {
// 输出: true
   print(validateUntrusted(<String, dynamic>{"type": "string"}, "foo"));

// 输出: false
   validateUntrusted(<String, dynamic>{"type": "string"}, null);

// 抛出 "invalid schema"
   try {
      validateUntrusted(<String, dynamic>{"type": "nonsense"}, null);
   } catch (e) {
      print(e);
   }
// 抛出 MaxDepthExceededError 的实例
   try {
      validateUntrusted(<String, dynamic>{
         "ref": "loop",
         "definitions": {
            "loop": {"ref": "loop"}
         }
      }, null);
   }
   catch(e){
      print(e);
   }
}

更多关于Flutter JSON类型定义插件json_typedef_dart的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter JSON类型定义插件json_typedef_dart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,json_typedef_dart 是一个帮助你在 Flutter 项目中定义和管理 JSON 数据结构的 Dart 插件。它允许你通过类型定义自动生成对应的 Dart 类,从而简化 JSON 解析和序列化的过程。

以下是一个使用 json_typedef_dart 插件的示例,展示如何定义 JSON 类型并生成相应的 Dart 类。

1. 安装插件

首先,你需要在 pubspec.yaml 文件中添加 json_typedef_dart 依赖:

dependencies:
  flutter:
    sdk: flutter
  json_typedef_dart: ^最新版本号  # 请替换为实际最新版本号

然后运行 flutter pub get 来获取依赖。

2. 定义 JSON 类型

创建一个文件,例如 json_types.dart,用于定义你的 JSON 类型。

import 'package:json_typedef_dart/json_typedef_dart.dart';

part 'json_types.g.dart';

@JsonTypeDef(
  'User',
  [
    JsonFieldDef('id', JsonType.int),
    JsonFieldDef('name', JsonType.string),
    JsonFieldDef('email', JsonType.string, isNullable: true),
    JsonFieldDef('age', JsonType.int, isNullable: true),
  ],
)
abstract class UserTypeDef {}

在这个例子中,我们定义了一个名为 User 的 JSON 类型,包含 idnameemailage 字段。

3. 生成 Dart 类

你需要运行一个构建脚本来生成对应的 Dart 类。通常,你可以使用 build_runner 来完成这个任务。

首先,添加 build_runner 到你的 dev_dependencies 中:

dev_dependencies:
  build_runner: ^最新版本号

然后,在项目根目录下运行以下命令来生成代码:

flutter pub run build_runner build

运行成功后,你应该会在项目目录下看到一个生成的 json_types.g.dart 文件,其中包含了 User 类的实现。

4. 使用生成的类

现在你可以在你的 Flutter 项目中使用生成的类了。例如,在 main.dart 文件中:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'json_types.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('JSON Type Def Example'),
        ),
        body: Center(
          child: UserExample(),
        ),
      ),
    );
  }
}

class UserExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 示例 JSON 数据
    String jsonData = '''
    {
      "id": 1,
      "name": "John Doe",
      "email": "john.doe@example.com",
      "age": 30
    }
    ''';

    // 解析 JSON 数据
    User user = User.fromJson(jsonDecode(jsonData));

    // 显示用户信息
    return Text('Name: ${user.name}, Email: ${user.email}, Age: ${user.age}');
  }
}

在这个例子中,我们解析了一个 JSON 字符串并将其转换为一个 User 对象,然后显示用户的信息。

总结

使用 json_typedef_dart 插件,你可以方便地定义 JSON 类型并自动生成对应的 Dart 类,从而简化 JSON 数据的管理和处理。希望这个示例能帮助你更好地理解和使用这个插件。

回到顶部