首页 > 其他分享 >鸿蒙开发,使用http返回的响应数据无法正常获取 ,利用hilog打印日志一直结果是object或者代码凭空消失,根本没有打印日志(灵异事件???)

鸿蒙开发,使用http返回的响应数据无法正常获取 ,利用hilog打印日志一直结果是object或者代码凭空消失,根本没有打印日志(灵异事件???)

时间:2024-03-23 10:58:37浏览次数:28  
标签:info object string 打印 ProductInfo JSON 日志 data Logger

项目场景:

这里简述项目相关背景:前后端分离项目,使用鸿蒙做前端,后端SpringBoot写好接口(通过商品分类id查询商品列表),鸿蒙前端页面使用Tabs组件导航,展示商品分类,点击分类标签,查询后端接口,返回对应分类商品列表数据

项目场景:鸿蒙开发,使用http返回的响应数据无法正常获取 ,利用hilog打印日志一直结果是object或者代码凭空消失,根本没有打印日志(灵异事件???)


问题描述

我已经通过本地模拟器发送数据访问后端接口,并获取响应数据(穷大学生买不起新的遥遥领先,有一部旧华为手机只支持api6无法适应我使用的api9),但是响应数据格式有问题,打印出来一直是object类型:
http请求及接受响应打印日志(这里使用自定义封装好的hilog类Logger来打印)代码如下:

http.createHttp().request(this.baseURL + this.url,
      { method: http.RequestMethod.GET,
        header: {
        "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGFpbXMiOnsiaWQiOjcsImVtYWlsIjoiMzIwMzM3NTgzNkBxcS5jb20ifSwiZXhwIjoxNzExNzYzMzQ0fQ.l_p0vlOxyFzJjlKrllQknoJTzhAul3XAjqfIHjMZd***",//后端JWTtoken验证
        },
        expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
      }
      , (err: any, data: any) => {
      if (!err) {
        Logger.info('data:'+data)
        // Logger.info('data.toSting():'+data.toSting())//有这行代码模拟器会直接闪退,因为TypeError
        console.log('data:JSON.stringify(data)=='+JSON.stringify(data))//这行代码凭空消失,根本没有打印日志
        Logger.info('JSON.parse(`${data.result}`):'+JSON.parse(`${data.result}`))
        Logger.info('${data.result}:'+data.result)

        let res: Response = JSON.parse(`${data.result}`)
        Logger.info('===res.data:'+res.data)
        Logger.info('JSON.stringify(res.data):'+JSON.stringify(res.data)) //这行代码凭空消失

        let Jsonresult:Object = JSON.parse(data.result.toString());
        this.products = Jsonresult['data'];
        Logger.info('products:'+this.products)//这里打印可以看到从后端获取了5个数据,但是打印出来都是object

          // data.result为HTTP响应内容,可根据业务需要进行解析
        Logger.info('Result:' + JSON.stringify(data));
        Logger.info('code:' + JSON.stringify(data.responseCode));
        // data.header为HTTP响应头,可根据业务需要进行解析
        Logger.info('header:' + JSON.stringify(data.header));
        Logger.info('cookies:' + JSON.stringify(data.cookies)); // 8+
      } else {
        Logger.info('error:' + JSON.stringify(err));
      }
    })

控制台日志输出情况如下图:
控制台日志输出情况
模拟器运行图:

在这里插入图片描述
后端idea控制台打印情况:(可以看到正确访问后端接口,查询了数据库)

后端idea控制台打印情况


原因分析:

不知道如何正确解析后端响应回来的数据,看官方示例代码,获取其他博主很简单就获取出来了,但是我怎么尝试都没能成功,实在是卡了太久了,耐心已被耗完(而且实在是太打击人了,鸿蒙开发梦破裂),所以发布出来,既为寻求帮助,也为记录这个问题看看其他朋友是否也被困于此,为大家寻求交流解决。

与鸿蒙官方的提问日志:
在这里插入图片描述
在这里插入图片描述

然后就没有任何了…

解决方案:

还没找到,已提交问题给鸿蒙官方,但是一开始给我的是无用甚至错误的解决方案,我指出后,继续提问,但是现在已经快一星期没有收到回复了。。(难道他们也没有找到问题)

这里贴出我整合后的项目最小化demo代码,给大家参考:
index代码:

import ComputerTabs from '../ComputerTabs'
@Entry
@Component
struct Index {
  build() {
    /*顶部Tab*/
    Column() {
      Stack({ alignContent: Alignment.TopEnd }) {

        Tabs({ barPosition: BarPosition.Start }) {
          /*推荐页*/
          TabContent() {
            // HomeTabs()
            // ComputerTabs()
          }.tabBar('热门推荐')
          /*书籍页*/
          TabContent() {
            // ComputerTabs()
          }.tabBar('书籍')
          /*手机页*/
          TabContent() {
            // ComputerTabs()
          }.tabBar('手机')
          /*电脑办公页*/
          TabContent() {
            ComputerTabs()
          }.tabBar('电脑')
          /*衣物页*/
          TabContent() {
            // ClothingTabs()
          }.tabBar('衣物')

        }
        // .backgroundColor('#750907')
        .backgroundColor(Color.White)
        .barMode(BarMode.Scrollable)
        .vertical(false)
        .scrollable(true)
        .onChange((index: number) => {
          console.info("点击的首页顶部tabs的索引为"+index.toString())
          // if(index===3){
          //   ComputerTabs()
          // }
        })
      }
    }
    .width('100%')
    .height('87%')
  }
}

tabBar子模块:ComputerTabs 代码:

import ProductModel from './ProductModel';
import ProductInfo from './ProductInfo';

@Component
export default struct ComputerTabs {

  productInfo1: ProductInfo = new ProductInfo(1, '标题1', '内容1', 8888, 6666, '2024-03-12 21:18:49', '2024-03-12 21:18:49'
  , 1, 1, 'https://web-demo-wfb.oss-cn-guangzhou.aliyuncs.com/15aaa965-3fee-4941-90e3-223b9f19b10e%E7%81%8C%E7%AF%AE%E9%AB%98%E6%89%8B.jpg'
  , '2')
  productInfo2: ProductInfo = new ProductInfo(2, '标题2', '内容2', 9999, 6666, '2024-03-12 21:18:49', '2024-03-12 21:18:49'
    , 1, 1, 'https://web-demo-wfb.oss-cn-guangzhou.aliyuncs.com/15aaa965-3fee-4941-90e3-223b9f19b10e%E7%81%8C%E7%AF%AE%E9%AB%98%E6%89%8B.jpg'
    , '2')

  // 假数据,模拟查询后端获取的数据
  // private productList: ProductInfo[] = [this.productInfo1, this.productInfo2]
  private productList: ProductInfo[] = ProductModel.getProductList()


  build() {
    ListCardDisplay({productList : this.productList})
  }
}

@Component
struct ListCardDisplay {

  private productList: ProductInfo[] = []

  build(){
    Column({ space: 5 }) {
      List() {
        ForEach(this.productList, (productItem: ProductInfo) => {
          ListItem() {
            ProductCard({product: productItem})
              .margin({ top: 20 })
          }
        }, (productItem: ProductInfo) => productItem.id.toString())
      }
      .padding(20)
      .scrollBar(BarState.Off)
    }
    .width('100%')
    .height('100%')
    .backgroundColor(0xF1F3F5)
  }

}

@Component
struct ProductCard {
  product:ProductInfo
  build() {
    Row() {
      Image(this.product.imgUrl)
        .width(80)
        .height(80)
        .margin({ right: 20 })

      Column() {
        Text(this.product.title)
          .fontSize(20)
          .margin({ bottom: 8 })
        Text(this.product.content)
          .fontSize(16)
          .fontColor(Color.Gray)
          .margin({ bottom: 8 })
      }
      .alignItems(HorizontalAlign.Start)
      .width('80%')
      .height('100%')
    }
    .padding(20)
    .borderRadius(12)
    .backgroundColor('#FFECECEC')
    .height(120)
    .width('100%')
    .justifyContent(FlexAlign.SpaceBetween)
  }
}

Logger代码:

import hilog from '@ohos.hilog';

const LOGGER_PREFIX: string = 'ShopAPP';

class Logger {
  private domain: number;
  private prefix: string;

  // format Indicates the log format string.
  private format: string = '%{public}s, %{public}s';

