从HarmonyOS升级到HarmonyOS NEXT-环信SDK数据迁移

news2024/11/15 8:25:41

2024年6月21日 HarmonyOS NEXT (后续称之为 NEXT) 正式发布,随着 NEXT 稳定版的逐渐临近,各个应用及SDK正在忙于适配 NEXT 系统,同样也面临着系统升级时如何对数据的迁移适配。本文通过使用环信 SDK 介绍如何从 HarmonyOS 系统升级到 NEXT 系统时,进行应用数据的迁移适配。

应用数据迁移步骤

官方文档

在进行数据迁移之前,我们需要先了解升级到NEXT系统,应用数据迁移需要进行哪些步骤。下图是整个迁移流程:

上图1-4步骤,均是由系统触发完成,开发者需要在第4步实现自定义的“BackupExtensionAbility”逻辑,实现自定义的数据恢复及转换逻辑。

1. HarmonyOS APK沙箱数据搬迁到中间目录

在升级的过程中,HarmonyOS系统会按照一定的规则,将应用的沙箱数据放置到四个数据目录中,然后这些数据会被整体压缩后搬迁到中间目录。

开发过程中,应用数据常用到的数据目录为:

/data/user/{userId}/{APK包名}/

/data/media/{userId}/Android/data/{APK包名}/

`/data/user/{userId}/{APK包名}/` 对应的路径为 HarmonyOS APK 应用的`data/data/{包名}`路径目录,而`/data/media/{userId}/Android/data/{APK包名}/`对应的是应用的`sdcard/Android/data/{包名}/`路径目录。应用进行数据迁移的话,主要是关注这两块的数据迁移。

2. 华为应用市场安装 NEXT 版本的应用

NEXT系统的“数据迁移框架”会从华为应用市场根据开发者账号下载对应的 NEXT 版本的应用。具体关联,请参考文档:HarmonyOS应用关联Android应用。

3. 数据导入

在NEXT 应用安装完成后,“数据迁移框架”将应用沙箱数据从中间目录搬迁到备份恢复目录。

APK应用沙箱目录与备份恢复目录映射关系见下表中所示:

APK应用沙箱目录

备份恢复目录

备份恢复目录获取方式

/data/user_de/{userId}/{APK包名}/

/data/storage/el1/base/.backup/restore/{APK包名}/de/

this.context.area = contextConstant.AreaMode.EL1;

let deSourcePath = this.context.backupDir + "restore/{APK包名}/de/"

/data/user/{userId}/{APK包名}/

/data/storage/el2/base/.backup/restore/{APK包名}/ce/

this.context.area = contextConstant.AreaMode.EL2;

let ceSourcePath = this.context.backupDir + "restore/{APK包名}/ce/"

/data/media/{userId}/Android/

data/{APK包名}/

/data/storage/el2/base/.backup/restore/{APK包名}/A/data/

this.context.area = contextConstant.AreaMode.EL2;

let dataSourcePath = this.context.backupDir + "restore/{APK包名}/A/data/"

/data/media/{userId}/Android/

obb/{APK包名}/

/data/storage/el2/base/.backup/restore/{APK包名}/A/obb/

this.context.area = contextConstant.AreaMode.EL2;

let obbSourcePath = this.context.backupDir + "restore/{APK包名}/A/obb/"

4. 数据转换
  • 在应用数据搬迁到备份恢复目录后,“数据迁移框架”向“备份恢复框架”发送应用数据恢复请求。

  • “备份恢复框架”拉起应用的“BackupExtensionAbility”独立进程,启动应用数据恢复。

  • 在“BackupExtensionAbility”独立进程中,开发者通过重写“onRestore”添加自定义逻辑,将备份恢复目录中的数据处理后保存到 NEXT 应用的沙箱中,完成应用的数据恢复。

  • “备份恢复框架”在应用数据恢复完成后,会清空备份恢复目录。

5. 启动 NEXT 应用,应用读取应用沙箱数据。

下面通过介绍环信 SDK 的数据迁移,来介绍具体的迁移过程。

需要迁移数据分析

以下为环信 SDK需要迁移的数据:

序号

数据名称

路径或者文件

备注

