Harmony Next - JSON 解析

389 阅读4分钟

前言

在开发移动端 APP 项目时,只要 APP 涉及网络请求就免不了要开发者处理 JSON 字符串数据,将其解析成开发者自定义的模型。从而便于开发者展示数据。

在鸿蒙系统中,在 API12 之前,我们需要手动将 Map 中的数据映射到模型的字段上。在 API12 上,我们可以使用 ohos.util.json 系统库便捷的来进行数据转换了。

JSON 数据解析

假设我们有以下模型代表学生的数据:

class Student {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

学生的 JSON 字符串数据如下:

const stuJson =  '{"name": "John", "age": 30}';

仅需下面一行代码我们就可以将 JSON 字符串数据转为我们需要的 Student 模型数据,代码如下:

const stu = JSON.parse(stuJson) as Student;
console.log(stu.name, stu.age);//打印 John 30

需要注意的是,使用该框架需要提前导入,导入代码如下:

import { JSON } from '@kit.ArkTS';
parse 函数

在上面我们调用的 parse 函数只传入了一个 JSON 字符串参数,该函数实际可以支持传入三个参数。函数定义如下:

parse(text: string, reviver?: Transformer, options?: ParseOptions): Object | null
  • 第一个参数 text,接受 JSON 格式的字符串。
  • 第二个参数 reviver,接受一个 Transformer 类型的转换函数。在该函数里我们可以对数据进行一些统一处理,比如将字符串类型全部转为小写。
  • 第三个参数 options,接受一个 ParseOptions 类型的参数,用来处理 BigInt,共有以下三种类型:
    • DEFAULT:不支持BigInt。
    • PARSE_AS_BIGINT:当整数小于-(2^53-1)或大于(2^53-1)时,解析为BigInt。
    • ALWAYS_PARSE_AS_BIGINT:所有整数都解析为BigInt。

假设,我们现有 Teacher 模型如下:

class Teacher {
  name: string;
  teachId: BigInt;

  constructor(name: string, teachId: BigInt) {
    this.name = name;
    this.teachId = teachId;
  }
}

该模型共有两个字段,name 代表教师的名字,需要全部小写;teachID 代表教师的 ID,假设位数很长需要使用 BigInt 来解析。

JSON 字符串数据格式如下:

const jsonText =  '{"name": "John", "teachId": 90071992547409922}';

JSON 字符串解析代码如下:

const jsonText =  '{"name": "John", "teachId": 90071992547409922}';
const options: JSON.ParseOptions = {
  bigIntMode: JSON.BigIntMode.PARSE_AS_BIGINT,
}
const teacher = JSON.parse(jsonText, this.nameToLow, options) as Teacher;
console.log(teacher.name, teacher.teachId); //打印 john 90071992547409922n


// 该函数用于将 name 字段的值都变为小写。
nameToLow(key: string, value: Object): Object {
  if (key ==="name" && typeof value === "string") {
    return value.toLowerCase();
  }
  return value;
}

如果 options 的值我们传的是 DEFAULT,则 teachId 会被解析成 90071992547409920,这个值显然和 JSON 字符串中的数据是不符的。

模型转 JSON

在开发过程中,我们不仅仅需要将 JSON 数据转为模型数据以便开发者使用。我们还需要将模型数据转为 JSON 数据以便网络请求。

下面我们就来看一下如何将 Student 模型数据转为 JSON 字符串,示例代码如下:

const stu = new Student("Jack", 24);
const jsonStr = JSON.stringify(stu); // {"name":"Jack","age":24}

has 函数

JSON 解析的系统库中,还有 has(obj: object, property: string): boolean 函数,用来判断当前字符串是否包含某个 key。

比如下面的代码:

const jsonText =  '{"name": "John", "teachId": 90071992547409922}';
const teacher = JSON.parse(jsonText);
// 这行代码判断 teacher 对象是否包含名字为 name 的 key。
const rst = JSON.has(teacher, "name"); // true

Tips:has接口仅支持最外层为字典形式,内部嵌套的字典形式或者外层为数组的形式是无法判断的。比如下面的代码:

const jsonText =  '{"name": "John", "teachId": 90071992547409922, "student": {"age": 10}}';
const teacher = JSON.parse(jsonText);
const rst = JSON.has(teacher, "age"); // false

remove 函数

remove(obj: object, property: string): void 该函数用于删除某个 key,用法和 has 类似,限制也是一样的,内部嵌套的字典形式或者外层为数组的形式是无法用的。

const jsonText =  '{"name": "John", "teachId": 90071992547409922}';
const teacher = JSON.parse(jsonText);
JSON.remove(teacher, "name"); // 执行完这一行,teacher 只包含 teachId 字段。