[Harmony]实现JSON与类的双向转换
使用reflect-metadata和class-transformer,实现JSON与类的双向转换。
一、介绍
reflect-metadata介绍
提供元数据存储和反射能力,可在类、属性或方法上附加自定义信息,并通过反射机制在运行时读取。
reflect-metadata关键修饰符:
1.@Reflect.metadata(key, value)
功能:为类/属性/方法附加元数据
参数:key:元数据标识符(字符串或Symbol) value:存储的任意类型数据
示例:
@Reflect.metadata('version', '1.0')
class MyClass {
@Reflect.metadata('type', 'string')
name: string = '';}
2.内置元数据类型
design:type:获取属性类型
design:paramtypes:获取方法参数类型
design:returntype:获取方法返回类型
class-transformer介绍
实现对象与JSON数据之间的双向转换,支持复杂类型的序列化/反序列化。
class-transformer核心修饰符:
1.@Expose(options?)
功能:控制属性序列化/反序列化可见性
参数:name:JSON字段别名 since/until:版本控制范围
示例:
@Expose({ name: 'user_name' })username: string = '';
2.@Type(typeFn)
功能:指定嵌套类型转换规则
参数:typeFn:返回目标类型的箭头函数
示例:
@Type(() => Date)createTime: Date;
3.@Transform(transformFn, options?)
功能:自定义值转换逻辑
参数:transformFn:转换处理器函数 groups:分组控制
示例:
@Transform(({ value }) => value.toUpperCase())
name: string;
二、应用
1.安装依赖
ohpm i class-transformer
ohpm i reflect-metadata # 需配合装饰器使用
2.基类Model
import 'reflect-metadata';
import { Type, Expose, plainToInstance, instanceToPlain, plainToClass } from 'class-transformer';export class BaseModel {/*** 类实例转JSON* @param instance 类实例* @param excludeExtraneous 是否排除未标记属性*/toJson(excludeExtraneous = true): string {return JSON.stringify(instanceToPlain(this, {excludeExtraneousValues: excludeExtraneous}));}
}
3.实际创建Model
import 'reflect-metadata';
import { Type, Expose } from 'class-transformer';
import { BaseModel } from '../../support/base/BaseModel';@Expose()
export class MFUserModel extends BaseModel {@Expose({ name: 'Token' }) // 支持JSON字段映射token: string = '';@Expose()Phone: string = '';@Expose()PostType: number = 0;// 嵌套对象处理@Expose()@Type(() => AllowOrgListModel) // 确保类型转换AllowOrgList?: AllowOrgListModel[] ;
}// 嵌套类定义
export class AllowOrgListModel {@Expose()OrgId: string = '';@Expose()PersonId: string = '';
}
3.使用示例
let par = {'Phone':this.userPhone, 'Password': this.password} as Record<string, number | String>;
httpReq.post<HttpResponseData>('/Person/Login', par).then(resData => {if (resData.Code == 200) {const userModel1 = plainToClass(MFUserModel, resData.RetData); // objectconst jsonStr = userModel.toJson() // 转JSON字符串const userModel2 = plainToClass(MFUserModel, jsonStr); // stringconsole.log('JSONString:', jsonStr);} else {Toast.show(resData.Msg)}
}).catch((error: Error) => {ConsoleLog.error('登录失败:', error.message);Toast.show(error.message)
});