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

vue java 实现大地图切片上传

在这里插入图片描述

文章目录

  • 一、项目背景
  • 二、页面
  • 三、代码
    • 1.前端
    • 2.mock-i18n.js文件
    • 3.xx.js文件定义方法
    • 4.配置文件 application.properties
    • 5.后端方法
  • 四、易错点
    • 易错点1:前端要进行分片切割,然后再分片上传。
    • 易错点2:后端配置文件要配置。
    • 易错点3:个人感觉最好分片大小别太大。
    • 易错点4:上传途中最好加个“遮罩”或者进度条,比如显示“正在上传中......”会更友好。
    • 易错点5:如果项目采用nginx,记得修改nginx.conf。
  • 五、补充点

一、项目背景

技术:vue+Arco Design+java

介绍:页面上传mapShow.zip压缩包,只允许上传压缩包,且上传有格式校验,然后文件大小在600M或者上G的压缩包,像这种上传是不可能直接一整个包上传的,浏览器也不支持,同时这样做也不友好。

解决方案:采用分片技术,即把一个打压缩包切割成每个10M大小的分片,然后上传到指定目录下,最后再把所有分片文件进行合并成mapShow.zip压缩包,最后再解压mapShow.zip文件到指定目录下即可。

二、页面

在这里插入图片描述

三、代码

1.前端

<div class="param"><a-spin style="width: 70%"><div class="param-title"><div class="param-title-text">{{ $t("OfflineMapPathSetting") }}:</div></div><div class="param-content"><divclass="parent"style="display: flex; align-items: center; gap: 20px"><div><span class="label">{{ $t("Import") }}:</span></div><a-input class="div" v-model="fileName" disabled /><a-upload@change="onChange":auto-upload="false":show-file-list="false"><template #upload-button><svg-loaderclass="frameIcon"name="import-file"></svg-loader></template></a-upload></div></div></a-spin>
</div>const onChange = async (fileList) => {files.value = [];const lastUploadedFile = fileList[fileList.length - 1];fileName.value = lastUploadedFile.name;const allowedExtensions = /(.zip)$/i;if (!allowedExtensions.exec(lastUploadedFile.name)) {Message.error(t("invalidCerFileType2"));return;}uploadeLoading.value = true;if (fileList.length > 0) {const lastUploadedFile = fileList[fileList.length - 1];const chunkSize = 10 * 1024 * 1024;const totalChunks = Math.ceil(lastUploadedFile.file.size / chunkSize);for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {const start = chunkIndex * chunkSize;const end = Math.min(start + chunkSize, lastUploadedFile.file.size);const chunk = lastUploadedFile.file.slice(start, end);const formData = new FormData();formData.append("file", chunk);formData.append("fileId", "mapShow");formData.append("chunkIndex", chunkIndex);formData.append("totalChunks", totalChunks);await importOfflineMapFunction(formData);}progress.value = 100;uploadeLoading.value = false;Message.success(t("LoadMap"));}
};const importOfflineMapFunction = async (formData) => {await importOfflineMap(formData).then((response) => {commonResponse({response,onSuccess: () => {},});});
};

2.mock-i18n.js文件

"invalidCerFileType2": "无效的文件类型,文件后缀必须是.zip等格式"

3.xx.js文件定义方法

export const importOfflineMap = (data) => {return $http({url: `/api/systemParam/importOfflineMap`,method: Method.POST,headers: {'Content-Type': 'multipart/form-data','X-Requested-With': 'XMLHttpRequest'},data,timeout: 300000})
}

4.配置文件 application.properties

spring.servlet.multipart.max-file-size=600MB
spring.servlet.multipart.max-request-size=2GB

5.后端方法

