axios发送网络请求 默认的序列化model会丢失方法和属性 HarmonyOS 鸿蒙Next

发布于 1周前 作者 sinazl 来自 鸿蒙OS

axios发送网络请求 默认的序列化model会丢失方法和属性 HarmonyOS 鸿蒙Next

在使用"@ohos/axios": "2.2.1"发送网络请求时候,指定response的类型是自定义的一个class的model对象,默认的序列化model,除了接口响应返回的属性,在model内部又定义了一些额外属性和方法,但是在使用的时候,额外属性和方法都会丢失无效,请问该如何处理?

2 回复
可以参考以下示例来处理该问题。

JSON.parse() 方法返回的是一个普通对象,而不是 DataBean 类的实例。不包含类定义的任何方法。需要在将 JSON 数据转换为 DataBean 实例时,手动创建类的实例,并将 JSON 对象的属性赋值给类的实例。

class DataBean { 
  code = -1; 
  msg = ''; 
  isOK() { 
    return this.code === 0; 
  } 
  // 静态方法,从 JSON 字符串创建 DataBean 实例 
  static fromJson(jsonString: string): DataBean { 
    const jsonData:ESObject = JSON.parse(jsonString); 
    const dataBean = new DataBean(); 
    dataBean.code = jsonData.code; 
    dataBean.msg = jsonData.msg; 
    return dataBean; 
  } 
} 

let json = ‘{“code”:0,“msg”:“success”}’; let dataBean = DataBean.fromJson(json); console.log(“test”,dataBean.msg); // success console.log(“test”,dataBean.isOK()); // true,

JSON转成实体class,需要new一个class的实例。如果使用JSON.parse() 返回的是一个普通对象,而不是class的实例,不包含类定义的任何方法。

可以使用自定义序列化实例方法,如上述示例中的“fromJson”自定义静态方法,从 JSON 字符串创建 DataBean 实例。

2、您可以使用第三方库 class-transformer 来实现该功能,地址为:https://gitee.com/openharmony-tpc/openharmony_tpc_samples/tree/master/class-transformer

demo如下:

import  { plainToClass } from “class-transformer”;

interface UserJson { id: number, firstName: string, lastName: string, age: number } const userJson:UserJson = { id: 1, firstName: “Johny”, lastName: “Cage”, age: 27 }

class User { id:number; firstName:string; lastName:string; age:number;

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

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

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

class DataBean { code = -1; msg = ‘’; isOK() { return this.code === 0; } // 静态方法,从 JSON 字符串创建 DataBean 实例 static fromJson(jsonString: string): DataBean { const jsonData:ESObject = JSON.parse(jsonString); const dataBean = new DataBean(); dataBean.code = jsonData.code; dataBean.msg = jsonData.msg; return dataBean; } }

@Entry @Component struct JSONParseModelPage { @State message: string = ‘Hello World’;

build() { Column() { Text(this.message) .id(‘JSONParseModelPageHelloWorld’) .fontSize(50) .fontWeight(FontWeight.Bold) .alignRules({ center: { anchor: container, align: VerticalAlign.Center }, middle: { anchor: container, align: HorizontalAlign.Center } })

  Button() {
    Text(<span class="hljs-string"><span class="hljs-string">'自定义序列化'</span></span>)
  }
  .type(ButtonType.Capsule)
  .height(<span class="hljs-number"><span class="hljs-number">40</span></span>)
  .width(<span class="hljs-number"><span class="hljs-number">200</span></span>)
  .margin({top: <span class="hljs-number"><span class="hljs-number">20</span></span>})
  .onClick(() =&gt; {
    <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> json = <span class="hljs-string"><span class="hljs-string">'{"code":0,"msg":"success"}'</span></span>;
    <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> dataBean = DataBean.fromJson(json);
    console.log(<span class="hljs-string"><span class="hljs-string">"test"</span></span>,dataBean.msg); <span class="hljs-comment"><span class="hljs-comment">// success</span></span>
    console.log(<span class="hljs-string"><span class="hljs-string">"test"</span></span>,dataBean.isOK());
  })

  Button() {
    Text(<span class="hljs-string"><span class="hljs-string">'transformer1'</span></span>)
  }
  .type(ButtonType.Capsule)
  .height(<span class="hljs-number"><span class="hljs-number">40</span></span>)
  .width(<span class="hljs-number"><span class="hljs-number">200</span></span>)
  .margin({top: <span class="hljs-number"><span class="hljs-number">20</span></span>})
  .onClick(() =&gt; {
    <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> user:User = plainToClass(User,userJson);
    console.log(<span class="hljs-string"><span class="hljs-string">"test"</span></span>,user.getName());
  })

  Button() {
    Text(<span class="hljs-string"><span class="hljs-string">'transformer2'</span></span>)
  }
  .type(ButtonType.Capsule)
  .height(<span class="hljs-number"><span class="hljs-number">40</span></span>)
  .width(<span class="hljs-number"><span class="hljs-number">200</span></span>)
  .margin({top: <span class="hljs-number"><span class="hljs-number">20</span></span>})
  .onClick(() =&gt; {
    <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> userStr = <span class="hljs-string"><span class="hljs-string">'{"id":2,"firstName":"Tom","lastName": "Jerry","age": 27}'</span></span>
    <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> userJson1:UserJson = <span class="hljs-built_in"><span class="hljs-built_in">JSON</span></span>.parse(userStr)
    <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> user:User = plainToClass(User,userJson1);
    console.log(<span class="hljs-string"><span class="hljs-string">"test"</span></span>,user.getName());
  })
}
.height(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
.width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)

} }

在HarmonyOS鸿蒙Next开发中,如果遇到axios发送网络请求时默认的序列化模型(model)丢失方法和属性的问题,这通常是因为axios默认将JavaScript对象序列化为JSON字符串,而JSON标准不支持函数和某些特殊属性(如Symbol属性、undefined值等)的序列化。

axios本身是一个基于Promise的HTTP客户端,它使用JSON.stringify来将请求数据转换为JSON字符串,这个过程会丢失对象的方法(functions)和不可枚举属性(non-enumerable properties),因为这些在JSON标准中是不被支持的。

为了解决这个问题,你可以考虑以下几种方法:

  1. 只发送需要的数据:在发送请求前,构造一个新的对象或数组,只包含需要序列化的数据,避免包含方法和特殊属性。

  2. 自定义序列化:如果必须使用某些特殊的数据结构,可以考虑在发送前手动序列化为字符串或其他格式,然后在服务器端进行相应的解析。

  3. 使用其他库:有些库提供了更高级的序列化功能,可能能够保留更多的对象信息,但需要注意兼容性和性能问题。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部