OpenHarmony实战开发-文件上传下载性能提升指导。

news2024/11/17 13:56:31

概述

在开发应用时,要实现高效的客户端跟服务器之间数据交换,文件传输的性能是至关重要的。一个数据交换性能较低的应用会导致其在加载过程中耗费较长时间,在很多的场景造成页面卡顿,极大的影响了用户体验。相反,一个数据交换高效的应用,则会让应用变得更加流畅。

本文将介绍两种常见的上传下载传输和网络请求的关键技术:数据压缩和断点续传,可提升上传下载的性能、减少宽带占用,从而提高数据传输效率。

上传下载接口

目前系统内提供给文件上传下载可用的模块有@ohos.net.http模块和@ohos.request模块。@ohos.net.http模块提供基础的HTTP数据请求能力,功能较为基础,本文不做介绍。@ohos.request模块主要给应用提供上传下载文件、后台传输代理的基础能力。它具备任务管理系统的默认并发功能,简化下载功能的实现和管理,提升数据传输的安全,整合通知机制,新增任务状态与进度查询功能,具有灵活性、高效性、可扩展性、可靠性、一致性和安全性的优势。

具体来说,@ohos.request模块包括以下功能:

  1. 任务管理:任务管理操作包括创建任务、暂停任务、恢复任务、删除任务、文件上传、文件下载、系统通知等。创建的任务分为前端任务和后台任务。前端任务是立即的、模态界面的、同步的,跟随应用的生命周期,通常数据量较小、耗时短,例如发布微信朋友圈、微博,通常优先级高且倾斜带宽资源。后台任务为可等待的、任意界面的、异步的,通常数据量较大、耗时长,例如缓存一部电影、同步数百兆字节乃至若干吉字节的数据,优先级相较于前端任务低且与应用生命周期无关。
  2. 任务查询管理:系统查询所有任务、过滤上传任务、过滤下载任务、过滤时间段内任务、过滤前端任务、过滤后台任务、用户查询指定任务信息、用户查询指定隐藏任务信息、系统查询指定任务信息、系统清理指定任务等。
  3. 任务自动恢复:网络条件不满足时任务不启动或者暂停,满足后自动启动或者恢复(需要HTTP服务器支持断点续传)。
  4. 安全隐私保护:包括网络权限检查、普通接口仅操作自己创建的任务、任务信息加密存储、系统接口检查、系统接口查询隐匿任务敏感字段、普通接口查询隐匿任务敏感字段、遍历攻击、DOS、僵尸任务、恶意的静默后台任务、系统管理接口权限等。
  5. 日志:包括调试模式和发布模式。调试模式可打印所有内存修改、磁盘、网络读写、逻辑分支等日志。发布模式下除了导致任务失败、服务异常的日志,其余日志都会关闭。
  6. 任务失败重试:对于不可恢复的原因,直接失败;对于可恢复的原因,网络断开、网络类型不匹配等,不现场重试,任务到等待网络恢复队列;网络超时则就地重试1次,仍网络超时,则立即失败。
  7. 服务按需启停:上传下载服务不随系统自启。应用主动调用任意接口,上传下载服务自动启动。网络连接事件会触发上传下载服务启动。在任务队列中,没有正在处理的任务,或者等待网络恢复的任务,延迟10秒钟,再check一次,仍旧没有的,则通知系统服务框架(SAMGR)可以停止并卸载上传下载服务。在服务退出过程中,新的接口请求可能失败,在客户端检查服务状态、通过重试按需启动。
  8. 通知:任务从第一次开始到最终结束都应该有进度通知。目前采用固定时间间隔触发进度通知,前台任务1秒,后台任务3秒。任务状态的每次变化也要触发进度通知。当任务完成和失败,则触发其专用的进度通知。提供了抑制开关,可以在创建任务时打开,以避免频繁通知。

下载任务的状态迁移流程

使用@ohos.request模块执行下载的任务,具有四种运行状态:初始任务、就绪任务、挂起任务、待网任务、成功任务、失败任务。可以通过create创建任务,start开始任务,pause挂起任务,resume恢复任务,remove移除任务,stop停止任务,任务结果有final-failed任务失败,final-completed下载完成,recoverable-failed重试失败,并支持查询任务状态,具体流程如图一所示:

图一 模块流程图
在这里插入图片描述

常见场景与方案

场景1:低带宽网络上传琐碎文件场景

在网络连接较差,低带宽的网络环境中,HTTP连接的建立耗时可能会大幅提升。这时候进行数据压缩可以加快页面加载速度,并减少HTTP请求数量和移动数据流量。

场景2:处理大量资源的场景