  /**
   * constructor.
   *
   * @param prefix Identifies the log tag.
   * @param domain Indicates the service domain, which is a hexadecimal integer ranging from 0x0 to 0xFFFFF
   * @param args Indicates the log parameters.
   */
  constructor(prefix: string = '', domain: number = 0xFF00) {
    this.prefix = prefix;
    this.domain = domain;
  }

  debug(...args: string[]): void {
    hilog.debug(this.domain, this.prefix, this.format, args);
  }

  info(...args: string[]): void {
    hilog.info(this.domain, this.prefix, this.format, args);
  }

  warn(...args: string[]): void {
    hilog.warn(this.domain, this.prefix, this.format, args);
  }

  error(...args: string[]): void {
    hilog.error(this.domain, this.prefix, this.format, args);
  }
}

export default new Logger(LOGGER_PREFIX, 0xFF02);

ProductInfo (封装的商品类)代码:

export default class ProductInfo {
  id: number
  title: string
  content: string
  originalPrice: number
  price: number
  createTime: string
  updateTime: string
  userId: number
  isShow: number
  isDel: number
  collectNum: number
  imgUrl: string
  category: string


  constructor(id: number, title: string, content: string, originalPrice: number, price: number,
              createTime: string, updateTime: string, userId: number, isShow: number,
              imgUrl: string, category: string, isDel : number = 0, collectNum : number = 0) {
    this.id = id;
    this.title = title;
    this.content = content;
    this.originalPrice = originalPrice;
    this.price = price;
    this.createTime = createTime;
    this.updateTime = updateTime;
    this.userId = userId;
    this.isShow = isShow;
    this.isDel = isDel;
    this.collectNum = collectNum;
    this.imgUrl = imgUrl;
    this.category = category;
  }
}

发送http请求,访问后端请求数据ProductModel类代码:

import ProductInfo from './ProductInfo'
import http from '@ohos.net.http';
import Logger from './Logger';
import Response from './Response';

class ProductModel{
  baseURL: string = "http://10.0.2.2:8080"
  // 请求的后端接口: 根据分类查询商品列表
  url: string = "/product/listByCategory?category=2"
  // 存储后端返回的数据
  products: ProductInfo[]

  getProductList(): ProductInfo[] {
    Logger.info("=====getProductList=====")

    http.createHttp().request(this.baseURL + this.url,
      { method: http.RequestMethod.GET,
        header: {
        "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGFpbXMiOnsiaWQiOjcsImVtYWlsIjoiMzIwMzM3NTgzNkBxcS5jb20ifSwiZXhwIjoxNzExNzYzMzQ0fQ.l_p0vlOxyFzJjlKrllQknoJTzhAul3XAjqfIHjMZdnM",
        },
        expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
      }
      , (err: any, data: any) => {
      if (!err) {
        Logger.info('data:'+data)
        // Logger.info('data.toSting():'+data.toSting())//有这行代码模拟器会直接闪退,因为TypeError
        console.log('data:JSON.stringify(data)=='+JSON.stringify(data))//这行代码凭空消失,根本没有打印日志
        Logger.info('JSON.parse(`${data.result}`):'+JSON.parse(`${data.result}`))
        Logger.info('${data.result}:'+data.result)

        let res: Response = JSON.parse(`${data.result}`)
        Logger.info('===res.data:'+res.data)
        Logger.info('JSON.stringify(res.data):'+JSON.stringify(res.data)) //这行代码凭空消失

        let Jsonresult:Object = JSON.parse(data.result.toString());
        this.products = Jsonresult['data'];
        Logger.info('products:'+this.products)//这里打印可以看到从后端获取了5个数据,但是打印出来都是object

          // data.result为HTTP响应内容,可根据业务需要进行解析
        Logger.info('Result:' + JSON.stringify(data));
        Logger.info('code:' + JSON.stringify(data.responseCode));
        // data.header为HTTP响应头,可根据业务需要进行解析
        Logger.info('header:' + JSON.stringify(data.header));
        Logger.info('cookies:' + JSON.stringify(data.cookies)); // 8+
      } else {
        Logger.info('error:' + JSON.stringify(err));
      }
    })

    return this.products
  }

}

const productModel = new ProductModel();

export default productModel as ProductModel;

封装的响应数据类Response(格式与后端保持一致)代码