1

SDK 数据库文件夹

data/data/{包名}/files/easemobDB/

2

SDK 数据库相关文件夹

data/data/{包名}/files/easemobDBPW/

3

SDK 配置文件

data/data/{包名}/files/em_ap_config.json data/data/{包名}/files/em_config.json data/data/{包名}/files/server.json

4

SDK 附件

sdcard/Android/data/{包名}/{AppKey}/

  1. 环信 SDK 已经适配了在 NEXT 应用使用 HarmonyOS APK 数据库的逻辑。1 和 2 部分数据迁移到 NEXT的指定文件夹即可。

  2. 第 3 部分的配置文件直接迁移到NEXT的指定文件夹即可。

  3. SDK 的附件,有如下情况:

(1)消息中的本地路径存储的是 Uri 。

这部分是在公共媒体库中,进行系统的升级后,经咨询华为,目前还没有映射关系。目前的处理可以参照如下思路:

  • 判断本地文件不存在后,调用 `ChatManager#downloadAttachment` 或者 ChatManager#downloadThumbnail 方法从服务器下载文件资源后,然后再展示。

  • 如果服务器文件过期,需要展示默认图片。

(2)消息中的本地路径存储的是第 4 部分的文件路径,则需要对路径进行转换。举例如下:

迁移过来的数据库中存储的附件本地路径为:

/storage/emulated/0/Android/data/{包名}/{appKey}/files/{receiver id}/{sender id}/f6dc0580-6b68-11ef-bac3-2d7c12bc3033.jpg

需要转换为:

/data/storage/el2/base/{appKey}/files/{receiver id}/{sender id}/f6dc0580-6b68-11ef-bac3-2d7c12bc3033.jpg

  • 建议此步骤在展示附件时进行判断,并更新对应的localPath。

  • 如果转换后,文件仍不存在,则需要展示默认图片。

环境准备及工具要求

HarmonyOS NEXT Developer Beta1或之后版本的终端设备一部。

HarmonyOS 系统终端设备一部。

工具要求:

工具

版本

说明

“迁移调试”工具

205.0.0.115及之后版本

模拟验证数据迁移

DevEco Studio

DevEco Studio NEXT Developer Beta2及之后版本

请参考:DevEco Studio使用指南

Compatible SDK

5.0.0(12)

请参考:版本说明

注意:

“迁移调试”工具需要向华为申请获取。

HarmonyOS NEXT Developer Beta1及之后版本,厂商合作伙伴可通过IssueReporter平台提交工单,向华为方技术支持人员申请“迁移调试”工具,模拟进行数据迁移验证。公共开发者请通过“华为开发者联盟官网”->“支持”,在线提单方式获取。

HarmonyOS NEXT Developer Beta1之前版本,开发者可以通过系统内置“迁移调试”工具,模拟进行数据迁移验证。

BackupExtensionAbility实现

官方文档:BackupExtensionAbility的实现

1. 在entry/src/main/ets/目录下,点击 New > Directory 创建backupExtension目录。
2. 点击entry/src/main/ets/backupExtension/目录,点击 New > File 创建BackupExtension.ets文件。
3. 基于迁移环信SDK实现的BackupExtensionAbility示例代码。
import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit';
import { contextConstant } from '@kit.AbilityKit';
import fs from '@ohos.file.fs';
import { JSON } from '@kit.ArkTS';

const TAG = `BackupExtensionAbility`;

/**
 * serviceExt进程入口
 */
export default class BackupExtension extends  BackupExtensionAbility {
  onBackup () {
    console.log(TAG,`onBackup ok`);
  }