如应用商店、网盘应用等,这类应用通常拥有大体积的文件资源。当用户从暂停或者断网中重新恢复时,如果从头开始上传下载则会额外耗费大量的时间。此时可以采用断点续传方法进行上传下载。

数据压缩

数据压缩是指在应用中对数据进行压缩,以减少存储空间和数据传输量、节省带宽,提高加载速度。数据压缩通常在网络传输和存储方面发挥着重要作用,特别是在处理大量数据或需要频繁传输数据的场景下。

在应用开发中,常见的数据压缩技术分类如下:

  • 有损压缩:仅限图片视频音频等文件适用。通过减少图片视频文件的分辨率,降低音频的音质等手段,以减少文件的大小,来实现减少加载时间和带宽消耗。
  • 无损压缩:对一些零碎文件可以使用@ohos.zlib(Zip模块)来进行打包压缩,减少上传请求次数;对一些大文件可以利用缓存技术,服务器将曾经上传过的大文件MD5码缓存起来,本地在上传前预生成MD5码并传输到服务器进行比对,如果相同则说明服务器存在该文件,可以跳过该文件上传,从而省略重复传输时间。

以从相册批量上传图片为例,介绍大量文件打包无损压缩上传相关技术,下图为相关示例的界面截图:

图二 相册批量上传图片示例图
在这里插入图片描述

以批量上传照片(分辨率为480*640,24位,平均大小50~120KB)为例,在RK设备上测试的结果如下表所示:
在这里插入图片描述

图三 上传数量和耗时对比图表
在这里插入图片描述

由于上传耗时收到网络状态影响偏差较大,结果取的几次测量结果的最小值。但是仍然可以从数据中看出,优化前的耗时基本为线性增长,压缩优化后的耗时在上传文件数量较低时并不明显,还会因为多余的压缩处理影响耗时。不过随着上传的照片数量增多,优化后的耗时和优化之前的耗时差距越来越明显,优化效果越好。

数据压缩的相关示例代码如下:

1.导入相关模块:

import common from '@ohos.app.ability.common';
import fs from '@ohos.file.fs';
import zlib from '@ohos.zlib';

2.创建压缩上传相关类:

class ZipUpload {
  // 创建任务前存放的uri
  private waitList: Array<string> = [];
  // 需要上传的文件uri
  private fileUris: Array<string> = [];
  ...
}

3.建立用于接收图库图片的临时文件夹,并将整个临时文件夹打包添加到待上传list内:

// 文件压缩处理
async zipUploadFiles(fileUris: Array<string>): Promise<void> {
  this.context = getContext(this) as common.UIAbilityContext;
  let cacheDir = this.context.cacheDir;
  let tempDir = fs.mkdtempSync(`${cacheDir}/XXXXXX`);
  // 将图库图片获取的uri放入fileUris中,遍历复制到临时文件夹
  for (let i = 0; i < fileUris.length; i++) {
    let fileName = fileUris[i].split('/').pop();
    let resourceFile: fs.File = fs.openSync(fileUris[i], fs.OpenMode.READ_ONLY);
    fs.copyFileSync(resourceFile.fd, `${tempDir}/${fileName}`, 0);
    fs.closeSync(resourceFile);
  }
  // 文件压缩,将之前生成的临时文件夹内打包到test.zip内
  let options: zlib.Options = {
    level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION,
    memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT,
    strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY
  };
  let data = await zlib.compressFile(tempDir, `${cacheDir}/test.zip`, options);
  // 删除临时文件夹
  fs.rmdirSync(tempDir);
  // 将生成的zip包放到传输队列
  this.waitList.push(`${cacheDir}/test.zip`);
}

断点续传

断点续传功能的实现,不管是应用端还是服务器端都需要用到合理的技术来互相协同。在实际开发中,开发者无需亲自实现断点续传功能,只需对SDK进行合理配置。

在应用端需要用到的技术和API:

  • @ohos.file.fs(文件管理):用于处理文件上传操作,提供了读取文件内容,文件分片和组合的功能。
  • @ohos.file.hash(文件哈希处理):用于实现文件MD5的计算,将计算的MD5值预先传到服务器端进行预处理,实现文件秒传,同时确保传输的准确性和可靠性。
  • @ohos.request(上传下载):用于实现文件上传操作,并支持在上传过程中的断点续传功能。

在服务器端需要用到的技术:

  • 协议需要支持Range:用于在服务器端支持范围请求,方便处理文件上传下载断点续传功能。
  • 文件校验相关逻辑:需要实现校验文件是否有错,确保在传输中断后能够准确恢复并继续传输。

