【鸿蒙实战开发】基于class-transformer的对象与JSON相互转换

80 篇文章 0 订阅
80 篇文章 0 订阅

场景一:方法将普通javascript对象转换为特定类的实例

解决方案

首先我们先定义一个想要指定的特定的类如下:

User里面包含属性id,fistname,lastname,age,data和它的构造方法,还有特定的方法getName和isAdult。

class User { 
  id: number; 
  firstName: string; 
  lastName: string; 
  age: number; 
  date?: Date; 

  constructor() { 
    this.id = 0; 
    this.firstName = ""; 
    this.lastName = ""; 
    this.age = 0; 
  } 

  getName() { 
    return this.firstName + ' ' + this.lastName; 
  } 

  isAdult() { 
    return this.age > 18 && this.age < 60; 
  } 
}

我们在前端处理后端传送过来的数据时,经过反序列化转换的对象全是plain(literal) object(普通(字面量)对象),如下,这里我们手动写一个待转换成特定对象的 JavaScript对象(JSON形式)。

interface UserJson { 
  id: number, 
  firstName: string, 
  lastName: string, 
  age: number, 
  date?: Date 
} 

const userJson:UserJson = { 
  id: 1, 
  firstName: "Johny", 
  lastName: "Cage", 
  age: 27, 
  date: new Date() 
}

使用class-transform可以直接将收到的userJson字面量对象转换为User实例对象,进而可以使用其中的方法。

使用plainToInstance(将字面量转为类实例,支持数组转换)这个接口来进行转化对应实例。

plainToInstance第一个参数传入特定的实体类,第二个传入需要转换的js对象。

export function test1() { 
  // JSON转为对象 
  const user: User = plainToInstance(User,userJson); 
  log("JSON转对象后输出情况"); 
  //输出class中的方法 
  log(user.getName()); 
  log(user.isAdult() + ""); 
}

实现效果:

image.png

在项目中使用class-transformer例子

上面已经说明了class-transformer的最简单用法,现在说一个示例如何在项目中使用。

前端代码:

class User { 
  //实体类还是我们刚才的实体User(包含fistname,lastname,age,data,和它的构造方法还有特定的方法getName和isAdult) 这里省略重复代码 
} 

Request.get({ 
  baseURL: 'http://xxxxx' 
}).then((user: User) => { 
  console.log(user) 
  console.log(user.username) 
  console.log(user.getName()) 
  console.log(user.isAdult()) 
})

后端代码:

@Get('/user') 
findUser() { 
  const user = new User('coder', '12345', 18); 
  return user; 
}

可以发现立马就报错了:

image.png

所以我们需要使用class-transformer的plainToInstance来做修改:

Request.get ({ 
  baseURL : 'http://xxx'}).then((user : User) => { 
  const user1 = plainToInstance(User, user) 
  console.log(user1.username) 
  console.log(user1.getName()) 
  console.log(user1.isAdult()) 
})

立马见效,并且还能调用其中的方法:
image.png

场景二:JSON转对象的时候,控制某些敏感字段不对外暴露

解决方案

使用exclude注解可以解决,还是使用User实体来做演示里面的password属性不想被传到JSON。

class User { 
  id: number; 
  @Exclude() 
  password: string; 

  constructor(id: number, password: string) { 
    this.id = id; 
    this.password = password; 
  } 
}

手动写一个待转换成特定对象的 javascript对象(JSON形式)。

interface UserJson { 
  'id': number, 
  'password': string 
}

如果是传入的字符串我们需要搭配JSON.parse来使用,将字符串转化成JSON格式的UserJson对象,使用plainToInstance来进行转换,由于使用了@Exclude()注解

转换成user对象后password属性也不会被输出。

export function SensitiveJsonToInstanceDemo() { 
  log('JSON转对象后输出情况'); 
  let ss = '{"id":1,"password":"123456"}' 
  let oo: UserJson = JSON.parse(ss) 
  let user: User = plainToInstance(User,oo) 
  log('user_id=' + user.id) 
  log('user_password=' + user.password); 
}

可见需要控制隐藏的password并不会被输出。
image.png

场景三:属性是一些复杂结构体时,实现json与对象的互转

解决方案

这里我们定义一个需要转换的User实体类,user的id,name 还有firstSonName,firstSonAge。

class User { 
  userId: number; 
  userName: string; 
  firstSonName: string; 
  firstSonAge: number; 

  constructor(userId: number, userName: string, firstSonName: string, firstSonAge: number) { 
    this.userId = userId; 
    this.userName = userName; 
    this.firstSonName = firstSonName; 
    this.firstSonAge = firstSonAge; 
  } 
}

服务端传一个字符串。

{ 
  'userId': 1, 
  'userName': 'abc', 
  'children': [ 
    { 
      'username': 'son1', 
      'age': '18' 
    }, 
  { 
    'username': 'son2', 
    'age': '28' 
   } 
  ] 
}

所以我们设计两个接口:

interface UserJson { 
  userId: number; 
  userName: string; 
  firstSonName: string; 
  firstSonAge: number; 
} 

interface FatherJson { 
  userId: number; 
  userName: string; 
  children: Record<string,string>[] 
}

直接使用plainToInstance将fatherjson转换成user对象是获取不到firstSonName,与firstSonAge的属性的,所以我们需要进行一个属性拍平。

export function ComplexJsonToInstanceDemo() { 
  //服务器返回的字符串 
  let ss = '{"userId":1,"userName":"abc","children":[{"username":"son1","age":"18"},{"username":"son2","age":"28"}]}' 
  //将字符串转化成JSON 
  let fatherjson: FatherJson = JSON.parse(ss) 
  let fs: Record<string,string> = fatherjson.children[0] 

  //fatherjson转userjson 
  let userjson: UserJson = { 
    userId: fatherjson.userId, 
    userName: fatherjson.userName, 
    firstSonName: fs['username'], 
    firstSonAge: parseInt(fs['age']) 
  } 

  let user: User = plainToInstance(User,userjson) 
  log('user_firstSonName=' + user.firstSonName) 
  log('user_firstSonAge=' + user.firstSonAge) 
}

实现效果,可看到firstSonName与firstSonAge,已经成功获取。

image.png

总结

使用三方库class-transformer搭配JSON的JSON.parse,可以满足类似gson/fastjson绝大部分的需求,更多用法可以参考​​https://github.com/typestack/class-transformer​​文档。

此外,建议审视设计的类和json是否合理,尽量避免使用复杂的转换。

写在最后

●如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
●点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
●关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
●更多鸿蒙最新技术知识点,请移步前往小编:https://gitee.com/

在这里插入图片描述

  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值