在鸿蒙开发的广袤天地中,网络层的搭建与封装无疑是构建高效、稳定应用的基石。继上篇的探索之后,本文将继续深入网络层的优化之旅,揭秘如何通过类型转换器、请求查询附加器以及丰富的常量参数,将网络层的构建艺术推向一个新的高度。
在网络请求的世界里,数据格式的转换至关重要。我们通过定义DataConverter接口,实现了对请求与响应数据类型的灵活转换。
export interface DataConverter {
requestConvert(extraData: string | Object | ArrayBuffer): string | Object | ArrayBuffer;
responseConvert(data: string | Object | ArrayBuffer, responseType: http.HttpDataType): string | Object | ArrayBuffer;
}
我们实现了一个默认的JsonDataConverter,它将请求数据转换为JSON字符串,并根据响应类型将响应数据转换为适当的格式。
export class JsonDataConverter implements DataConverter {
requestConvert(extraData: string | Object | ArrayBuffer): string | Object | ArrayBuffer {
// 将请求数据转换为JSON字符串
return JSONUtil.beanToJsonStr(extraData);
}
responseConvert(data: string | Object | ArrayBuffer, responseType: http.HttpDataType): string | Object | ArrayBuffer {
// 根据responseType将响应数据转换为相应的格式
switch (responseType) {
case http.HttpDataType.STRING:
return JSON.parse(data as string);
case http.HttpDataType.OBJECT:
return data;
default:
return data;
}
}
}
参数附加器QueryParamAppender接口允许我们对发送的请求数据进行重组,满足诸如参数签名等业务需求。
// 定义一个用于附加查询参数的接口
export interface QueryParamAppender {
append(queryParams?: Map | Array | Array >): string|undefined;
}
通过CustomQueryParamAppender的实现,我们简化了查询参数的编码和附加过程。
export class CustomQueryParamAppender implements QueryParamAppender {
append(queryParams?: Map | undefined): string|undefined {
if (queryParams===undefined || queryParams.size === 0) {
return;
}
const paramsArray: string[] = [];
for (const qp of queryParams) {
let key = qp[0]
let value = qp[1]
let encodedValue = '';
if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
encodedValue += `${encodeURIComponent(`${key}[${i}]`)}=${encodeURIComponent(value[i].toString())}&`;
}
if (encodedValue.length > 0) {
encodedValue = encodedValue.slice(0, -1); // 移除最后一个 '&'
}
} else {
encodedValue = encodeURIComponent(key) + '=' + encodeURIComponent(value.toString());
}
paramsArray.push(encodedValue);
}
return paramsArray.join('&');
}
}
通过定义一系列的常量,我们为网络请求的错误处理提供了统一的接口。这些常量不仅包括了各种网络错误的场景,还涵盖了HTTP状态码的含义,为开发者提供了清晰的指导。
{
"name": "network_unavailable",
"value": "网络不可用"
},
{
"name": "invalid_url_format",
"value": "URL格式不合法"
},
{
"name": "invalid_url_not_exist",
"value": "URL不存在"
},
{
"name": "parameter_error",
"value": "参数错误"
},
{
"name": "permission_denied",
"value": "权限被拒绝"
},
{
"name": "unsupported_protocol",
"value": "不支持的协议"
},
{
"name": "bad_url_format",
"value": "URL使用错误的/非法的格式或缺少URL"
},
{
"name": "could_not_resolve_proxy_name",
"value": "无法解析代理名称"
},
{
"name": "could_not_resolve_host_name",
"value": "无法解析主机名"
},
{
"name": "could_not_connect_to_server",
"value": "无法连接到服务器"
},
{
"name": "weird_server_reply",
"value": "服务器回复异常"
},
{
"name": "access_denied_to_remote_resource",
"value": "访问远程资源被拒绝"
},
{
"name": "http2_framing_layer_error",
"value": "HTTP2帧层错误"
},
{
"name": "transferred_partial_file",
"value": "传输了部分文件"
},
{
"name": "failed_writing_data_to_disk",
"value": "将数据写入磁盘/应用程序失败"
},
{
"name": "upload_failed",
"value": "上传失败"
},
{
"name": "failed_to_open_read_local_data",
"value": "无法打开/读取本地数据"
},
{
"name": "out_of_memory",
"value": "内存不足"
},
{
"name": "timeout_reached",
"value": "达到超时时间"
},
{
"name": "redirects_exceeded",
"value": "达到重定向的最大次数"
},
{
"name": "server_returned_nothing",
"value": "服务器未返回任何内容(无头信息,无数据)"
},
{
"name": "failed_sending_data_to_peer",
"value": "向对等端发送数据失败"
},
{
"name": "failure_receiving_data_from_peer",
"value": "从对等端接收数据失败"
},
{
"name": "ssl_certificate_problem",
"value": "本地SSL证书问题"
},
{
"name": "unsupported_ssl_cipher",
"value": "不支持指定的SSL加密算法"
},
{
"name": "ssl_peer_certificate_or_ssh_remote_key_not_ok",
"value": "SSL对等证书或SSH远程密钥不正确"
},
{
"name": "unrecognized_http_content_or_transfer_encoding",
"value": "无法识别的HTTP内容或传输编码"
},
{
"name": "maximum_file_size_exceeded",
"value": "超过最大文件大小"
},
{
"name": "disk_full_or_allocation_exceeded",
"value": "磁盘已满或分配超过限制"
},
{
"name": "remote_file_already_exists",
"