鸿蒙学习笔记(5)-HTTP请求数据
一、Http请求数据
http模块是鸿蒙内置的一个模块,提供了网络请求的能力。不需要再写比较原始的AJAS代码。
ps:在项目中如果要访问网络资源,不管是图片文件还是网络请求,必须给项目开放权限。

(1)网络连接方式
HTTP数据请求连接:通过HTTP发起的一个单向数据请求。
WebSocket连接:使用WebSocket建立服务器与客户端的双向连接。
Socket连接:通过Socket进行数据传输,更加底层。
(2)涉及接口文档
| 类型 | 说明 |
|---|---|
| http.createHttp() | 创建一个HTTP请求,里面包括发起请求、中断请求、订阅/取消订阅HTTP Response Header事件。 |
| HttpRequest() | 根据URL地址,发起HTTP网络请求。 |
| requestInStream() | 根据URL地址,发起HTTP网络请求并返回流式响应,得到二进制数据,应用到文件下载,从后端拿到的不再是JSON和字符串,而是二进制数据。 |
| destroy() | 中断请求任务。 |
(3)request接口开发步骤
1、步骤概述
1、从@kit.NetworkKit中导入http命名空间。Kit是我们项目需要用到的各种服务,如网络服务,分布式管理服务,蓝牙通信等。
2、调用creatHttp()方法,创建一个HttpRequest对象。
3、调用该对象的request()方法,订阅http响应头事件,此接口会比request请求先返回。可以根据业务需要订阅此消息。(此步骤不是必须,是用来监控响应头信息,如果你想发请求给后端,想要先知道后端返回的数据是JSON还是文件之类的,可以用此监控,他会比内容先返回客户端。)
4、调用该对象的equest()方法,传入http请求的url地址和可选参数,发起网络请求。
5、得到结果过后,按照实际业务需要,解析返回结果,筛选或者进行数据转化。
6、调用该对象的off()方法,取消订阅http响应头事件。
7、当请求使用完毕时,调用destroy()方法主动销毁。
2、封装代码:
//在common模块中封装一个基础的请求工具import { http } from "@kit.NetworkKit";//封装请求代码,考虑到以后每个模块都要发送请求,默认放在common模块中。
//1、导入
export function MyRequest(url:string,method:http.RequestMethod,requestData:string){//2、创建http请求const httpRequest = http.createHttp()//3、可以用httprequest监听响应头(不是必须)httpRequest.on('headersReceive', (header: Object) => {console.info('header: ' + JSON.stringify(header));});httpRequest.request(url, {method:method,//请求方式header:{//设置请求头//前端浏览器告诉后端,前端传递的数据格式'Content-Type': 'application/json'},extraData:requestData, //设置请求要传给后端的数据connectTimeout:9000, //前端发送数据给后端如果9秒没有结果,前端主动终止行为readTimeout:9000, //读取数据超过9秒,告诉前端请求失败},(error:Error,data:http.HttpResponse)=>{//error没有内容代表成功if (!error) {console.log(`请求成功,返回数据:${JSON.stringify(data)}`)// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}else {console.log(`请求失败,具体原因:${JSON.stringify(error)}`)// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}})
}
3、使用说明:
在页面中要使用这个工具来测试请求是否成功,在common/index.ets文件中先暴露。

export {MyRequest} from './src/main/ets/utils/HttpUtils'
在home页面或者组件中,引入对应的函数
import {MyRequest} from '@ohos/common'///比如跟事件绑定,测试数据是否能收到
.onClick((event:ClickEvent) => {MyRequest('http://47.98.128.191:4001/home/swiperdate',http.RequestMethod.GET,'')})
此时可以看到日志可以收到:

