当前位置: 首页 > news >正文

SpringBoot中整合ONLYOFFICE在线编辑

SpringBoot整合OnlyOffice

  • SpringBoot整合OnlyOffice实现在线编辑
    • 1. 搭建私有的OnlyOffice的服务
    • 2. SpringBoot进行交互
      • 2.1 环境
      • 2.2 我们的流程
      • 2.3 接口规划
        • 2.3.1 获取编辑器配置的接口
        • 2.3.2 文件下载地址
        • 2.3.3 文件下载地址
    • 3. 总结
      • 4. 注意
        • 4.1 你的项目的地址一定一定要和onlyoffice可以正常通讯,如果不行则一直不可能成功。
        • 4.2 TOKEN是可以可选项,建议一开始不要使用,后面有需要的时候再去添加。
        • 4.3 一定要看一下官网文档,文档真的很全很重要
        • 4.4 协同的话只要参数就是一个KEY,如果需要超过20个的限制直接重新编译即可,大神一大堆,很容易就可以找到。

SpringBoot整合OnlyOffice实现在线编辑

公司有一个需求,就是实现 *Word* , *Excel* ,等文件的在线编辑,市场上面进行了多方面的选型,考虑了 *[OpenOffice](https://openoffice.apache.org/)* , *[Office Online](https://www.microsoft.com/zh-cn/microsoft-365/free-office-online-for-the-web?legRedir=true&CorrelationId=13c8a865-b9b0-48ff-b3ed-3ea9ec31cd55)*, 但是最终还是选择了 *[OnlyOffice](https://www.onlyoffice.com/zh/)* 这个产品。
他的一个很大的优势在于开源,支持协同,社区比较活跃。api比较全面,还有中文的文档。还有一点比较好的就是支持协同,并且支持协同,虽然协同在社区版中存在限制,但是支持代码修改,可以重新编译。社区的大佬很多,很赞。唯一遗憾的就是效率比较低,在使用私有对象存储的时候存在延迟。其他的没有使用到,所以不进行评论。中文文档:[https://api.onlyoffice.com/zh/editors/basic](https://api.onlyoffice.com/zh/editors/basic)

1. 搭建私有的OnlyOffice的服务

搭建过程这里就不进行涉猎了,建议使用docker进行搭建,下载官方镜像包即可,(现在dockerhub被墙,自行解决,不建议自己再次打包,因为我在尝试的时候总是出现莫名奇妙的问题可能是我的问题。推荐使用官网原版镜像)。根据官方文档一步步操作即可。搭建过程中,如果是自己玩建议不要开启 **JWT** ,生产环境建议开一下。但是开的成本就是你对接的时候需要获取token然后在进行交互。

2. SpringBoot进行交互

2.1 环境

java: 17
boot: 3.0.5
页面:一个h5页面即可
需要的其他依赖

<!-- ... 其他的依赖自行添加即可,不重要,比如 fastjson2,jackson 等 --><!-- 这个JAR 主要的作用是与OnlyOffice交互的时候生成token使用的 -->
<dependency><groupId>com.inversoft</groupId><artifactId>prime-jwt</artifactId><version>1.3.1</version></dependency>

2.2 我们的流程

我们使用一个 H5 页面即可,页面通过加载一个 app.js 。然后通过一个 config 进行渲染,就可以实现一个编辑。app.js 是核心js文件

  1. only office 我只使用他的一个编辑的功能(这是一个核心,就是编辑文件,文件的来源和存储与它无关)
  2. 被编辑的文件从哪里获取?从 config 对象中的配置获取,这里就需要自行实现。
  3. 编辑后的文件如何获取?config对象中有一个回调地址,这个地址会给到服务器一个编辑的状态,并且携带一个获取编辑后文件的url(这个url就是only office 服务中的一个文件下载地址),根据这个url来获取编辑后的文件。然后在对这个文件进行存储。
    回调的实现参考:https://api.onlyoffice.com/zh/editors/callback#status

在这里插入图片描述

2.3 接口规划

一共设计三个接口,

  1. 获取编辑器的配置
  2. 获取需要编辑的文件流
  3. 编辑后保存文件的回调
    保存后的文件:注意,这里编辑后的文件并不是在回调里面以流的形式给,而是在回调接口里面给服务器一个状态,根据状态去获取一个下载编辑后文件的一个地址,然后根据地址去主动的获取文件。
2.3.1 获取编辑器配置的接口

/*** 被编辑文件的下载连接* 这里就是自己服务的配置地址* only office 调用你的服务的地址,一定是 onlyoffice服务可以ping通的你的项目地址。ping不通=白搭*/
@Value("${only.office.downUrl}")
private String downFileUrl = "";
/*** 这里是回调地址:例如 http://192.168.0.10:8080/office/edit/callback/{fileId}* 自行定义即可(就是后面自己编写的接口,但是一定要通可onlyoffice服务互通)* only office 调用你的服务的地址,一定是 onlyoffice服务可以ping通的你的项目地址。ping不通=白搭*/
@Value("${only.office.callBackUrl}")
private String editCallBackUrl = "";@Operation(summary = "根据文件的ID来获取在线编辑的配置和token")
@PostMapping("/token/{fileId}")
@Parameters({@Parameter(name = "fileId", description = "不是对象ID是文件的ID", in = ParameterIn.PATH)
})
public ResultVo<?> getToken(@PathVariable String fileId) {String fileKey ;if (redisUtil.hHasKey(RedisName.ONLY_OFFICE_FILE_KYE,fileId)) {fileKey = redisUtil.hget(RedisName.ONLY_OFFICE_FILE_KYE,fileId).toString();//return ResultVo.error(CustomExceptionType.ONLY_OFFICE_COORDINATION_ERROR);}else{fileKey = fileId + RandomUtil.randomNumbers(10);}String json = """{"document": {"title": "%s","key": "%s","fileType":"%s","lang": "zh-CN","permissions": {"comment": true,"commentGroups": {"edit": ["Group2", "Group1"],"remove": [""],"view": ""},"copy": true,"deleteCommentAuthorOnly": false,"download": true,"edit": true,"editCommentAuthorOnly": false,"fillForms": true,"modifyContentControl": true,"modifyFilter": true,"print": true,"review": true,"reviewGroups": ["Group1", "Group2", ""]},"url": "%s"},"editorConfig": {"customization":{"autosave": true,"forcesave": true}"lang": "zh-CN","callbackUrl": "%s","onEditing": {"mode": "fast","change": true},"mode": "edit","user": {"group": "Group1","id": "%s","name": "%s"}}}""";// TODO 这里文件的key可以通过redis进行保存,这样可以支持多人在线协同,现在不做处理json = String.format(json, fileInfo.getFileName(),fileKey,// TODO 这里是文件类型,自行定义'xlsx',// TODO 这里是文件下载地址,fileId 为文件的唯一标识,自行定义downFileUrl + fileId, // TODO 这里是定义回调地址,fileId 为文件的唯一标识用来区分是那个文件编辑的回调。editCallBackUrl + fileId,"userid","username");Map<String, Object> map = JSONObject.parseObject(json, new TypeToken<Map<String, Object>>() {}.getType());// TODO 这里是获取onlyoffice 交互的token,自己写的建议直接注释// String token = jwtManager.createToken(map);// map.put("token", token);// TODO 这个key可以直接注释,这里主要作用是协同redisUtil.hset(RedisName.ONLY_OFFICE_FILE_KYE,fileId,fileKey,60*60*24);return ResultVo.success(map);
}
2.3.2 文件下载地址

这个接口的作用就是获取一个文件流,根据ID来获取一个文件流

这里的地址就是上一个接口中下载文件的地址。

@GetMapping("down/file/{fileId}")
@Operation(summary = "根据参数下载一个文件")
public void downFolderById(@PathVariable String fileId, HttpServletResponse response){// TODO 1. 根据文件的唯一ID来获取数据库中的记录EtmfFileInfo fileInfo = fileInfoOpt.getById(fileId);// TODO 2. 根据下载路径从 minio 中获取文件流 (因为我们使用的是minio,其他的自行切换即可)try (InputStream inputStream = smoMinIoUtils.downloadFile(fileInfo.getFileUrl())) {downFileInfo(response, fileInfo, inputStream);} catch (ServerException | ErrorResponseException | InsufficientDataException | IOException |NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException |InternalException e) {JwtUtil.responseError(response, 500L, "文件下载失败:" + e.getMessage());}
}public static void downFileInfo(HttpServletResponse response, EtmfFileInfo fileInfo, InputStream inputStream) throws IOException {response.setCharacterEncoding("UTF-8");response.setContentType("application/octet-stream; charset=UTF-8");response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileInfo.getFileName(), StandardCharsets.UTF_8));ServletOutputStream stream = response.getOutputStream();IOUtils.copy(inputStream,stream);stream.flush();stream.close();
}
2.3.3 文件下载地址

这里是文件的回调地址,主要就是获取一个状态码,然后根据状态码判定是否保存文件。


@Operation(summary = "文件编辑之后的回调")
@Parameters({@Parameter(name = "fileId", description = "文件的ID", in = ParameterIn.PATH)
})
@PostMapping("/edit/callback/{fileId}")
public void editCallBack(@PathVariable String fileId, HttpServletRequest request, HttpServletResponse response) {try {PrintWriter writer = response.getWriter();String body;try {Scanner scanner = new Scanner(request.getInputStream());scanner.useDelimiter("\\A");body = scanner.hasNext() ? scanner.next() : "";scanner.close();} catch (Exception ex) {writer.write("get request.getInputStream error:" + ex.getMessage());return;}if (body.isEmpty()) {writer.write("empty request.getInputStream");return;}JSONObject jsonObj = JSON.parseObject(body);int status = (Integer) jsonObj.get("status");log.debug("================文件编辑获取到的参数是:{}", JSON.toJSONString(jsonObj));int saved = 0;if (List.of(2,3,6).contains(status)) {String downloadUri = (String) jsonObj.get("url");log.debug("================文件进行保存处理,需要保存的状态值是:{},可以获取到文件的路径是:{}", status,downloadUri);try {URL url = new URL(downloadUri);// 根据文件下载地址来获取编辑后的文件流HttpURLConnection connection = (HttpURLConnection) url.openConnection();InputStream stream = connection.getInputStream();if (stream == null) {throw new Exception("Stream is null");}// TODO 根据文件的唯一标识获取数据库中文件记录EtmfFileInfo fileInfo = fileInfoOpt.getById(fileId);// TODO 根据文件流创建一个文件File savedFile = new File(fileInfo.getFileName());try (FileOutputStream out = new FileOutputStream(savedFile)) {int read;final byte[] bytes = new byte[1024];while ((read = stream.read(bytes)) != -1) {out.write(bytes, 0, read);}out.flush();}// TODO 根据文件上传到 MINIO中boolean b = smoMinIoUtils.uploadFile(fileInfo.getFileUrl(), savedFile);log.info("编辑文件后,文件上传状态:{},上传的文件是:{},Id是:{}",b,fileInfo.getFileName(),fileId);savedFile.delete();connection.disconnect();} catch (Exception ex) {saved = 1;ex.printStackTrace();}finally {// 正常保存的时候剔除掉redis缓存if (status == TWO) {redisUtil.hdel(RedisName.ONLY_OFFICE_FILE_KYE,fileId);}}}writer.write("{\"error\":" + saved + "}");writer.flush();writer.close();log.debug("======================编辑完成--------------返回值是:{}","{\"error\":" + saved + "}");} catch (IOException e) {e.printStackTrace();throw new SmoGlobalException(CustomExceptionType.OTHER_ERROR);}
}

3. 总结

文件的在线编辑主要就是依托与onlyoffice实现的,而编辑器的配置是通过我们的接口来定义的,接口中的配置可以自由的定义编辑器的文件类型,窗口大小,文件来源,回调地址,保存类型等等。
你需要编辑的文件可以放在任意的位置,只要你的接口可以通过流的方式给到onlyofiice编辑器即可。
文件编辑后的处理都是在回调中处理的,最好先看一下文档的回调写法。回调的时候记得打印日志,观察一下接口的内容,一定要记得是通过回调中的url参数来获取编辑后的文件流的,并不是通过回调接口直接把文件流给到你。我在这里没有注意看饶了弯路。所以提醒一下。

4. 注意

4.1 你的项目的地址一定一定要和onlyoffice可以正常通讯,如果不行则一直不可能成功。
4.2 TOKEN是可以可选项,建议一开始不要使用,后面有需要的时候再去添加。
4.3 一定要看一下官网文档,文档真的很全很重要
4.4 协同的话只要参数就是一个KEY,如果需要超过20个的限制直接重新编译即可,大神一大堆,很容易就可以找到。

相关文章:

SpringBoot中整合ONLYOFFICE在线编辑

SpringBoot整合OnlyOffice SpringBoot整合OnlyOffice实现在线编辑1. 搭建私有的OnlyOffice的服务2. SpringBoot进行交互2.1 环境2.2 我们的流程2.3 接口规划2.3.1 获取编辑器配置的接口2.3.2 文件下载地址2.3.3 文件下载地址 3. 总结4. 注意4.1 你的项目的地址一定一定要和only…...

Python打字练习

代码解析 导入模块和定义单词列表 import tkinter as tk import randomsample_words ["apple", "banana", "cherry", "date", "fig", "grape", "kiwi", "lemon", "mango", &quo…...

Pytorch添加自定义算子之(10)-mmdeploy编译流程

整体参考 一、mmcv的编译安装 见上一篇 opencv的安装 $env:OpenCV_DIR = "D:\git_clone\opencv\build" # 我这里下载解压之后的地址 $env:path = "$env:OpenCV_DIR\x64\vc15\bin;" + $env:path $env:path = "D:\git_clone\opencv\build\OpenCVConf…...

大数据面试题之Flink(4)

Flink广播流 Flink实时topN 在实习中一般都怎么用Flink Savepoint知道是什么吗 为什么用Flink不用别的微批考虑过吗 解释一下啥叫背压 Flink分布式快照 Flink SQL解析过程 Flink on YARN模式 Flink如何保证数据不丢失 Flink广播流 Apache Flink 中的广播流&…...

C#实战|账号管理系统:通用登录窗体的实现。

哈喽,你好啊,我是雷工! 本节记录登录窗体的实现方法,比较有通用性,所有的项目登录窗体实现基本都是这个实现思路。 一通百通,以下为学习笔记。 01 登录窗体的逻辑 用户在登录窗输入账号和密码,如果输入账号和密码信息正确,点击【登录】按钮,则跳转显示主窗体,同时在固…...

php简单商城小程序系统源码

&#x1f6cd;️【简单商城小程序】&#x1f6cd;️ &#x1f680;一键开启&#xff0c;商城搭建新体验&#x1f680; 你还在为繁琐的商城搭建流程头疼吗&#xff1f;现在&#xff0c;有了简单商城系统小程序&#xff0c;一切变得轻松又快捷&#xff01;无需复杂的编程知识&a…...

NativeMemoryTracking查看java内存信息

默认该功能是禁用的&#xff0c;因为会损失5-10%的性能 开启命令 -XX:NativeMemoryTrackingdetail 打印命令 jcmd 45064 VM.native_memory summary scaleMB > NativeMemoryTracking.log 具体的日志信息 ➜ ~ ➜ ~ jcmd 45064 VM.native_memory summary scaleMB 45064…...

建智慧医院核心:智能导航系统的功能全析与实现效益

在数字化转型的浪潮中&#xff0c;智慧医院的建设是医疗行业数字化转型的关键步骤。随着医院规模的不断扩大和医疗设施的日益复杂&#xff0c;传统的静态不连续的导航方式已无法满足患者的需求。院内智能导航系统&#xff0c;作为医疗数字化转型的关键组成部分&#xff0c;正逐…...

数据库基础之:函数依赖

函数依赖在数据库设计中是非常关键的概念&#xff0c;用于描述关系数据库中数据项之间的相关性。下面我将通过几个例子来说明函数依赖的几种类型&#xff1a;完全函数依赖、部分函数依赖和传递函数依赖。 完全函数依赖 考虑一个关系模式 Student&#xff0c;包含属性 Student…...

Newport太阳光模拟器MSOL-UV-X使用说明手侧

Newport太阳光模拟器MSOL-UV-X使用说明手侧...

pandas读取CSV格式文件生成数据发生器iteration

背景 数据集标签为csv文件格式&#xff0c;有三个字段column_hander [‘id’, ‘boneage’, ‘male’]&#xff0c;需要自己定义数据集。文件较大&#xff0c;做一个数据发生器迭代更新数据集。 实现模板 在Pandas中&#xff0c;可以使用pandas.read_csv函数读取CSV文件&…...

SpringBoot 启动流程四

SpringBoot启动流程四 前面这个创建对象是初始化SpringApplication对象 是加载了SpringBoot程序的所有相关配置 我们接下来要将这个run方法 run过程是一个运行 初始化容器 我们看我们的运行结果是得到一个ConfigurableApplicationContext对象 package com.bigdata1421.star…...

实现桌面动态壁纸(二)

目录 前言 一、关于 WorkerW 工作区窗口 二、关于窗口关系 2.1 窗口以及窗口隶属关系 2.2 桌面管理层窗口组分简析 2.3 厘清两个概念的区别 2.4 关于设置父窗口 三、编写代码以供在 Vista 上实现 3.1 方法二&#xff1a;子类化并自绘窗口背景 四、初步分析桌面管理层…...

JavaEE——计算机工作原理

冯诺依曼体系&#xff08;VonNeumannArchitecture&#xff09; 现代计算机&#xff0c;大多遵守冯诺依曼体系结构 CPU中央处理器&#xff1a;进行算术运算与逻辑判断 存储器&#xff1a;分为外存和内存&#xff0c;用于存储数据&#xff08;使用二进制存储&#xff09; 输入…...

并发、多线程和HTTP连接之间有什么关系?

一、并发的概念 并发是系统同时处理多个任务或事件的能力。在计算中&#xff0c;这意味着系统能够在同一时间段内处理多个任务&#xff0c;而不是严格按照顺序一个接一个地执行它们。并发提高了系统的效率和资源利用率&#xff0c;从而更好地满足用户的需求。在现代应用程序中&…...

展开说说:Android服务之startService源码解析

通过上一篇文章我们掌握了Android四种的基本使用&#xff0c;本篇从源码层面总结一下startService的执行过程。 本文依然按着是什么&#xff1f;有什么&#xff1f;怎么用&#xff1f;啥原理&#xff1f;的步骤来分析。 1、是什么 上一篇总结了“Service是Android系统中的四…...

Java + MySQL 实现存储完整 Json

Java MySQL 实现存储完整 Json 一、应用场景二、数据库配置三、后端代码配置1、maven 依赖2、实体类3、Service 实现类4、xml 文件 四、测试1、新增接口2、查询接口3、数据表内容 一、应用场景 将前端传过来的 Json 完整存储到 MySQL 中&#xff0c;涉及技术栈为 Java、MyBat…...

解决刚申请下来的AWS EC2,无法用finalshell连接的问题

在AWS的命令页面创建一个root用户 切换到root 模式,输入密码 su root 不知道密码的可以使用一下命令来设置root用户的密码&#xff1a; su passwd root 再切换到root用户 su 修改配置文件 输入 vim /etc/ssh/sshd_config进入文件&#xff0c;键入’i’ &#xff0c;进行…...

如何在PD虚拟机中开启系统的嵌套虚拟化功能?pd虚拟机怎么用 Parallels Desktop 19 for Mac

PD虚拟机是一款可以在Mac电脑中运行Windows系统的应用软件。使用 Parallels Desktop for Mac 体验 macOS 和 Windows 的最优性能&#xff0c;解锁强大性能和无缝交互。 在ParallelsDesktop&#xff08;PD虚拟机&#xff09;中如何开启系统的嵌套虚拟化功能&#xff1f;下面我们…...

vue中实现button按钮的重复点击指令

// 注册一个全局自定义指令 v-debounce Vue.directive(debounce, {// 当被绑定的元素插入到 DOM 中时...inserted: function (el, binding) {let timer;el.addEventListener(click, () > {clearTimeout(timer);timer setTimeout(() > {binding.value(); // 调用传给指令…...

智能与伦理:Kimi与学术道德的和谐共舞

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 Kimi&#xff0c;由月之暗面科技有限公司开发的智能助手&#xff0c;擅长中英文对话&#xff0c;能处理多种文档和网页内容。在论文写作中&#xff0c;Kimi可提供资料查询、信息整理、语…...

mac有什么解压软件 mac怎么解压7z软件 苹果电脑好用的压缩软件有哪些

众所周知&#xff0c;macOS集成解压缩软件归档实用工具&#xff0c;可直接解压zip格式的压缩包。但对于其他比较常见的格式&#xff0c;诸如RAR、7z、TAR等&#xff0c;则无能为力&#xff0c;不过&#xff0c;我们可以选择大量第三方解压缩软件&#xff0c;帮助我们更好地完成…...

C语言_练习题

求最小公倍数 思路&#xff1a;假设两个数&#xff0c;5和7&#xff0c;那么最小至少也要7吧&#xff0c;所以先假定最小公倍数是两个数之间较大的&#xff0c;然后看7能不能同时整除5和7&#xff0c;不能就加1继续除 int GetLCM(int _num1, int _num2) {int max _num1>_n…...

Type-C接口快充取电技术的实现

Type-C接口快充取电技术的实现 Type-C接口快充取电技术主要通过USB PD&#xff08;Power Delivery&#xff09;协议实现。这种技术利用了Type-C接口的物理特性和PD协议的智能性&#xff0c;实现了高效、安全、快速的充电过程。具体实现过程如下&#xff1a; 接口连接与检测&a…...

压测工具---Ultron

压测工具&#xff1a;Ultron 类型&#xff1a;接口级和全链路 接口级 对于接口级别的压测我们可以进行 http接口压测、thrift压测、redis压测、kafka压测、DDMQ压测、MySQL压测等&#xff0c;选对对应的业务线、选择好压测执行的时间和轮数就可以执行压测操作了 全链路 对…...

Kubernetes 负载均衡器解决方案 MetalLB实践

Kubernetes 负载均衡解决方案 MetalLB实践 MetalLB 是一个用于在 Kubernetes 集群中提供外部 IP 地址的负载均衡器实现。 准备工作 1. 安装需知 安装 MetalLB 有一些前置条件&#xff1a; Kubernetesv1.13.0 或者更新的版本 集群中的 CNI 要能兼容 MetalLB&#xff0c;最新…...

力扣爆刷第159天之TOP100五连刷61-65(翻转单词、对称二叉树、遍历求和)

力扣爆刷第159天之TOP100五连刷61-65&#xff08;翻转单词、对称二叉树、遍历求和&#xff09; 文章目录 力扣爆刷第159天之TOP100五连刷61-65&#xff08;翻转单词、对称二叉树、遍历求和&#xff09;一、151. 反转字符串中的单词二、129. 求根节点到叶节点数字之和三、104. 二…...

(七)[重制]C++命名空间与标准模板库(STL)

​ 引言 在专栏C教程的第六篇C中的结构体与联合体中&#xff0c;介绍了C中的结构体和联合体&#xff0c;包括它们的定义、初始化、内存布局和对齐&#xff0c;以及作为函数参数和返回值的应用。在专栏C教程的第七篇中&#xff0c;我们将深入了解C中的命名空间&#xff08;nam…...

Elasticsearch:Runtime fields - 运行时字段(一)

目录 使用运行时字段带来的好处 激励 折衷 映射运行时字段 定义运行时字段而不使用脚本 忽略运行时字段上的脚本错误 更新和删除运行时字段 在搜索请求中定义运行时字段 创建使用其他运行时字段的运行时字段 运行时字段&#xff08;runtime fields&#xff09;是在查询…...

03:C语言运算符

C语言运算符 1、常见运算符2、赋值运算符3、判断运算符4、与- - 1、常见运算符 数学运算符号。常见数学运算符号&#xff0c;跟数学中理解相同 加号 - 减号 * 乘号 / 除号&#xff0c;相除以后的商 % 取余符号&#xff0c;相除以后余数是几 ()括号括起来优先级最高&#xff0…...

JAVA每日作业day7.4

ok了家人们今天学习了Date类和simpleDateformat类&#xff0c;话不多说我们一起看看吧 一.Date类 类 java.util.Date 表示特定的瞬间 ( 日期和时间 ) &#xff0c;精确到毫秒。 1.2 Date类的构造方法 public Date(): 用来创建当前系统时间对应的日期对象。 public Date(long …...

WordPress网站违法关键词字过滤插件下载text-filter

插件下载地址&#xff1a;https://www.wpadmin.cn/2025.html 插件介绍 WordPress网站违法关键词字过滤插件text-filter由本站原创开发,支持中英文关键字自动替换成**号&#xff0c;可以通过自定义保存修改按钮增加“预设关键字”&#xff0c;也可以导入定义好的txt文本形式的关…...

ros1仿真导航机器人 navigation

仅为学习记录和一些自己的思考&#xff0c;不具有参考意义。 1navigation导航框架 2导航设置过程 &#xff08;1&#xff09;启动仿真环境 roslaunch why_simulation why_robocup.launch &#xff08;2&#xff09;启动move_base导航、amcl定位 roslaunch why_simulation nav…...

Python制作动态颜色变换:颜色渐变动效

文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Pygame颜色变换函数主循环 完整代码 引言 颜色渐变动画是一种视觉上非常吸引人的效果&#xff0c;常用于网页设计和图形应用中。在这篇博客中&#xff0c;我们将使用Python创建一个动态颜色变换的动画效果。通…...

Python 异步编程介绍与代码示例

Python 异步编程介绍与代码示例 一、异步编程概述 异步编程是一种编程范式&#xff0c;它旨在处理那些需要等待I/O操作完成或执行耗时任务的情况。在传统的同步编程中&#xff0c;代码会按照顺序逐行执行&#xff0c;直到遇到一个耗时操作&#xff0c;它会阻塞程序的执行直到…...

堆叠的作用

一、为什么要堆叠 传统的园区网络采用设备和链路冗余来保证高可靠性&#xff0c;但其链路利用率低、网络维护成本高&#xff0c;堆叠技术将多台交换机虚拟成一台交换机&#xff0c;达到简化网络部署和降低网络维护工作量的目的。 二、堆叠优势 1、提高可靠性 堆叠系统多台成…...

ubuntu 如何查看某一个网卡的ip地址

在Ubuntu中&#xff0c;你可以使用多种方法来查看某一个网卡的IP地址。以下是一些常用的方法&#xff1a; 使用ip命令&#xff1a; ip命令是现代Linux系统中用于显示和操作路由、网络设备、策略路由和隧道的工具。要查看所有网络接口的IP地址&#xff0c;你可以使用&#xff1a…...

跨界客户服务:拓展服务边界,创造更多价值

在当今这个日新月异的商业时代&#xff0c;跨界合作已不再是新鲜词汇&#xff0c;它如同一股强劲的东风&#xff0c;吹散了行业间的壁垒&#xff0c;为企业服务创新开辟了前所未有的广阔天地。特别是在客户服务领域&#xff0c;跨界合作正以前所未有的深度和广度&#xff0c;拓…...

linux驱动编程 - kfifo先进先出队列

简介&#xff1a; kfifo是Linux Kernel里面的一个 FIFO&#xff08;先进先出&#xff09;数据结构&#xff0c;它采用环形循环队列的数据结构来实现&#xff0c;提供一个无边界的字节流服务&#xff0c;并且使用并行无锁编程技术&#xff0c;即当它用于只有一个入队线程和一个出…...

JS 四舍五入使用整理

一、Number.toFixed() 把数字转换为字符串,结果的小数点后有指定位数的数字,重点返回的数据类型为字符串 toFixed() 方法将一个浮点数转换为指定小数位数的字符串表示,如果小数位数高于数字,则使用 0 来填充。 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。…...

上万组风电,光伏,用户负荷数据分享

上万组风电&#xff0c;光伏&#xff0c;用户负荷数据分享 可用于风光负荷预测等研究 获取链接&#x1f517; https://pan.baidu.com/s/1izpymx6R3Y8JsFdx42rL0A 提取码&#xff1a;381i 获取链接&#x1f517; https://pan.baidu.com/s/1izpymx6R3Y8JsFdx42rL0A 提取…...

在物联网快速发展的趋势下,Java 怎样优化对低功耗、资源受限的边缘设备的支持,保障物联网应用的稳定运行?

在物联网快速发展的趋势下&#xff0c;Java可以通过以下方式优化对低功耗、资源受限的边缘设备的支持&#xff0c;以保障物联网应用的稳定运行&#xff1a; 精简Java运行环境&#xff1a;针对边缘设备的资源限制&#xff0c;可以使用精简型的Java运行环境&#xff0c;避免不必要…...

java-HashSet 源码分析 1

## 深入分析 Java 中的 HashSet 源码 HashSet 是 Java 集合框架中的一个重要类&#xff0c;它基于哈希表实现&#xff0c;用于存储不重复的元素。HashSet 允许 null 元素&#xff0c;并且不保证元素的顺序。本文将详细分析 HashSet 的源码&#xff0c;包括其数据结构、构造方法…...

K8S 部署 EFK

安装说明 系统版本为 Centos7.9 内核版本为 6.3.5-1.el7 K8S版本为 v1.26.14 ES官网 开始安装 本次安装使用官方ECK方式部署 EFK&#xff0c;部署的是当前的最新版本。 在 Kubernetes 集群中部署 ECK 安装自定义资源 如果能打开这个网址的话直接用这个命令安装,打不开的话…...

AI Earth应用—— 在线使用sentinel数据VV和VH波段进行水体提取分析(昆明抚仙湖、滇池为例)

AI Earth 本文的主要目的就是对水体进行提取,这里,具体的操作步骤很简单基本上是通过,首页的数据检索,选择需要研究的区域,然后选择工具箱种的水体提取分析即可,剩下的就交给阿里云去处理,结果如下: 这是我所选取的一景影像: 详情 卫星: Sentinel-1 级别: 1 …...

基于Hadoop平台的电信客服数据的处理与分析③项目开发:搭建基于Hadoop的全分布式集群---任务9:HBase的安装和部署

任务描述 任务内容为HBase的安装部署与测试。 任务指导 HBase集群需要整个集群所有节点安装的HBase版本保持一致&#xff0c;并且拥有相同的配置 具体配置步骤如下&#xff1a; 1. 解压缩HBase的压缩包 2. 配置HBase的环境变量 3. 修改HBase的配置文件&#xff0c;HBase…...

go语言day09 通道 协程的死锁

Go语言学习——channel的死锁其实没那么复杂 - JackieZheng - 博客园 (cnblogs.com) 目录 通道 创建通道 1&#xff09;无缓冲通道 2&#xff09;有缓冲通道 通道的使用 1) 值从通道入口进 2) 值从通道出口出 信道死锁&#xff1a; 0&#xff09;死锁现场0 1&#xff09;死…...

黑马的ES课程中的不足

在我自己做项目使用ES的时候&#xff0c;发现了黑马没教的方法&#xff0c;以及一些它项目的小问题 搜索时的匹配方法 这个boolQuery().should 我的项目是通过文章的标题title和内容content来进行搜索 但是黑马它的项目只用了must 如果我们的title和content都用must&#x…...

STM32 中断编程入门

目录 一、中断系统 1、中断的原理 2、中断类型 外部中断 定时器中断 DMA中断 3、中断处理函数 中断标志位清除 中断服务程序退出 二、实际应用 中断控制LED 任务要求 代码示例 中断控制串口通信 任务要求1 代码示例 任务要求2 代码示例 总结 学习目标&…...

使用maven搭建一个SpingBoot项目

1.首先创建一个maven项目 注意选择合适的jdk版本 2.添加依赖 2.在pom.xml中至少添加依赖 spring-boot-starter-web 依赖&#xff0c;目的是引入Tomcat&#xff0c;以及SpringMVC等&#xff0c;使项目具有web功能。 <!-- 引入 包含tomcat&#xff0c;SpringMVC&#xff0c…...