通过结合应用端和服务器端的相关技术,可以共同实现高效且可靠的文件断点续传功能,提供更好的用户体验并确保数据传输的稳定性。

文件上传

对于大文件断点续传上传,本文采用@ohos.request(上传下载)模块中的request.agent任务托管接口,可以自动实现暂停继续重试等操作,无需手动将文件分片和记录上传分片信息。流程图如图四所示:

图四 断点续传上传流程图
在这里插入图片描述

断点续传上传示例代码如下:

1.导入相关模块:

import common from '@ohos.app.ability.common';
import request from '@ohos.request';

1.创建相关上传类:

class Upload {
  // 后台任务
  private backgroundTask: request.agent.Task | undefined = undefined;
  // 创建任务前存放的uri
  private waitList: Array<string> = [];
  ...
}

1.生成MD5码,上传到服务器进行校验:

async checkFileExist(fileUri: string): Promise<boolean> {
  let httpRequest = http.createHttp();
  // 生成md5码
  let md5 = await hash.hash(fileUri, 'md5');
  let requestOption: http.HttpRequestOptions = {
    method: http.RequestMethod.POST,
    extraData: {
      'MD5': md5
    }
  }
  let response = await httpRequest.request('http://XXX.XXX.XXX.XXX/XXXX', requestOption);
  let result = response.result;
  let flag = false;
  ... // 根据服务器返回对应数据判断是否存在
  if (flag) {
    return true;
  } else {
    return false;
  }
}

1.配置Config,创建后台上传任务:

private config: request.agent.Config = {
  action: request.agent.Action.UPLOAD,
  headers: HEADER,
  url: '',
  mode: request.agent.Mode.BACKGROUND,
  method: 'POST',
  title: 'upload',
  network: request.agent.Network.ANY,
  data: [],
  token: 'UPLOAD_TOKEN'
}
...
// 转换uri
private async getFilesAndData(cacheDir: string, fileUris: Array<string>): Promise<Array<request.agent.FormItem>> {
...
}
// 创建文件上传后台任务
async createBackgroundTask(fileUris: Array<string>) {
 // 获取上传url
  this.config.url = 'http://XXX.XXX.XXX.XXX';
  this.config.mode = request.agent.Mode.BACKGROUND;
  let tempData = await this.getFilesAndData(this.context.cacheDir, fileUris);
  // 判断每个文件是否为空
  for (let i = 0; i < tempData.length; i++) {
    let flag = await this.checkFileExist(`${this.context.cacheDir}/${tempData[i].name}`);
    if (!flag) {
      this.config.data.push(tempData[i])
    }
  }
  let isFileExist = await this.checkFileExist(`${this.context.cacheDir}/${this.config.data[0].name}`);
  if (this.config.data.length === 0) {
    return;
  }
  this.backgroundTask = await request.agent.create(this.context, this.config);
}

1.任务开始:

await this.backgroundTask.start();

1.任务暂停:

async pause() {
  if (this.backgroundTask === undefined) {
    return;
  }
  await this.backgroundTask.pause();
}

1.任务继续:

async resume() {
  if (this.backgroundTask === undefined) {
    return;
  }
  await this.backgroundTask.resume();
}

文件下载

对于大文件断点续传下载,也可以直接调用request.agent接口,该接口的断点续传是基于HTTP协议Header里的Range字段实现的,在任务暂停重启的时候,会自动设置Header中的Range字段,无需进行额外的配置。

Range简介

HTTP协议里面的Range字段,官方名称为范围请求,它允许服务器只发送 HTTP
消息的一部分到客户端,可以用来请求部分数据而不是整个资源。

Range的格式通常是Range:
=-,其中表示范围所采用的单位,通常是字节(bytes), 和
表示请求的起始字节和结束字节的位置。

Range语法如下:

// 表示从range-start到文件末尾 Range: =- //
表示从range-start到range-end Range: =- //
可以同时选择多段,用逗号分隔 Range: =-,
- // 示例:表示返回1024 bytes之后的文件 Range: bytes=1024-

服务器收到请求后,正确处理请求会回复206 Partial Content,未正常处理则会回复其他响应码。下表是服务器回复的常见响应码:

服务器响应码常见的原因206 Partial Content服务器收到正常Range请求的响应码,返回部分内容的响应。416 Range
Not Satisfiable所请求的范围不合法,表示服务器错误。200 OK服务器忽略了 Range 首部,返回整个文件。

断点续传下载示例代码如下:

1.导入模块:

import common from '@ohos.app.ability.common';
import request from '@ohos.request';

2.创建下载类:

class Download {
  // 任务存放前的uri
  private waitList: Array<string[]> = [];
  // 下载任务
  private downloadTask: request.agent.Task | undefined = undefined;
  // 后台任务下载列表
  private backgroundDownloadTaskList: Array<request.agent.Task> = [];
  ...
}

3.配置Config,创建后台下载任务:

async createBackgroundTask(downloadList: Array<string[]>) {
  let splitUrl = url.split('//')[1].split('/');
  let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
  let downloadConfig: request.agent.Config = {
    action: request.agent.Action.DOWNLOAD,
    url: url,
    method: 'POST',
    title: 'download',
    mode: request.agent.Mode.FOREGROUND, // 必须是后台任务才能续传
    network: request.agent.Network.ANY,
    saveas: `./${folder}/${splitUrl[splitUrl.length-1]}`,
    overwrite: true
  }
  this.downloadTask = await request.agent.create(context, downloadConfig);
  if (this.backgroundDownloadTaskList.findIndex(task => task.config.url === downTask.config.url) === -1) {
    this.backgroundDownloadTaskList.push(downTask);
  }
}

4.任务开始:

...
await downTask.start();
...

5.任务暂停:

async pause() {
  if (this.backgroundDownloadTaskList.length === 0) {
    return;
  }
  this.backgroundDownloadTaskList.forEach(async task => {
    await task.pause();
  })
}

6.任务继续:

async resume() {
  if (this.backgroundDownloadTaskList.length === 0) {
    return;
  }
  this.backgroundDownloadTaskList.forEach(async task => {
    await task.resume();
  })
}

7.任务停止:

async deleteAllBackTasks() {
  if (this.backgroundDownloadTaskList.length > 0) {
    this.backgroundDownloadTaskList.forEach(async task => {
      await request.agent.remove(task.tid);
    })
    this.backgroundDownloadTaskList = [];
  }
}

如果大家还没有掌握鸿蒙,现在想要在最短的时间里吃透它,我这边特意整理了《鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程》以及《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

OpenHarmony APP开发教程步骤:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

《鸿蒙开发学习手册》:

如何快速入门:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.基本概念
2.构建第一个ArkTS应用
3.……

在这里插入图片描述

开发基础知识:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

鸿蒙生态应用开发白皮书V2.0PDF:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

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

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

相关文章

【进程地址空间】地址空间理解存在原因 | 深入理解页表写时拷贝虚拟地址

目录 地址空间深入理解 划分区域 理解地址空间 地址空间存在的意义 意义1 意义2 意义3 理解页表和写时拷贝 页表 写时拷贝 OS识别错误 理解虚拟地址 fork解释 上篇我们简单的学习了进程地址空间/页表/物理地址/虚拟地址/写时拷贝等概念。本篇深入理解下。 地址空…