  /**
   * 数据恢复处理接口。接口是同步接口,其内部所有的异步操作请进行同步等待。
   *
   * @param bundleVersion 版本信息
   */
  async onRestore (bundleVersion : BundleVersion): Promise<void> {
    console.log(TAG, `onRestore ok ${JSON.stringify(bundleVersion)}`);
    if (bundleVersion.name.startsWith("0.0.0.0")){
      this.context.area = contextConstant.AreaMode.EL2;

      // 设置要迁移APK包的包名, 需要替换为需要迁移的APK的,下面为示例
      let apkPackageName = "com.xxx.xxx";

      let ceSourcePath = this.context.backupDir + `restore/${apkPackageName}/ce/`;
      let dataSourcePath = this.context.backupDir + `restore/${apkPackageName}/A/data/`;
     
      // 其中<USERID>当前固定为100, 参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/app-sandbox-directory-V5#应用沙箱路径和真实物理路径的对应关系
      const userId = 100;

      // 定义要迁移的APK沙箱目录
      let targetSDKSourcePath = ceSourcePath + "data/user/" + userId + "/" + apkPackageName + "/";
      if (fs.accessSync(targetSDKSourcePath)) {
        // 设置要迁移的APK files文件夹下的数据库文件夹
        const sdkDbDir = "easemobDB/";
        // 设置要迁移的APK files文件夹下的数据库附属文件夹
        const sdkDbPwdDir = "easemobDBPW/";
        // 设置要迁移的APK files文件夹下的SDK配置文件(4.3.0版本后有em_ap_config.json文件,之前版本的请忽略)
        const sdkConfigs = ["em_ap_config.json", "em_config.json", "server.json"];

        // 迁移 APK 沙箱目录 files 文件夹下的文件及文件夹到目标文件夹
        const fileDestDir = this.context.getApplicationContext().filesDir + "/";
        console.log(TAG, "fileDestDir: "+fileDestDir);
        console.log(TAG, "start to move db folder");
        await this.moveDirToTargetDir(targetSDKSourcePath + "files/" +sdkDbDir, fileDestDir + sdkDbDir);
        console.log(TAG, "end to move db folder");
        console.log(TAG, "start to move db pw folder");
        await this.moveDirToTargetDir(targetSDKSourcePath + "files/" +sdkDbPwdDir, fileDestDir + sdkDbPwdDir);
        console.log(TAG, "end to move db pw folder");
        sdkConfigs.forEach(async file => {
          const filePath = targetSDKSourcePath + "files/" + file;
          console.log(TAG, filePath + " to " + (fileDestDir+file));
          await this.moveFileToTargetPath(filePath, fileDestDir + file);
        })
      }
      let targetSDKDataSourcePath = dataSourcePath + "data/media/" + userId + "/Android/data/" + apkPackageName + "/";
      if (fs.accessSync(targetSDKDataSourcePath)) {
        // 设置要迁移 SD 卡下的的AppKey文件夹
        const sdkAppKeySourceDir = "easemob#easeim/";
        // 迁移 AppKey 文件夹到目标文件夹
        console.log(TAG, "start to move appkey folder");
        // 获取升级到 HarmonyOS NEXT 后SDK的目标文件夹路径
        const sdkDestDir = this.getTargetDestDir() + "/";
        console.log(TAG, sdkDestDir);
        await this.moveDirToTargetDir(targetSDKDataSourcePath + sdkAppKeySourceDir, sdkDestDir + sdkAppKeySourceDir);
        console.log(TAG, "end to move appkey folder");
      }
      // 在此处实现终端设备从HarmonyOS 4.0升级到HarmonyOS NEXT后,应用数据的转换和迁移
      // 涉及异步操作请进行同步等待
      console.log(TAG, `HarmonyOS to HarmonyOS NEXT scenario`);
    } else {
      // 在此处实现从HarmonyOS NEXT设备迁移到HarmonyOS NEXT设备后,应用数据的处理。无特殊要求,可以空实现
      // 涉及异步操作请进行同步等待
      console.log(TAG, `Other scenario`);
    }
  }

  async moveFileToTargetPath(sourcePath: string, destPath: string) {
    try {
      // 若mode为0,移动位置存在同名文件时,强制移动覆盖。
      await fs.moveFile(sourcePath, destPath);
    } catch (e) {
      console.log(TAG, "moveFileToTargetPath: " + JSON.stringify(e));
    }
  }