此时请求发送完毕能够得到后端数据,但请求不是直接在页面或者组件中编写的代码,而是提取到了common模块中,如何拿到服务端的数据并显示到页面上,这才是需要解决的问题。
4、泛型编程
typescript中非常重要的一个概念:泛型编程。
利用一个简单的案例:
function computed(params1:number,params2:number):number{return params1 +params2
}computed(1,3)//编译通过
computed('xiao','ming')//编译失败,因为只接受number类型
为了简化上面的代码,使代码更加灵活,尤其是在数据约束上,既要增加约束,又要让参数支持更多类型,或者更加灵活,设计方式便是采用泛型的方式来设计参数类型 。
function computed<T>(params1:T,params2:T):T{return params1 +params2
}computed<number>(1,3) //编译通过
computed<string>('xiao','ming') //编译通过
computed<bollean>(true,false) //编译通过
同一个函数因为有了泛型,可以多次使用 ,这里我们以上面出现的问题:如何拿到服务端的数据并显示到页面上,利用promise来解决。通过promise对象将异步的请求代码封装到容器中获取到结果。
import { http } from "@kit.NetworkKit";
//BasicConstants下暴露基础URL地址,和传入的资源路径拼接
import { BasicConstants} from '../../constants/BasicConstants'
//封装请求代码,考虑到以后每个模块都要发送请求,默认放在common模块中。
//1、导入
export function MyRequest(url:string,method:http.RequestMethod,requestData:string){//2、创建http请求const httpRequest = http.createHttp()return new Promise((reslove:(value:string)=>void,reject:(value?:string)=>void)=>{//request发送请求就是异步代码httpRequest.request(//不再简单是url,而是做一下拼接基础地址BasicConstants.BASE_URL+url,{method:method,//请求方式header:{//设置请求头//前端浏览器告诉后端,前端传递的数据格式'Content-Type': 'application/json'},extraData:requestData, //设置请求要传给后端的数据connectTimeout:9000, //前端发送数据给后端如果9秒没有结果,前端主动终止行为readTimeout:9000, //读取数据超过9秒,告诉前端请求失败},(error:Error,data:http.HttpResponse)=>{//error没有内容代表成功if (!error) {console.log(`请求成功,返回数据:${JSON.stringify(data,null,2)}`)reslove(JSON.stringify(data))// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}else {console.log(`请求失败,具体原因:${JSON.stringify(error)}`)reject(JSON.stringify(error))// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}})})}
页面中获取请求返回的数据:

但此时传入参数是固定必须是string类型,不够灵活,接下来进一步封装,利用泛型编程做进一步优化使得代码实现复用。K代表请求的数据类型,T代表返回的数据类型
import { http } from "@kit.NetworkKit";
import { BasicConstants} from '../../constants/BasicConstants'
//封装请求代码,考虑到以后每个模块都要发送请求,默认放在common模块中。
//1、导入
//K代表请求的数据类型,T代表返回的数据类型
export function MyRequest<T,K>(url:string,method:http.RequestMethod,requestData?:K){//2、创建http请求const httpRequest = http.createHttp()return new Promise((reslove:(value:T)=>void,reject:(value?:string)=>void)=>{//request发送请求就是异步代码httpRequest.request(//不再简单是url,而是做一下拼接基础地址BasicConstants.BASE_URL+url,{method:method,//请求方式header:{//设置请求头//前端浏览器告诉后端,前端传递的数据格式'Content-Type': 'application/json'},extraData:JSON.stringify(requestData)||'', //设置请求要传给后端的数据connectTimeout:9000, //前端发送数据给后端如果9秒没有结果,前端主动终止行为readTimeout:9000, //读取数据超过9秒,告诉前端请求失败},(error:Error,data:http.HttpResponse)=>{//error没有内容代表成功if (!error) {console.log(`请求成功,返回数据:${JSON.stringify(data,null,2)}`)//这里如何reslove(JSON.parse(data.result as string))// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}else {console.log(`请求失败,具体原因:${JSON.stringify(error)}`)reject(JSON.stringify(error))// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}})})}
页面中获取请求返回的数据:

完整工具封装见资源文件。
(4)HTTP数据请求

4.1 导入HTTP模块
import http from '@ohos.net.http';
4.2 使用HTTP模块发送请求,处理响应.
4.2.1 创建一个http的请求对象,不可复用。
const httpRequest = http.createHttp()
4.2.2 调用一个request方法,发起网络请求。
ps:像这种可能存在数据请求发送完但数据还没收到,因此此处方法执行完会存放一个未来会完成的结果Promise。
req.request('http://localhost:3000/users',//请求URL地址
{ //请求选项HttpRequestOptionsmetnod:http.RequestMethod.GET,extraData:{'param1':'value1'} //k1=v1&k1=v2
}
)
HttpRequestOptions 说明:
名称 类型 描述 method RequestMethod 请求方式,GET(查询)、POST(表单提交,新增)、PUT(修改)、DELETE(删除)等 extraData string|Object 请求参数 header Object 请求头字段 connectTimeout number 请求超时时间,单位毫秒,默认60000ms readTimeout number 读取超时间,同上
4.2.3 获取服务器响应的内容,Promise提供两种方法分别是then成功回调和catch失败回调。
.then((resp:http.HttpResponse)=>{if(resp.responseCode === 200){//请求成功}})
.catch((err:Error)=>{//请求失败
});
HttpResponse 说明:
名称 类型 描述 responseCode responseCode 响应状态码 header Object 响应头 cookies string 响应返回的cookies result string|Object 响应体,默认是JSON字符串 resultType HttpDataType 返回值类型
二、Promise
Promise是es6提出的一个概念,主要用来解决异步回调的问题。Promise是一个数据容器,保存了未来的一个结果,Promise本身是可以用来存放同步代码和异步代码,平时经常用来解决存放异步代码。以下是网络请求的一个发展历程:
发送网络请求,获取结果
1.1 发送网络请求
//"AJAX"(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)
//浏览器默认提供的对象,获取结果
const xmlhttp = new XMLhttpRequest()
//连接服务器
xmlhttp.open('GET','http://+地址',true)
xmlhttp.send('id=1')//监听状态码,当状态码是200时
xmlhttp.onreadystatechange = function(){//首先状态码必须是200,readyState代表xmlhttp加载过程if(xmlhttp.status == 200 && xmlhttp.readyState == 4){const result = xmlhttp.responseText//拿到数据后转化const obj = JSON.parse(result)}
}
1.2 将其封装工具
function ajas( {method='GET',url,data='',async=true} ){//"AJAX"(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)//浏览器默认提供的对象,获取结果const xmlhttp = new XMLhttpRequest()//连接服务器xmlhttp.open(method,url,async)xmlhttp.send(data)//监听状态码,当状态码是200时xmlhttp.onreadystatechange = function(){//首先状态码必须是200,readyState代表xmlhttp加载过程if(xmlhttp.status == 200 && xmlhttp.readyState == 4){const result = xmlhttp.responseText//拿到数据后转化const obj = JSON.parse(result)//这里return obj没有意义,这里是个事件,时间返回的函数外面是接收不到的}}
//如果在fuction函数这里return obj也是不可以的,局部的变量无法在外部用
}//使用封装工具
ajax({method:'GET',url:'http://+地址',data:'id = 1'async:true
})
此时的obj还不能调出来使用,这时解决方法:在函数中在传入一个函数 success,如果函数能进入if中实现结果的取用,将在函数中调用。
function ajas( {method='GET',url,data='',async=true,success} ){//"AJAX"(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)//浏览器默认提供的对象,获取结果const xmlhttp = new XMLhttpRequest()//连接服务器xmlhttp.open(method,url,async)xmlhttp.send(data)//监听状态码,当状态码是200时xmlhttp.onreadystatechange = function(){//首先状态码必须是200,readyState代表xmlhttp加载过程if(xmlhttp.status == 200 && xmlhttp.readyState == 4){const result = xmlhttp.responseText//拿到数据后转化const obj = JSON.parse(result)success(Obj)}else if(404 500){error('失败')}}
}//使用封装工具
ajax({method:'GET',url:'http://+地址',data:'id = 1'async:true,success:function(msg){console.log(msg)}//是否请求成功error:function(error){}
})
这样做有缺陷:回调地狱,无限制的在回调函数中执行任务,得到回调结果,层层嵌套,开发中要避免,不存在可读性。
//使用封装工具
ajax({method:'GET',url:'http://+地址',data:'id = 1'async:true,success:function(msg){console.log(msg)ajax({url:'http://+地址',data:msg.id,success(msg2){ ajax({url:'',data:msg.classesId}//是否请求成功error:function(error){}
})
Promise
由上述Promise来解决异步编程的问题。
//按照1234执行顺序来执行,因为promise本身是同步的,如果在promise中放入一个异步的代码,异步代码是需要花时间,异步代码不论花费多长时间,等到代码运行结束,成功或者失败都会存放在resolve,reject中。
console.log(1)
//resolve,reject 这两个参数是函数
const promise = new Promise((resolve,reject)=>{
console.log(2)//存放同步代码或者异步代码,这里主要存放异步代码ajas({url:'http://xxx',method:'POST',data:{id:1},success:(msg)=>{resolve(msg)},error:(error)=>{reject(error)}})
})//then这个函数是异步的,只有resolve执行完毕,then才会执行
promise.then((result)=>{console.log(4)
})
.catch(error=>{})console.log(3)
await和async
es7提出的一个新方案,可以等待promise的结果。
//resolve,reject 这两个参数是函数
const promise2 = new Promise((resolve,reject)=>{//存放同步代码或者异步代码,这里主要存放异步代码ajas({url:'http://xxx',method:'POST',data:{id:1},success:(msg)=>{resolve(msg)},error:(error)=>{reject(error)}})
})async function show(){const res1 = await promise1const res2 = await promise2
}
axios工具
在前面代码的基础上,第三方工具axios做了一件事情,将axios代码和promise代码进行了封装,形成了一个完整的请求工具。
//封装格式
class Axios{baseURL =''get(){return new Promise (()=>{resolve(xxx)reject(xxx)})}post(){}creat(){}
}export const axios = new Axios()//代码中如何使用
import axios from 'axios'
//方法1:通过then拿到服务器响应回来的结果
axios.get('http://xxx').then(res=>{{)
//方法2:通过await和async配合拿到服务器响应回来的结果
result = await axios.post('http://xxx')
作为一个第三方库,使用的时候需要先完成下包的操作,打开终端执行命令,ohpm 是一个包管理工具,用来管理鸿蒙提供的第三方模块。
相关文章:
鸿蒙学习笔记(5)-HTTP请求数据
一、Http请求数据 http模块是鸿蒙内置的一个模块,提供了网络请求的能力。不需要再写比较原始的AJAS代码。 ps:在项目中如果要访问网络资源,不管是图片文件还是网络请求,必须给项目开放权限。 (1)网络连接方式 HTTP数…...
AI文生图工具推荐
一、AI文生图技术实现原理 AI文生图(Text-to-Image)基于生成对抗网络(GAN)或扩散模型(Diffusion Model)实现,通过深度学习将文本描述转化为图像。其核心流程包括: 文本编码…...
Spark-SQL核心编程
Spark-SQL核心编程 数据加载与保存 加载数据 spark.read.load 是加载数据的通用方法。如果读取不同格式的数据,可以对不同的数据格式进行设定 保存数据 df.write.save 是保存数据的通用方法。如果保存不同格式的数据,可以对不同的数据格式进行设定 …...
github 项目迁移到 gitee
1. 查看远程仓库地址 git remote -v 2. 修改远程仓库地址 确保 origin 指向你的 Gitee 仓库,如果不是,修改远程地址。 git remote set-url origin https://gitee.com/***/project.git 3. 查看本地分支 git branch 4. 推送所有本地分支 git p…...
AcWing 11:背包问题求方案数 ← 0-1背包
【题目来源】 https://www.acwing.com/problem/content/11/ 【题目描述】 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总…...
React应用开发学习指南
AI生成研究报告:关键词 React应用开发 React 已经成为前端 Web 开发领域的主导力量,它是一个免费且开源的 JavaScript 库,主要用于构建用户界面 (UI) 1。其多功能性延伸到为 Web 和原生应用程序创建 UI,使其成为行业内备受追捧的…...
LVGL源码(9):学会控件的使用(自定义弹窗)
LVGL版本:8.3 LVGL的控件各式各样,每种控件都有自己的一些特性,当我们想要使用一个LVGL控件时,我们首先可以通过官网去了解控件的一些基本特性,官网链接如下: LVGL Basics — LVGL documentation…...
HarmonyOs学习 环境配置后 实验1:创建项目Hello World
HarmonyOS开发入门:环境配置与Hello World实验 实验目标 掌握HarmonyOS开发环境配置,创建首个HarmonyOS应用并实现"Hello World"界面展示 实验准备 已安装DevEco Studio开发环境已配置HarmonyOS开发依赖项熟悉基本TypeScript/ArkTS语法&am…...
国产SMT贴片机自主技术突破解析
内容概要 随着电子信息产业对精密制造需求的持续升级,国产SMT贴片机的技术突破已成为装备自主化进程的关键节点。本文聚焦设备研发的三大核心领域:高动态运动控制系统通过线性电机与数字信号处理技术的融合,将重复定位精度提升至5μm级别&am…...
8、表单控制:预言水晶球——React 19 复杂表单处理
一、水晶球的预言本质 "每个表单都是时空裂缝中的预言容器,"占卜课教授特里劳妮凝视着水晶球,"React-Hook-Form与Formik的融合,让数据捕获如同捕捉未来碎片!" ——以魔法部神秘事务司的预言厅为隐喻…...
8 编程笔记全攻略:Markdown 语法精讲、Typora 编辑器全指南(含安装激活、基础配置、快捷键详解、使用技巧)
1 妙笔在手,编程无忧! 1.1 编程为啥要做笔记?这答案绝了! 嘿,各位键盘魔法师!学编程不记笔记,就像吃火锅不配冰可乐 —— 爽到一半直接噎住!你以为自己脑子是顶配 SSD,结…...
【MySQL】SQL语句在MySQL中的执行过程?主要存储引擎区别?
MySQL SQL语句执行过程详解 作为面试官,我来详细剖析一条SQL语句在MySQL中的完整执行过程,这是每个后端开发者都应该掌握的核心知识。 一、连接阶段 建立连接 客户端通过TCP/IP协议与MySQL服务器建立连接(默认3306端口)服务器验证用户名、密码和权限…...
Linux(autoDL云服务器)mamba-ssm环境安装——一次成功!
1.创建环境选择torch2.0, cuda11.8,python3.8 2.从GitHub官网下载cp38对应的,causl_conv1d,和mamba-ssm2.2.2。下载入下图所示。 3.直接用finalshell 或者xshell连接服务器上传,到根目录下面。 直接用pip install *…...
代码审计入门 原生态sql注入篇
前置知识: 漏洞形成的原因: 1、可控的参数 2、函数缺陷 代码审计的步骤: 1、全局使用正则搜索 漏洞函数 ,然后根据函数看变量是否可控,再看函数是否有过滤 2、根据web的功能点寻找函数,然后根据函数看…...
spring Ai---向量知识库(一)
在一些垂直领域以及公司内部信息相关或者实时性相关的大模型应用,就无法直接使用chatGPT。 这个时候,向量知识库就进入了。 通过坐标向量最接近的即为匹配相关答案。 向量模型定义:将文档向量化,保证内容越相似的文本,…...
jmeter利用csv进行参数化和自动断言
1.测试数据 csv测试数据如下(以注册接口为例) 2.jemer参数化csv设置 打开 jmeter,添加好线程组、HTTP信息头管理器、CSV 数据文件设置、注册请求、响应断言、查看结果树 1) CSV 数据文件设置 若 CSV 中数据包含中文,…...
C# 类型、存储和变量(数据成员和函数成员)
本章内容 C#程序是一组类型声明 类型是一种模板 实例化类型 数据成员和函数成员 预定义类型 用户定义类型 栈和堆 值类型和引用类型 变量 静态类型和dynamic关键字 可空类型 数据成员和函数成员 像short、int和long等这样的类型称为简单类型。这种类型只能存储一个数据项。 其…...
Java八种常见的设计模式
一、单例模式 单例模式是(Singleton Pattern)Java中最常用的设计模式之一,它保证一个类仅有一个实例,并提供一个全局访问点。 实现单例模式的核心是将类的构造方法私有化,以防止外部直接通过构造函数创建实例。同时&am…...
数据结构实验7.2:二叉树的基本运算
文章目录 一,实验目的二,问题描述三,基本要求四,实验操作五,示例代码六,运行效果 一,实验目的 深入理解树与二叉树的基本概念,包括节点、度、层次、深度等,清晰区分二叉…...
Go-zero框架修改模版进行handler统一响应封装
使用go-zero快速生成接口的时候,发现还是有一些情况不太好处理,比如说,想要自定义响应封装等等。 最开始第一版写api文件的时候,写法是这样的。 type LoginRequest {UserName string json:"userName"Password string …...
AI专题(一)----NLP2SQL探索以及解决方案
前面写了很多编码、算法、底层计算机原理等相关的技术专题,由于工作方向调整的缘故,今天开始切入AI人工智能相关介绍。本来按照规划,应该先从大模型的原理开始介绍会比较合适,但是计划赶不上变化,前面通用大模型的工作…...
深入理解 React Hooks:简化状态管理与副作用处理
在现代前端开发中,React 已经成为了最受欢迎的 JavaScript 库之一。随着 React 16.8 的发布,React Hooks 的引入彻底改变了开发者编写组件的方式。Hooks 提供了一种更简洁、更直观的方式来管理组件的状态和副作用,使得函数组件能够拥有类组件…...
Spring Boot 实现防盗链
在 Spring Boot 项目中实现防盗链可以通过多种方式,下面为你介绍两种常见的实现方法,分别是基于请求头 Referer 和基于令牌(Token)的防盗链。 基于请求头 Referer 的防盗链 这种方法通过检查请求头中的 Referer 字段,…...
Java 动态代理实现
Java 动态代理实现 一、JDK动态代理二、CGLIB动态代理三、动态代理的应用场景四、JDK代理与CGLIB代理比较 动态代理是Java中一种强大的技术,它允许在运行时创建代理对象,用于拦截对目标对象的方法调用。 一、JDK动态代理 JDK动态代理是Java标准库提供的代…...
2025年4月通信科技领域周报(4.07-4.13):6G技术加速落地 卫星通信网络迎来组网高潮
2025年4月通信科技领域周报(4.07-4.13):6G技术加速落地 卫星通信网络迎来组网高潮 目录 2025年4月通信科技领域周报(4.07-4.13):6G技术加速落地 卫星通信网络迎来组网高潮一、本周热点回顾1. 华为发布全球首…...
《手环表带保养全攻略:材质、清洁与化学品避坑指南》
系列文章目录 文章目录 系列文章目录前言一、表带材质特性与专属养护方案二、清洁剂使用红黑榜三、家庭清洁实验:化学反应警示录四、保养实践方法论总结 前言 手环作为现代生活的智能伴侣,表带材质选择丰富多样。从柔软亲肤的皮质到耐用耐磨的金属&…...
人脸扫描黑科技:多相机人脸扫描设备,打造你的专属数字分身
随着科技的迅猛发展,人脸扫描这个词已经并不陌生,通过人脸扫描设备制作超写实人脸可以为影视制作打造逼真角色、提升游戏沉浸感,还能助力教育机构等领域生产数字人以丰富教学资源,还在安防、身份识别等领域发挥关键作用࿰…...
基于Python的中国象棋小游戏的设计与实现
基于Python的中国象棋小游戏的设计与实现 第一章 绪论1.1 研究背景1.2 研究意义 第二章 需求分析2.1 需求分析2.1.1核心功能需求2.1.2 用户体验需求2.1.3 衍生功能需求 2.2 可行性分析2.2.1 技术可行性2.2.2 经济可行性2.2.3 市场可行性2.2.4 法律与合规性 第三章 概要设计3.1 …...
简单好用的在线工具
用AI写了一些在线工具,简介好用,推荐给大家,欢迎大家使用并提议意见。 网址:https://www.bittygarden.com/ 目前已有以下功能: MD5SM3SHAUnicode 编码Unicode 解码Base32 编码Base32 解码Base64 编码Base64 解码URL …...
JAVA设计模式——(1)适配器模式
JAVA设计模式——(1)适配器模式 目的理解实现优势 目的 将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法一起工作的两个类能够在一起工作。 理解 可以想象成一个国标的插头,结果插座是德标的&…...