export default class Response{
  /**
   * 响应码
   * 0-成功  1-失败
   */
  code: number
  /**
   * 响应消息
   */
  msg: string
  /**
   * 响应数据
   */
  data: any
}

标签:info,object,string,打印,ProductInfo,JSON,日志,data,Logger
From: https://blog.csdn.net/WFB2157/article/details/136961880

相关文章

  • Vue开发日志:自定义组件:通用开发流程
    自定义组件:通用开发流程通用流程一组概念:key,value,labelProps:required和default同时存在的必要性让我们简单梳理一下通用流程在Vue.js中开发自定义组件的通用流程如下:定义组件模板:创建一个.vue文件,里面包含模板、样式和脚本部分。例如:<!--MyCustomCompone......
  • 【python】(05)如何python中的logging模块记录日志信息
    系列文章回顾【python】(01)初识装饰器Decorator【python】(02)初识迭代器Iterator【python】(03)初识生成器Generator【python】(04)python中实现多任务并发和并行的区别【python】(05)如何python中的logging模块记录日志信息文章目录一.Logging模块的常用组......
  • nginx高级访客日志切割
    切割理念(先纯手动的去切割日志,备份日志)给nginx进程发送信号,让nginx重新生成一个新日志文件,这就是一个日志切割根本/var/log/nginx/access.log.bak#1.备份原本日志文件nginxreloadreopen信号#配置文件中定义的日志文件名,是这个2./var/log/nginx/access.log #......
  • Oracle Data Guard Gap日志间隙SCN增量备份恢复案例分享
            本期将为大家分享”OracleDataGuardGap日志间隙SCN增量备份恢复”案例。        欢迎关注“数据库运维之道”公众号,一起学习数据库技术!        关键字:DataGuard日志间隙、RedoGap、ArchiveGap、DataGuardGap、ORA-00308、ORA-2703......
  • 【Azure Log A workspace】Azure上很多应用日志收集到Log A workspace后如何来分别各
    问题描述AzureLogAnalyticsWorkspace作为Azure云上统一存储日志的服务,可以由多个服务直接发送日志到LogAWorkspace。如ApplicationInsights,AzureDiagnostic Settings等。只是,当数据都收集到同一个Workspace后,如何来分别是那些资源发送的日志呢?分别占用了多少的存储......
  • 如何使用极狐GitLab Runner 修改日志大小限制
    本文作者:徐晓伟GitLab是一个全球知名的一体化DevOps平台,很多人都通过私有化部署GitLab来进行源代码托管。极狐GitLab是GitLab在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。本文讲述了如何调整极狐GitlabRunner日志大小限制问题测试项目:https......
  • 浮木云学习日志(12)---表格设计(二)
    上次做了一个包括表格的页面设计,个人认为关于表格设计的内容介绍比较笼统,可能没办法直接对这个组件进行透彻的了解,本次我就来详细介绍一下如何通过高级表格设计玩转表格设计。感兴趣的小伙伴可以去他们官网https://www.fumucloud.com/一起体验一下这个高级表格组件。本次记录我们......
  • 云打印和无线打印有什么区别?
    近段时间,云打印的概念越来越火热,而与此同时,无线打印也逐渐被大家所接受。那么云打印和无线打印有什么区别?今天带大家来了解一下。 云打印和无线打印有什么区别?想要了解云打印和无线打印的区别,首先我们得先来了解一下云打印和无线打印。云打印是近年来较为火热的云概念之一,......
  • 云打印的应用场景有哪些?
    近段时间以来,随着互联网的发展,云打印也随之火热。那么云打印的应用场景有哪些?有哪些用户需要用到云打印呢?今天就带大家来了解一下。云打印的应用场景有哪些?有哪些用户需要用到云打印?现在能用到云打印的场景还是非常多的,这边按照各个应用场景来给大家分别介绍一下,如果你也符合的......
  • 开发者选项 选择日志级别 这个是个小米miui特有的选项,aosp里搜了下好像没有
    "Developeroptions""Selectloglevel" https://github.com/ingbrzy/Xiaomi.eu-MIUIv10-XML-Compare/blob/master/sakura/Settings.apk/res/values/strings.xmlhttps://github.com/ingbrzy/Xiaomi.eu-MIUIv11-XML-Compare/blob/master/davinci_stabl......