  async moveDirToTargetDir(sourceDir: string, destDir: string) {
    if (fs.accessSync(sourceDir)) {
      if (!fs.accessSync(destDir)) {
        fs.mkdirSync(destDir, true);
      }
    }
    try {
      // mode为2,文件级别强制覆盖。目标文件夹下存在与源文件夹名冲突的文件夹,若冲突文件夹下存在同名文件,则强制覆盖冲突文件夹下所有同名文件,未冲突文件将继续保留。
      console.log(TAG, sourceDir + " to " + destDir);
      await fs.moveDir(sourceDir, destDir, 2);
    } catch (e) {
      console.log(TAG, "moveDirToTargetDir: " + JSON.stringify(e));
    }
  }

  getTargetDestDir(): string {
    const filesDir = this.context.getApplicationContext().filesDir;
    console.log(TAG, "getTargetDestDir: "+filesDir);
    let lastPosition = filesDir.lastIndexOf('/files');
    return lastPosition != -1 ? filesDir.substring(0, lastPosition) : filesDir;
  }
}
4. 元数据资源配置

需要在 backup_config.json 文件中设置迁移场景,其他的元数据配置在本场景下不需要配置,示例如下:

{
  "allowToBackupRestore": true,
  "extraInfo": {
    "supportScene": [
      "hmos2next"
    ]
  }
}
5. 在 module.json5 中注册 BackupExtension

需要在 entry 内的module.json5里面进行注册,示例代码如下:

"extensionAbilities": [
  {
    "description": "DemoBackupExtension",
    "icon": "$media:app_icon",
    "name": "BackupExtensionAbility",
    "srcEntry": "./ets/backupExtension/BackupExtension.ets",  // 对应BackupExtension.ets在代码仓中的位置
    "type": "backup",                                         // 类型需要选择backup
    "exported": false,
    "metadata": [                                             // 对应注册的元数据资源
      {
        "name": "ohos.extension.backup",
        "resource": "$profile:backup_config"
      }
    ]
  }
]

开发者自验证

官方文档:开发者自验证

应用沙箱数据准备

APK 应用文件路径(从Android Studio的Device Explorer中看)与华为要求的准备的 APK 应用沙箱目录的映射关系:

APK 应用文件路径

APK 应用沙箱目录

data/data/{包名}/

/data/user/{userId}/{APK包名}/

sdcard/Android/data/{包名}/

/data/media/{userId}/Android/data/{APK包名}/

应用沙箱数据准备参考官方文档即可,以下是需要注意的事项:

     1. 准备好的应用沙箱文件需要整体放入到压缩包的目录下,例如:

/data/user/{userId}/{APK包名}/  放入到 {APK包名}/ce  后,目录路径为:{APK包名}/ce/data/user/{userId}/{APK包名}/

     2. 准备好的压缩包,可以通过 DevEco Studio -> Device File Browser  找到目标设备,找到手机的 Download 文件夹路径(/storage/media/100/local/files/Docs/Download/ ),右击 Download 文件夹,选择 “Upload…” 选中压缩好的压缩包。 

     3. 或者通过 hdc 命令,通过命令 hdc file send localPath/xxx.zip /storage/media/100/local/files/Docs/Download/xxx.zip 将文件从本地发送到手机。

NEXT 设备上模拟验证应用数据迁移
申请“迁移调试”工具

HarmonyOS NEXT Developer Beta1及之后版本,厂商合作伙伴可通过IssueReporter平台提交工单,向华为方技术支持人员申请“迁移调试”工具,模拟进行数据迁移验证。公共开发者请通过“华为开发者联盟官网”->“支持”,在线提单方式获取。

如果采取在线提单方式获取,可参考如下申请:

选择 `HarmonyOS NEXT -> HarmonyOS NEXT其他` 路径,申请格式为:

邮箱:

应用名称:

申请原因:

一般提单后,一天左右即可得到“迁移调试”工具的hap下载链接。

测试`BackupExtensionAbility`逻辑

按照官方文档进行调试时,点击启用迁移 按钮后,“迁移调试”工具会调起 NEXT 应用的`BackupExtensionAbility`独立进程,在这里会处理自定义的数据恢复操作。可以通过 DevEco Studio 的Log,选择backup进程({应用包名}:backup)查看迁移日志。可以在这一数据是否迁移成功。

其他
  1.  在数据迁移这一步,建议使用 mv  命令,文件的迁移效率要高于 copy  命令。
  2.  HarmonyOS应用关联Android应用。