分数求和(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;double a 0, b 1, result1 2, sum 0;int i 0;//循环运算&#xff1b;for (i 1; i <…

人工智能大模型培训老师叶梓 探索知识库问答中的查询图生成:处理多跳复杂问题的新方法

在人工智能领域&#xff0c;基于知识库的问答&#xff08;KBQA&#xff09;技术正变得越来越重要。它使得机器能够理解自然语言问题&#xff0c;并从结构化的知识库中检索答案。然而&#xff0c;面对多跳复杂问题&#xff0c;传统的KBQA方法往往力不从心。近期&#xff0c;研究…

Threejs绘制传送带

接下来会做一个MES场景下的数字孪生&#xff0c;所以开始做车间相关的模型&#xff0c;不过还是尽量少用建模&#xff0c;纯代码实现&#xff0c;因为一方面可以动态使用&#xff0c;可以调节长度和宽度等&#xff0c; 下面这节就做一个简单的传送带&#xff0c;这是所有车间都…

C++心决之类和对象详解(中篇)(封装入门二阶)

目录 1.类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3.析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 5.赋值运算符重载 5.1 运算符重载 5.2 赋值运算符重载 5.3 前置和后置重载 7.const成员 8.取地址及const取地址操作符重载 1.类的…

Win 进入桌面黑屏,只有鼠标

大家好&#xff0c;我叫秋意零。 今天&#xff0c;遇到一个同事电脑进入桌面黑屏&#xff0c;只有鼠标。经过询问沟通&#xff0c;说是 Windows 突然进行了自动更新&#xff0c;更新之后桌面就黑了屏。经过查询是一个桌面进程没启动才会导致桌面黑屏。首先分两种情况&#xff0…

【linux】软件工具安装 + vim 和 gcc 使用(上)

目录 1. linux 安装软件途径 2. rzsz 命令 3. vim 和 gcc 使用 a. vim的基本概念 b. 命令模式下的指令 c. 底行模式下的指令 1. linux 安装软件途径 源代码安装rpm安装 -- linux安装包yum安装&#xff08;最好&#xff0c;可以解决安装源&#xff0c;安装版本&#xff0…

ArrayList与顺序表(1)

前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&#x…

使用matplotlib的quiver绘制二维箭头图

使用ax.quiver绘制二维箭头图 1. matplotlib的quiver函数的调用方式 quiver函数是axes类的成员函数&#xff0c;其基本调用方式为&#xff1a; quiver([X, Y], U, V, [C], **kwargs) [X,Y]是箭头的位置&#xff0c;U,V是箭头的方向&#xff0c;C是箭头颜色。 具体而言&#x…

多项式轨迹规划

公众号“轻松玩转机器人”&#xff0c;欢迎关注。 1、简介 常用的多项式规划一般泛指3次、5次和7次等多项式规划&#xff0c;4次多项式规划用到的比较少&#xff0c;暂不介绍。 为什么奇数次多项式比较常用呢&#xff1f;因为其有偶数个系数&#xff01; 偶数个系数有什么用…

泛型的初步认识(1)

前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&#x…

Unity中的UI系统之UGUI

目录 概述UGUI基础——六大基础组件六大基础组件概述Canvas画布组件CanvasScaler画布缩放控制器组件必备知识恒定像素模式缩放模式恒定物理模式3D模式 Graphic Raycaster图形射线投射器EventSystem和Standalone Input ModuleRectTransform UGUI基础——三大基础控件Image图像控…

【解决】Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed

问题原因&#xff1a; 在Java8及高版本以上的版本在源应用程序不信任目标应用程序的证书&#xff0c;因为在源应用程序的JVM信任库中找不到该证书或证书链。也就是目标站点启用了HTTPS 而缺少安全证书时出现的异常 解决方案&#xff1a; 我使用的是忽略证书验证 public clas…

vs code server for wsl closed unexpectedly

前言&#xff1a; 我的Windows 版本&#xff1a; 10.0.19045.4291 &#xff08;如果你是Win11或者你要使用WSL2请谨慎&#xff09; 之前是可以用的&#xff0c;但安装Vmware&#xff08;并安装了Ubuntu进行了一番实验后&#xff0c;就出现如标题所述问题&#xff09; 问题&a…

内存满了如何处理?

目录 虚拟内存 内存分配过程 直接内存回收和后台内存回收 回收内存的触发标准 那些内存被回收呢? 内存回收后,内存还是不够怎么办呢? 虚拟内存 介绍操作系统内存如何使用时,不可以避免的先认识到虚拟内存 首先我们通过虚拟内存的作用,来认识一下: 1.虚拟内存可以使得…

基础SQL DML-插入语句

插入语句前&#xff0c;我们先创建一个表。表的创建在DDL语句里面涉及&#xff0c;可以参考&#xff1a;小赖同学吖-CSDN博客 我们创建一个员工表进行数据的插入操作 插入&#xff08;添加&#xff09;语句的语法 给员工表添加一条记录 给员工表添加多条记录 也可以通过下面的方…

Python 面向对象——2.类与对象实例属性补充解释,self的作用等

本章学习链接如下&#xff1a; Python 面向对象——1.基本概念 实例的属性 1.创建对象 在上一小节的学习中我们提到了类中的变量与函数变量的区别&#xff0c;self.param1和param1&#xff0c;接下来我们继续详细解释这个知识点。 当我们创建一个学生的类&#xff0c;比如…

铜缆与网线:数字时代的信息高速公路

在现代社会&#xff0c;信息传输已成为日常生活的重要部分。从个人通信到全球数据中心&#xff0c;铜缆和网线扮演着至关重要的角色。本文将详细介绍铜缆和网线的类型、特点以及它们在数字时代的应用。 铜缆的种类与应用 铜缆的类型 UTP&#xff08;无屏蔽双绞线&#xff09;&…

登录的几种方式

一、session 1、客户端发送请求&#xff0c;服务器将登录信息存储在 Session 中&#xff0c;Session 依赖于 Cookie&#xff08;cookie指的就是在浏览器里面存储的一种数据&#xff0c;仅仅是浏览器实现的一种数据存储功能。Cookie实际上是一小段的文本信息。&#xff09;&…

Arthas介绍及使用技巧

文章目录 简介能做什么&#xff1f; 使用下载并启动arthas选择应用 java 进程退出 arthas 常用查看命令帮助查看 dashboard通过 thread 命令来获取到线程的栈通过 jad 来反编译 Classwatch 查看方法出入参、sc 搜索类: 查看已加载类所在的包monitor 方法执行监控trace 方法内调…