项目场景:
这里简述项目相关背景:前后端分离项目,使用鸿蒙做前端,后端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控制台打印情况:(可以看到正确访问后端接口,查询了数据库)
原因分析:
不知道如何正确解析后端响应回来的数据,看官方示例代码,获取其他博主很简单就获取出来了,但是我怎么尝试都没能成功,实在是卡了太久了,耐心已被耗完(而且实在是太打击人了,鸿蒙开发梦破裂),所以发布出来,既为寻求帮助,也为记录这个问题看看其他朋友是否也被困于此,为大家寻求交流解决。
与鸿蒙官方的提问日志:
然后就没有任何了…
解决方案:
还没找到,已提交问题给鸿蒙官方,但是一开始给我的是无用甚至错误的解决方案,我指出后,继续提问,但是现在已经快一星期没有收到回复了。。(难道他们也没有找到问题)
这里贴出我整合后的项目最小化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