端到端验证

在完成自验证步骤后,应用需要上架到华为应用市场,开发者需要模拟终端用户将终端设备从HarmonyOS升级到HarmonyOS NEXT的场景,端到端验证应用数据迁移结果。

具体步骤参考官方文档。

总结

经过“应用分析 -> 应用适配(含适配)-> 应用上架 -> 端到端验证”几个步骤最终完成应用数据的迁移,本文主要介绍的是 应用分析应用适配(含验证) 部分的介绍。希望本文可以帮助到正在和即将进行数据迁移的同学们。如果有需要探讨的地方可以在下方留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2152812.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计推荐-基于python大数据的个性化图书数据可视化分析

&#x1f496;&#x1f525;作者主页&#xff1a;毕设木哥 精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; 实战项目 文章目录 实战项目 一、个性化图书数据可视化分析-项…

带你0到1之QT编程:十四、QV/HBoxLayout和QStatckedWidget双剑合璧

此为QT编程的第十四谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; …

【我的 PWN 学习手札】tcache extend

目录 前言 一、利用手法 二、流程演示 &#xff08;1&#xff09;三块物理相邻的堆块 &#xff08;2&#xff09;溢出修改 size &#xff08;3&#xff09;释放该 chunk &#xff08;4&#xff09;重新申请该 chunk &#xff08;5&#xff09;释放第三块 chunk&#x…

算法-Init

&#xff08;1&#xff09;有限性&#xff08;Finiteness&#xff09;&#xff1a;算法必 需在有限步骤内结束&#xff1b; &#xff08;2&#xff09;确定性&#xff08;Definiteness&#xff09;&#xff1a;算法的每一个步骤必须清晰无歧义地定义&#xff1b; &#xff08;3…

科研入门学习

学习视频链接 为什么要读论文 读哪些论文 论文的分类 论文质量 如何找论文 根据领域大牛的名字进行搜索查看高水平论文引用的论文&#xff0c;高水平论文引用的论文很大程度也是高水平的论文 如何整理论文 如何读论文 读论文的困境 不同人群阅读差异 读论文的方式 论文的结构…

叉车限速器外接LED屏,监督厂区安全,让速度慢下来!

叉车限速器外接LED屏&#xff0c;可实时显示当前叉车行驶中的速度&#xff0c;单/双面电子显示屏供用户选择&#xff0c;方便企业人员监控司机当前行驶速度&#xff0c;当速度超过指定值时&#xff0c;叉车速度报警系统发出声光警示&#xff0c;提醒行人、司机&#xff0c;超速…

【ArcGIS微课1000例】0121:面状数据共享边的修改方法

文章目录 一、共享边概述二、快速的修改办法1. 整形共享边2. 修改边3. 概化边缘一、共享边概述 面状数据共享边指的是两个或多个面状数据(如多边形)共同拥有的边界。在地理信息系统(GIS)、三维建模、大数据分析等领域,面状数据共享边是描述面状空间数据拓扑关系的重要组成…

C / C++的内存管理

前言 Hello&#xff0c;我又回来了&#xff0c;今天我们将继续学习C部分&#xff0c;今天我们将承接前面的知识&#xff0c;继续学习C的内存管理&#xff0c;今天的内容较为重要&#xff0c;所以我们废话不多说&#xff0c;我们还是按例三连上车&#xff0c;开始我们今天内容&…

【图灵完备 Turing Complete】游戏经验攻略分享 Part.4 处理器架构

比较有难度的一个部分。 运算单元ALU&#xff0c;其实就是通过OP选择计算方式&#xff0c;然后选通某个计算&#xff0c;之后输出。每个计算逐个实现就行了。 下面是一个优化占地面积的ALU&#xff0c;变得紧凑了一点。 下面是一个简单的OP选通原理线路。判断是立即数寻址&…

吹爆吊打 GPT-4 的大模型新王者Reflection 70B,是否言过其实?

引言 一觉睡西天&#xff0c;谁知梦里乾坤大。只身眠净土&#xff0c;只道其中日月长。 小伙伴们好&#xff0c;我是微信公众号《小窗幽记机器学习》的小编&#xff1a;卖铁观音的小男孩。今天这篇小作文主要介绍这几天网上狂吹的开源新晋王者Reflection 70B&#xff0c;该模型…

