HarmonyOS鸿蒙Next中怎样处理应用中的JSON数据?
HarmonyOS鸿蒙Next中怎样处理应用中的JSON数据? 开发中需要处理JSON数据,怎样处理:
- 网络请求返回JSON
- 本地数据存储
- 对象与JSON互转
- 类型安全处理
4 回复
实现方案
1. 基础JSON操作
/**
* JSON序列化与反序列化
*/
export class JsonUtils {
/**
* 对象转JSON字符串
*/
static stringify(obj: Object): string {
return JSON.stringify(obj);
}
/**
* JSON字符串转对象
*/
static parse<T>(json: string): T {
return JSON.parse(json) as T;
}
/**
* 安全解析(带错误处理)
*/
static safeParse<T>(json: string, defaultValue: T): T {
try {
return JSON.parse(json) as T;
} catch (err) {
Logger.error('JsonUtils', 'JSON解析失败', err as Error);
return defaultValue;
}
}
/**
* 格式化JSON(美化输出)
*/
static format(obj: Object): string {
return JSON.stringify(obj, null, 2);
}
}
// ✅ 使用示例
const item = { id: 1, name: '物品1' };
const json = JsonUtils.stringify(item);
const obj = JsonUtils.parse<Item>(json);
2. 模型类定义
/**
* 物品模型
*/
export class Item {
id: number = 0;
name: string = '';
categoryId: number = 0;
createTime: number = 0;
tags: string[] = [];
/**
* 从JSON创建对象
*/
static fromJson(json: Record<string, Object>): Item {
const item = new Item();
item.id = json.id as number;
item.name = json.name as string;
item.categoryId = json.category_id as number; // 字段映射
item.createTime = json.create_time as number;
item.tags = json.tags as string[] || [];
return item;
}
/**
* 转换为JSON对象
*/
toJson(): Record<string, Object> {
return {
id: this.id,
name: this.name,
category_id: this.categoryId, // 字段映射
create_time: this.createTime,
tags: this.tags
};
}
/**
* 转换为JSON字符串
*/
toJsonString(): string {
return JSON.stringify(this.toJson());
}
}
// ✅ 使用
const jsonStr = '{"id":1,"name":"物品1","category_id":2,"create_time":1702886400000}';
const item = Item.fromJson(JSON.parse(jsonStr));
console.info('物品:', item.name);
const json = item.toJsonString();
console.info('JSON:', json);
3. 列表数据处理
/**
* 列表数据转换
*/
export class ItemListConverter {
/**
* JSON数组转对象数组
*/
static fromJsonArray(jsonArray: Array<Record<string, Object>>): Item[] {
return jsonArray.map(json => Item.fromJson(json));
}
/**
* 对象数组转JSON数组
*/
static toJsonArray(items: Item[]): Array<Record<string, Object>> {
return items.map(item => item.toJson());
}
/**
* JSON字符串转对象数组
*/
static parseArray(jsonStr: string): Item[] {
try {
const jsonArray = JSON.parse(jsonStr) as Array<Record<string, Object>>;
return this.fromJsonArray(jsonArray);
} catch (err) {
Logger.error('ItemListConverter', '解析失败', err as Error);
return [];
}
}
}
// ✅ 使用
const jsonStr = '[{"id":1,"name":"物品1"},{"id":2,"name":"物品2"}]';
const items = ItemListConverter.parseArray(jsonStr);
console.info('物品数量:', items.length);
4. 嵌套对象处理
/**
* 带分类的物品
*/
export class ItemWithCategory {
id: number = 0;
name: string = '';
category: Category | null = null; // 嵌套对象
static fromJson(json: Record<string, Object>): ItemWithCategory {
const item = new ItemWithCategory();
item.id = json.id as number;
item.name = json.name as string;
// ✅ 处理嵌套对象
if (json.category) {
item.category = Category.fromJson(json.category as Record<string, Object>);
}
return item;
}
toJson(): Record<string, Object> {
const json: Record<string, Object> = {
id: this.id,
name: this.name
};
// ✅ 处理嵌套对象
if (this.category) {
json.category = this.category.toJson();
}
return json;
}
}
export class Category {
id: number = 0;
name: string = '';
static fromJson(json: Record<string, Object>): Category {
const category = new Category();
category.id = json.id as number;
category.name = json.name as string;
return category;
}
toJson(): Record<string, Object> {
return {
id: this.id,
name: this.name
};
}
}
5. Preferences存储JSON
/**
* 使用Preferences存储对象
*/
export class PreferencesJsonStorage {
private prefs: preferences.Preferences;
/**
* 保存对象
*/
async saveObject<T>(key: string, obj: T): Promise<void> {
const json = JSON.stringify(obj);
await this.prefs.put(key, json);
await this.prefs.flush();
}
/**
* 读取对象
*/
async getObject<T>(key: string, converter: (json: Record<string, Object>) => T): Promise<T | null> {
const json = await this.prefs.get(key, '') as string;
if (!json) {
return null;
}
try {
const obj = JSON.parse(json) as Record<string, Object>;
return converter(obj);
} catch (err) {
Logger.error('PreferencesJsonStorage', '解析失败', err as Error);
return null;
}
}
/**
* 保存数组
*/
async saveArray<T>(key: string, array: T[]): Promise<void> {
const json = JSON.stringify(array);
await this.prefs.put(key, json);
await this.prefs.flush();
}
/**
* 读取数组
*/
async getArray<T>(key: string, converter: (json: Record<string, Object>) => T): Promise<T[]> {
const json = await this.prefs.get(key, '') as string;
if (!json) {
return [];
}
try {
const jsonArray = JSON.parse(json) as Array<Record<string, Object>>;
return jsonArray.map(j => converter(j));
} catch (err) {
Logger.error('PreferencesJsonStorage', '解析失败', err as Error);
return [];
}
}
}
// ✅ 使用
const storage = new PreferencesJsonStorage();
// 保存对象
await storage.saveObject('current_item', item);
// 读取对象
const item = await storage.getObject('current_item', Item.fromJson);
// 保存数组
await storage.saveArray('recent_items', items);
// 读取数组
const items = await storage.getArray('recent_items', Item.fromJson);
6. 网络请求数据转换
/**
* API响应模型
*/
export class ApiResponse<T> {
code: number = 0;
message: string = '';
data: T | null = null;
static fromJson<T>(
json: Record<string, Object>,
dataConverter: (json: Record<string, Object>) => T
): ApiResponse<T> {
const response = new ApiResponse<T>();
response.code = json.code as number;
response.message = json.message as string;
if (json.data) {
response.data = dataConverter(json.data as Record<string, Object>);
}
return response;
}
isSuccess(): boolean {
return this.code === 200;
}
}
// ✅ 使用示例
async function fetchItem(id: number): Promise<Item | null> {
try {
const responseText = await httpRequest(`/api/items/${id}`);
const json = JSON.parse(responseText) as Record<string, Object>;
const response = ApiResponse.fromJson(json, Item.fromJson);
if (response.isSuccess()) {
return response.data;
} else {
Logger.error('API', response.message);
return null;
}
} catch (err) {
Logger.error('API', '请求失败', err as Error);
return null;
}
}
关键要点
1. 类型安全
// ✅ 推荐:使用泛型
static parse<T>(json: string): T {
return JSON.parse(json) as T;
}
// ✅ 推荐:定义fromJson方法
static fromJson(json: Record<string, Object>): Item {
// 手动映射字段,类型安全
}
// ❌ 避免:直接使用JSON.parse
const obj = JSON.parse(json); // any类型
2. 字段映射
// ✅ 数据库字段 <-> 对象属性映射
static fromJson(json: Record<string, Object>): Item {
const item = new Item();
item.categoryId = json.category_id as number; // ✅ 映射
return item;
}
toJson(): Record<string, Object> {
return {
category_id: this.categoryId // ✅ 映射回去
};
}
3. 错误处理
// ✅ 推荐:try-catch包裹
static safeParse<T>(json: string, defaultValue: T): T {
try {
return JSON.parse(json) as T;
} catch (err) {
Logger.error('Parse error', err);
return defaultValue;
}
}
// ❌ 避免:不处理错误
const obj = JSON.parse(json); // 可能抛异常
最佳实践
1. 模型类规范
export class Item {
// 1. 定义属性并初始化
id: number = 0;
name: string = '';
// 2. fromJson静态方法
static fromJson(json: Record<string, Object>): Item {
const item = new Item();
item.id = json.id as number;
item.name = json.name as string;
return item;
}
// 3. toJson实例方法
toJson(): Record<string, Object> {
return {
id: this.id,
name: this.name
};
}
}
2. 数组处理
// ✅ 统一的数组转换工具
static parseArray<T>(
jsonStr: string,
converter: (json: Record<string, Object>) => T
): T[] {
try {
const jsonArray = JSON.parse(jsonStr);
return jsonArray.map(converter);
} catch (err) {
return [];
}
}
总结
JSON处理要点:
✅ 定义fromJson/toJson方法 ✅ 使用泛型保证类型安全 ✅ try-catch处理解析错误 ✅ 字段名映射(snake_case <-> camelCase) ✅ 嵌套对象递归处理
规范的JSON处理提升代码质量!
在HarmonyOS Next中,处理JSON数据主要使用系统提供的JSON模块。开发者可以使用@ohos.util命名空间下的JSON类进行序列化和反序列化操作。通过JSON.parse()方法可以将JSON字符串转换为对象,而JSON.stringify()方法则可以将对象转换为JSON字符串。此外,ArkTS语言内置了对JSON数据的支持,可以直接操作JSON对象。