private static String OFFLINE_MAP_TEMPORARY_PATH = "\\..\\temporary\\";
private static String OFFLINE_MAP_TARGET_PATH = "\\..\\nginx\\html\\mapShow\\";@Operation(summary = "导入离线地图")
@PostMapping(value = "/importOfflineMap")
public ResponseModel importOfflineMap(@RequestParam("file") MultipartFile file,@RequestParam("fileId") String fileId,@RequestParam("chunkIndex") int chunkIndex,@RequestParam("totalChunks") int totalChunks) {return systemParamUserControl.importOfflineMap(file, fileId, chunkIndex, totalChunks);
}public ResponseModel importOfflineMap(MultipartFile file, String fileId, int chunkIndex, int totalChunks) {try {String userDir = System.getProperty("user.dir");logger.info("importOfflineMap-user.dir:{}", userDir);String offlineMapTemporaryPath = userDir + OFFLINE_MAP_TEMPORARY_PATH;File uploadFile = new File(offlineMapTemporaryPath);if (!uploadFile.exists()) {uploadFile.mkdirs();}String chunkFileName = offlineMapTemporaryPath + fileId + ".part" + chunkIndex;file.transferTo(new File(chunkFileName));if (chunkIndex == totalChunks - 1) {String offlineMapTargetPath = userDir + OFFLINE_MAP_TARGET_PATH;mergeFile(fileId, totalChunks, offlineMapTemporaryPath, offlineMapTargetPath);}} catch (IOException e) {logger.error("importOfflineMap-IOException:{}", e);}return ResponseModel.ofSuccess();}private void mergeFile(String fileId, int totalChunks, String offlineMapTemporaryPath, String offlineMapTargetPath) {// 创建最终文件File outputFile = new File(offlineMapTemporaryPath + fileId + ".zip");try {FileOutputStream fos = new FileOutputStream(outputFile);for (int i = 0; i < totalChunks; i++) {Path chunkPath = Paths.get(offlineMapTemporaryPath + fileId + ".part" + i);Files.copy(chunkPath, fos);Files.delete(chunkPath);}unzip(outputFile, offlineMapTargetPath);} catch (Exception e) {logger.error("mergeFile-Exception:{}", e);}}private void unzip(File zipFile, String destDir) throws IOException {byte[] buffer = new byte[1024];try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {ZipEntry zipEntry = zis.getNextEntry();while (zipEntry != null) {File newFile = new File(destDir, zipEntry.getName());if (zipEntry.isDirectory()) {newFile.mkdirs();} else {// Create directories for nested filesnew File(newFile.getParent()).mkdirs();try (FileOutputStream fos = new FileOutputStream(newFile)) {int len;while ((len = zis.read(buffer)) > 0) {fos.write(buffer, 0, len);}}}zipEntry = zis.getNextEntry();}zis.closeEntry();}zipFile.delete();}

四、易错点

易错点1:前端要进行分片切割,然后再分片上传。

易错点2:后端配置文件要配置。

后端配置文件要配置,不然默认浏览器只支持5M或者1M,当上传10M分片文件时会报错,无法调通接口,执行流程就卡在前端了,压根调不通后端上传接口。

spring.servlet.multipart.max-file-size=600MB
spring.servlet.multipart.max-request-size=2GB

易错点3:个人感觉最好分片大小别太大。

易错点4:上传途中最好加个“遮罩”或者进度条,比如显示“正在上传中…”会更友好。

易错点5:如果项目采用nginx,记得修改nginx.conf。

如果项目采用nginx,记得修改nginx.conf,配置上传切片大小、超时时间等等参数设置,否则也会上传失败。

五、补充点

网上还有网友说道使用什么“断点续传”的功能,这个我目前未验证,不清楚如何,其他博主可自行验证然后分享结论看是否可行。

相关文章:

vue java 实现大地图切片上传

文章目录 一、项目背景二、页面三、代码1.前端2.mock-i18n.js文件3.xx.js文件定义方法4.配置文件 application.properties5.后端方法 四、易错点易错点1&#xff1a;前端要进行分片切割&#xff0c;然后再分片上传。易错点2&#xff1a;后端配置文件要配置。易错点3&#xff1a…...

langchain+ollama+deepseek的部署(win)

ANACONDA 安装 官网&#xff1a;Download Anaconda Distribution | Anaconda 配置系统环境 在系统变量中配置 检查是否配置成功 通过 cmd 窗口输入&#xff1a; conda info 如图&#xff1a;表示成功 配置你的虚拟环境 二、安装 ollama allama 安装 官网地址&#xff1a…...

deepseek实战教程-第四篇开放平台接口文档使用

第二篇讲解了如何本地安装大模型&#xff0c;然后编写一个基于jsspringboot的项目&#xff0c;通过页面实现对话的功能。实际上&#xff0c;上面的demo用到是deepseek提供的接口&#xff0c;那么deepseek共提供了多少接口呢&#xff1f;这就要讨论到deepseek的接口库了&#xf…...

Android第六次面试总结(Java设计模式二)

在 Android 开发里&#xff0c;ListView 和 RecyclerView 是常用的视图组件&#xff0c;用于展示大量数据列表。不过&#xff0c;这些视图组件本身无法直接展示原始数据源&#xff0c;需要借助 Adapter&#xff08;适配器&#xff09;把数据源适配成视图能够展示的数据&#xf…...

一站式电脑工具箱,功能全面且实用

小明工具箱是一款集成了系统设置、维护工具、实用工具、图像处理等四大类工具的电脑工具箱&#xff0c;涵盖了上百种实用工具&#xff0c;能够满足用户在文件管理、文本处理、系统优化、图像处理等多方面的需求。 初次使用&#xff0c;需双击软件&#xff0c;便会自动将工具解压…...

那些正常的动态规划

文章目录 前言动态规划到底是啥&#xff1f; 线性dp最长上升子序列子集和子序列和子串的区别内容分析 最大上升子序列例题1——[NOIP2004 提高组] 合唱队形分析 最长公共子序列最长公共子串 平面dp例题2——[NOIP2000 提高组] 方格取数分析 例题3——[NOIP2008 提高组] 传纸条分…...

Opencv计算机视觉编程攻略-第二节 图像像素操作

第二节 图像像素操作 1.访问像素值2.用指针扫描图像3.扫描图像并访问相邻像素4.实现简单的图像运算5.图像重映射 1.访问像素值 以椒盐噪声为例展示像素值访问的几种方法 void salt(cv::Mat image, int n) {// C11 random number generatorstd::default_random_engine generat…...

华为交换相关

端口模式 &#xff08;1&#xff09;access&#xff1a;只能属于单个VLAN&#xff0c;一般用于连接计算机端口 &#xff08;2&#xff09;trunk&#xff1a;端口允许多个VLAN通过&#xff0c;可以接收和发送多个VLAN报文&#xff0c;默认情况下只有管理VLAN不携带标签信息 &…...

Chrome Performance 面板完全指南:从卡顿到丝滑的终极调试术

1.写在前面 前端性能调试是优化网页加载速度和运行效率的关键步骤&#xff0c;Chrome DevTools 的 Performance 面板 是核心工具; 2.Performance 面板使用步骤 ★ 基础 打开面板 在 Chrome 中按 F12 → 切换到 Performance 标签页。 开始录制 方式一&#xff1a;点击 ⚫️ 圆…...

idea中快速注释函数

在IntelliJ IDEA中&#xff0c;有多种方法可以快速注释函数。 使用快捷键 你可以使用以下快捷键来快速注释函数[3]&#xff1a; 行注释&#xff1a;使用Ctrl/&#xff08;Windows系统&#xff09;或Command/&#xff08;Mac系统&#xff09;可以在当前行前添加或删除单行注释…...

深入解析Linux网络、安全与容器技术

1. Netfilter&#xff1a;Linux内核的包处理框架 Netfilter 是Linux内核中用于控制网络数据包的核心机制&#xff0c;负责处理数据包的过滤、修改和转发。其核心功能包括&#xff1a; 包过滤&#xff08;Packet Filtering&#xff09;&#xff1a;根据规则允许或拒绝数据包通过…...

JDK 24:Java 24 中的新功能

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;历代文学&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编程&#xff0c;高并发设计&#xf…...

java中的枚举类型和c,c++的有区别吗?c,c++的枚举,结构体,联合体,三种数据有什么区别和联系

Java 枚举类型与 C、C 枚举类型的区别 1. 类型安全 Java&#xff1a;Java 的枚举类型是类型安全的。枚举常量是枚举类型的实例&#xff0c;编译器会严格检查传递的参数是否为该枚举类型的有效常量。例如&#xff1a; java Apply enum Color { RED, GREEN, BLUE } // 编译器会检…...

ubuntu服务器server版安装,ssh远程连接xmanager管理,改ip网络连接。图文教程

ventoy启动服务器版iso镜像&#xff0c;注意看server名称&#xff0c;跟之前desktop版ubuntu不一样。没有gui界面。好&#xff0c;进入命令行界面。语言彻底没汉化了&#xff0c;选英文吧&#xff0c;别的更看不懂。 跟桌面版ubuntu类似&#xff0c;选择是否精简系统&#xff0…...

什么叫税务黑名单?详解税务黑名单的来源。

一、什么叫税务黑名单&#xff1f; 1、税务黑名单是指由税务部门根据相关法律法规和税收管理策&#xff0c;对违反税收法规、逃避纳税义务或其他严重违法违规行为的个人或企业进行记录和公示的名单。 2、被列入税务黑名单意味着该个人或企业在税务方面存在严重的不诚信行为&a…...

计算机二级:基础操作题

一 sinfoinput() info_listsinfo.split(,) print("姓名,年龄") for strname in info_list:snamestrname[:-2]sagestrname[-2:]print("{},{}".format(sname,sage))二 import random as r r.seed(1) sinput("请输入三个整数n&#xff0c;m&#xff0c…...

python机器学习——新手入门学习笔记

一&#xff0c;概论 1.什么是机器学习 定义&#xff1a; 机器学习是从数据中自动分析获得模型&#xff0c;并利用模型对未知数据进行预测。 其实就是通过问题和数据&#xff0c;发现规律&#xff0c;并进行预测&#xff0c;与人脑相似。目的就是从历史数据当中获得规律&#x…...

LabVIEW 与 PLC 通讯的常见方式

在工业自动化和数据采集系统中&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09; 广泛用于控制和监测各种设备&#xff0c;而 LabVIEW 作为强大的图形化编程工具&#xff0c;常用于上位机数据处理和可视化。为了实现 LabVIEW 与 PLC 的高效通讯&#xff0c;常见的方法包…...

深度学习 Deep Learning 第9章 卷积网络 CNN

深度学习 Deep Learning 第9章 卷积网络 章节概述 本章深入探讨了卷积网络的原理、变体及其在深度学习中的应用。卷积网络通过卷积操作实现了参数共享和稀疏连接&#xff0c;显著提高了模型的效率和性能。本章首先介绍了卷积操作的基本形式及其在不同数据维度上的应用&#x…...

Tekton系列之实践篇-从触发到完成的完整执行过程

以下介绍的是基于 Gitee 仓库 的 Tekton 工作流程 操作流程 定义task 克隆代码的task # task-clone.yaml apiVersion: tekton.dev/v1beta1 kind: Task metadata:name: git-clone spec:workspaces:- name: source # 工作目录params:- name: repo-url # 你的 Gitee 仓库地址…...

【简单学习】Prompt Engineering 提示词工程

一、Prompt 1、Prompt 是什么&#xff1f; Prompt 是一种人为构造的输入序列&#xff0c;用于引导 GPT 模型根据先前输入的内容生成相关的输出。简单来说&#xff0c;就是你向模型提供的 “提示词”。 在 ChatGpt 中&#xff0c;我们可以通过设计不同的 prompt&#xff0c;让…...

neo4j删除所有数据

neo4j删除所有数据 一次性删除 MATCH (n) DETACH DELETE n ;分批次删除 先删除关系 MATCH ()-[r]->()WITH r LIMIT 100000DELETE rRETURN count(r)在删除节点 MATCH (n)WITH n LIMIT 100000DELETE nRETURN count(n)验证 查询节点总数 MATCH (n) RETURN count(n) AS node…...

零基础入门网络爬虫第5天:Scrapy框架

4周 Srapy爬虫框架 不是一个简单的函数功能库&#xff0c;而是一个爬虫框架 安装&#xff1a;pip install scrapy 检测&#xff1a;scrapy -h Scrapy爬虫框架结构 爬虫框架 爬虫框架是实现爬虫功能的一个软件结构和功能组件集合爬虫框架是一个半成品&#xff0c;能够帮助…...

ARCGIS PRO DSK 栅格数据(Raster)

ArcGIS Pro 中与栅格相关的功能可以在两个单独程序集中的两个命名空间中找到。 1、ArcGIS.Core.dll 中的 ArcGIS.Core.Data.Raster 命名空间提供了栅格类和成员&#xff0c;用于处理栅格数据集、内存栅格、像素块和光标。 2、ArcGIS.Desktop.Mapping.dll 中的 ArcGIS.Desktop.M…...

C#设计模式快速回顾

知识点来源&#xff1a;人间自有韬哥在&#xff0c;豆包 目录 一、七大原则1. 单一职责原则 (Single Responsibility Principle)2. 开放封闭原则 (Open-Closed Principle)3. 里氏替换原则 (Liskov Substitution Principle)4. 接口隔离原则 (Interface Segregation Principle)5…...

分页查询互动问题(用户端)

文章目录 概要整体架构流程技术细节小结 概要 需求分析以及接口设计 技术细节 1.Controller层 GetMapping("/page")ApiOperation("分页查询问题")public PageDTO<QuestionVO> queryQuestionPage(QuestionPageQuery query){return questionService…...

【全队项目】智能学术海报生成系统PosterGenius(项目介绍)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a;&#x1f3c0;大模型实战训练营_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…...

P5356 [Ynoi Easy Round 2017] 由乃打扑克 Solution

Description 给定序列 a ( a 1 , a 2 , ⋯ , a n ) a(a_1,a_2,\cdots,a_n) a(a1​,a2​,⋯,an​)&#xff0c;有 m m m 个操作分两种&#xff1a; add ⁡ ( l , r , x ) \operatorname{add}(l,r,x) add(l,r,x)&#xff1a;对每个 i ∈ [ l , r ] i\in[l,r] i∈[l,r] 执行 …...

【线程安全问题的原因和方法】【java形式】【图片详解】

在本章节中采用实例图片的方式&#xff0c;以一个学习者的姿态进行描述问题解决问题&#xff0c;更加清晰明了&#xff0c;以及过程中会发问的问题都会一一进行呈现 目录 线程安全演示线程不安全情况图片解释&#xff1a; 将上述代码进行修改【从并行转化成穿行的方式】不会出…...

MySQL-----视图与索引

目录 视图 1.视图 2.操作 11.索引 1.定义 2.优缺点: 3.分类 4.索引的设计原则 5.索引的使用 作业 视图 1.视图 ❓如果需要在原表中隐藏部分字段时&#xff0c;怎么办&#xff1f; 视图 &#x1f4d6;视图: 是一个没有存储任何数据的表&#xff0c;可以对其CRUD视图…...