【医疗大数据】医疗保健领域的大数据管理:采用挑战和影响

选自期刊**《International Journal of Information Management》**&#xff08;IF:21.0) 医疗保健领域的大数据管理&#xff1a;采用挑战和影响 1、研究背景 本研究的目标是调查阻止医疗机构实施成功大数据系统的组织障碍&#xff0c;识别和评估这些障碍&#xff0c;并为管理…

Qemu开发ARM篇-1、环境搭建篇

文章目录 1、目标2、欢迎来到qemu世界3、开发环境4、依赖安装5、编译安装qemu 1、目标 我们的目标是在x86平台上搭建上arm开发环境&#xff0c;及在x86平台模拟一台arm设备&#xff0c;以达到能快速在x86平台上学习arm相关知识&#xff0c;如uboot启动、kernel开发调试等&…

实时美颜的技术突破:视频美颜SDK与直播美颜工具的开发详解

如今&#xff0c;视频美颜SDK和直播美颜工具的开发&#xff0c;为各类应用提供了技术支持&#xff0c;使得美颜效果更加智能、高效。本文将详细探讨实时美颜的技术突破及其在视频美颜SDK和直播美颜工具中的应用与开发。 一、视频美颜SDK的核心技术 1.人脸检测与特征点识别 视…

稀土抗紫外屏蔽剂在涂层中的应用

稀土抗紫外屏蔽剂的主要作用是有效地吸收或阻挡紫外线&#xff0c;从而保护材料或表面免受紫外线的伤害&#xff0c;延长其使用寿命。 稀土抗紫外屏蔽剂在涂层上的应用具有以下显著优势&#xff1a; 1. 增强涂层的耐久性&#xff1a;稀土抗紫外屏蔽剂能够有效吸收和散射紫外线…

Linux常用命令(部分学习待继续补充)

pwd print working directory 打印当前的工作目录 / 根目录 ls list 列出当前目录下的所有文件 ls / ls -h(human) ls -l(long) cd change directory 更改目录 cd … 回到上一级目录 ls list ls -l 会列出文件的详细信息 第一个字符是-表示普通文件 d表示是一个目录 rwx read …

load jsonl File with OpenAI API request results to pandas data.frame

题意&#xff1a;将包含 OpenAI API 请求结果的 jsonl 文件加载到 pandas DataFrame 中 问题背景&#xff1a; I have a large data set containing around 500k observation. It has a string variable that I want to create an embedding for. I used the OpenAI API to cr…

【练习15】拼三角

链接&#xff1a;A-拼三角_牛客小白月赛32 (nowcoder.com) 分析&#xff1a; 三角形的三个边a、b、c必须满足条件&#xff1a;ab>c,ac>b,bc>a 可以先将输入的六个数按从小到大排序&#xff0c;然后再枚举。 因为已经排好序了&#xff0c;如果第一行ab<c&#xff0c…

LeetCode2414题: 最长的字母序连续子字符串的长度(原创)

【题目描述】 字母序连续字符串 是由字母表中连续字母组成的字符串。换句话说&#xff0c;字符串 "abcdefghijklmnopqrstuvwxyz" 的任意子字符串都是 字母序连续字符串 。 例如&#xff0c;"abc" 是一个字母序连续字符串&#xff0c;而 "acb" 和…

Linux启动流程,0,1,2进程,init进程,idle进程,内核态到用户态的kernel_execve(一)

&#xff1f;是&#xff0c;如果定义了&#xff0c;就按Makefile的&#xff0c;如果如下make编译时&#xff0c;就按如下 linux内核入口 进程0在用户空间看不到&#xff0c;因为他是内核进程 进程2就是守护进程&#xff0c;维护内涵运转的 一生二&#xff0c;二生三&#xff…

【网络安全的神秘世界】攻防环境搭建及漏洞原理学习

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 Kali安装docker 安装教程 PHP攻防环境搭建 中间件 介于应用系统和系统软件之间的软件。 能为多种应用程序合作互通、资源…