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

JavaWeb文件上传

文件上传总览

文件上传主要是指将本地文件(包括但不限于图片、视频、音频等)上传到服务器,提供其他用户浏览或下载的过程。在日常生活中,我们在很多情况下都需要使用文件上传功能,比如:发微博、发朋友圈等(这里主要是指照片和视频文件),可见文件上传的重要性。文件上传功能实现需要涉及到两个部分,一个部分是前端程序、一个部分是后端程序,本文将前后端分开讲解。

接收文件

文件上传的前端准备

前端若想进行文件上传(网页的文件上传),就必须要有文件上传的三要素,前端必须要有这三要素才可以完成文件上传。前端要想实现文件上传就必须定义一个form表单,其中必须要有一个表单项类型为file;表单的提交方式必须是post方式,其原因是get方式提交有大小限制(并且不是很大),但文件上传可能涉及到大文件,所以说应该使用post方式提交表单;其最后一个要素,也是最重要的要素,就是在form表单中需要通过enctype属性设置表单的编码格式为 "multipart/form-data",这个设置非常重要——文件的本质上是二进制数据,而form表单的默认编码格式(x-www-form-urlencoded)是不适合传递二进制数据的。

假如说使用form表单默认的编码格式传输文件的问题:简单概括就是使用x-www-form-urlencoded编码格式传输文件,不会传输文件中的内容(数据),只能传输一个文件名。假如说我有一个.txt文本文件,使用默认的编码格式进行上传:

(该文件是有内容的)

该表单的编码格式是默认的x-www-form-urlencoded

 

发现上传的文件数据只有上传的文件的文件名,这证明了若使用form表单的默认编码格式,那么传输文件是失败的,只会上传文件的文件名。 总结一下文件上传的前端准备: 需要一个form表单,表单中需要一个表单项类型为file,并且该表单的提交方式必须为post,而且表单的编码格式必须修改为multipart/form-data。

文件上传的后端程序

文件上传的后端程序首先肯定是需要一个控制方法(SpringBoot),用于接收文件上传这个“功能接口”的请求,并且请求的其他数据之前怎么接收现在仍然怎么接收(比如简单参数、实体参数、日期参数等,还是像之前那么接收即可);请求提交的文件需要用SpringBoot提供的对象MultipartFile接收(前端中file表单项的名称必须和控制方法参数列表中MultipartyFile对象名完全相同)

创建请求处理类,并定义文件上传功能接口的控制器方法

@Slf4j
@RestController
public class FileController {@PostMapping("/upload")public Result upload(String username, Integer age, MultipartFile image) {log.info("文件上传:{},{},{}", username, age, image);return Result.success();}
}

此时通过前端页面发起请求:

<!DOCTYPE html>
<html lang="ch-ZN">
<head><meta charset="UTF-8"><title>上传文件</title>
</head>
<body><form action="/upload" method="post" enctype="multipart/form-data">姓名: <input type="text" name="username"><br>年龄: <input type="text" name="age"><br>头像: <input type="file" name="image"><br><input type="submit" value="提交"></form></body>
</html>

 通过调试启动服务,发现此时可以成功接收到上传的文件,并获取文件的路径:

转到该路径下发现了三个.temp的临时文件: 

这是因为该表单有三个表单项,分别是两个text表单项(username和age)和一个file表单项(image文件),两个大小小的就是传的username和age的值,30kb那个temp文件就是上传的文件了,通过记事本打开验证一下:

 

 

现在已经在服务端接收到了文件,但是一但程序运行停止,这些临时文件也会消失——只要这次请求响应结束结束后(不管成功与否),临时文件都会被删除,所以说后端程序不但要接收上传的文件,更重要的是还需要将接收到的文件保存起来。总结一下文件上传的准备工作: 前端页面需要三要素:1.需要在form表单中定义一个表单项的type为file;2.需要指定表单的提交方式为post;3.需要指定表单的编码格式enctype为multipart/form-data。 这三要素缺一不可!后端需要使用Spring框架提供的MultipartFile类来接收前端上传的文件。

本地存储

上述代码成功在服务端接收到了客户端上传的文件,但是发现只能生成一个临时文件,一但这次请求响应结束后,.temp临时文件就会自动删除,这显然是不符合开发逻辑的,所以说我们需要将这些.temp临时文件存储起来。此处先介绍本地存储。

本地存储就是:在服务端接收到客户端上传的文件之后,将文件存储在本地服务器磁盘中。因为是基于SpringBoot框架,这其实并不困难,因为Spring框架中的MultipartFile对象提供了这样的方法——transferTo,transferTo的参数中需要传递一个File文件对象,就是将.temp临时文件写入到这个传递的文件对象中完成文件的本地存储。

此处在获取File对象的时候出现一个问题:不能把文件名写死了——因为假如有多个文件时,若把文件名写死了,那么后接收到的文件就会把前一次接收到的文件的内容覆盖了,整个功能接口就只能保存一个文件了。此时的解决方法是将File对象的文件名存储为上传文件的原文件名,MultpartFile对象中封装了上传文件的所有信息,并且提供了对应的方法获取这些信息,所以说直接可以通过操作MultipartFile对象得到原文件名:

@Slf4j
@RestController
public class FileController {@PostMapping("/upload")public Result upload(String username, Integer age, MultipartFile image) throws IOException {String originalFilename = image.getOriginalFilename();image.transferTo(new File("E:\imagesTest\" + originalFilename));return Result.success();}
}

此时代码就可以正确的接收到客户端上传的文件并将其保存在File指定的路径了:

 

但此时还有一个问题,假如说A用户上传了一个1.txt文件,接着B用户又上传了一个txt文件,也叫1.txt,那么就会出现B用户的文件内容将A用户的文件内容覆盖的问题,因为本地存储是按照文件的原名称存储的,遇到重名文件就会出现这样的问题。

避免文件名重复导致的覆盖问题

可能有人会想到使用System.currentTimeMillis()这个方法获取当前时间的毫秒值作为文件名避免重复,但是在一些大的项目中,有可能同一毫秒就正好有两个人上传了同一个同名的文件,这还是不能从根本上解决文件名重复的问题;解决这个问题可以使用UUID(通用唯一识别码)作为文件名进行存储,UUID是不会重复的(小概率事件不发生)。

但是又存在一个问题,假如说将UUID作为文件名,那么文件的扩展名是什么? 其实也非常简单,因为我们已经得到了文件的原名称,通过寻找到原文件名(字符串)中最后一个“.”所处的位置(因为无论文件名是什么,最后一个.之后的才是扩展名),找到最后一个“.”所处的位置之后,直接通过subString()方法截取到最后就可以获取文件的扩展名了,然后再将其和UUID进行拼接,就可以生成一个以UUID命名存储的文件了。

@PostMapping("/upload")
public Result upload(String username, Integer age, MultipartFile image) throws IOException {// 获取原文件名String originalFilename = image.getOriginalFilename();// 获取最后一个“.”的索引int index = originalFilename.lastIndexOf(".");// 通过subString方法和最后一个“.”索引进行截取,获取文件扩展名String externalName = originalFilename.substring(index);// UUID + 扩展名 = 新文件名String newFileName = UUID.randomUUID().toString() + externalName;image.transferTo(new File("E:\imagesTest\" + newFileName));return Result.success();
}

此时,文件在本地存储就是UUID了,再也不会有重复的可能了。

文件上传的大小配置

在SpringBoot框架中,文件上传,默认单个文件允许最大大小为1M。如果需要上传大文件,可以根据需求在application.properties(我使用的是yaml配置文件进行配置,思想是一样的,只是配置的格式不同)配置文件中进行设置:

servlet:multipart:# 配置单个文件最大上传大小(默认1MB)max-file-size: 10MB# 配置单个请求最大上传大小(一次请求可以上传多个文件)max-request-size: 100MB

这样配置之后,就可以根据需求上传大文件了。

本地存储不足

1.将文件存储到本地,无法通过浏览器等直接访问到文件。

2.若项目中上传了大量文件,这些文件都存储到服务器的本地磁盘,服务器的磁盘空间是十分宝贵的,用来存储用户上传的文件是十分浪费的,并且若服务器的磁盘存储空间满了,想要扩容也是十分困难的,并且现在很多项目都是服务器集群,扩容就更加困难了。

3.若服务器的磁盘损坏,存储的文件恢复极其困难,安全性不高。

现在几乎已经不使用本地存储了,都是使用云存储。

 

 

 

相关文章:

JavaWeb文件上传

文件上传总览 文件上传主要是指将本地文件&#xff08;包括但不限于图片、视频、音频等&#xff09;上传到服务器&#xff0c;提供其他用户浏览或下载的过程。在日常生活中&#xff0c;我们在很多情况下都需要使用文件上传功能&#xff0c;比如&#xff1a;发微博、发朋友圈等…...

软件工程——期末复习(3)

一、题目类(老师重点提到过的题目) 1、高可靠性是否意味着高可用性&#xff1f;试举例证明自己的观点&#xff1f; 答&#xff1a;高可靠性不意味着高可用性 可靠性说明系统已经准备好&#xff0c;马上可以使用&#xff1b;可用性是系统可以无故障的持续运行&#xff0c;是一…...

apache的BeanUtils的Converter被相互污染覆盖问题

问题描述 apache的BeanUtils工具集中用来把map对象转换为java对象的BeanUtils#populate方法会因为单例的原因其转换器Converter被相互污染覆盖问题 maven依赖 <dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</…...

TCP的“可靠性”(上)

目录 TCP的“可靠性”&#xff08;上&#xff09;确认应答&#xff08;可靠性传输的基础&#xff09;超时重传连接管理&#xff08;三次握手&#xff0c;四次挥手&#xff09; TCP的“可靠性”&#xff08;上&#xff09; 想必大家都或多或少的听说过TCP的特性&#xff1a;有连…...

超标量处理器设计笔记(5)虚拟存储器、地址转换、page fault

虚拟存储器 概述地址转换单级页表多级页表案例最好情况&#xff1a;虚拟地址是连续的最差情况&#xff1a;每个第二级 PT 都装有一项 增加级数 Page Fault 程序保护 概述 当程序比物理内存空间更大时&#xff0c;无法全部装在物理内存中&#xff0c;需要对程序进行切片 虚拟…...

SparkSQL 读写数据攻略:从基础到实战

目录 一、输入Source 1&#xff09;代码演示最普通的文件读取方式&#xff1a; 2&#xff09; 通过jdbc读取数据库数据 3) 读取table中的数据【hive】 二、输出Sink 实战一&#xff1a;保存普通格式 实战二&#xff1a;保存到数据库中 实战三&#xff1a;将结果保存在h…...

react 使用状态管理调用列表接口渲染列表(包含条件查询,统一使用查询按钮,重置功能),避免重复多次调用接口的方法

react开发调用api接口一般使用useEffect来监听值的变化&#xff0c;通过值的变化与否来进行接口调用。 比如我们要进行一个查询接口 const [pageParams, setPage] useState({name: ,id: ,});const [dataList, setDataList] useState([]);const getList async () > {const…...

Stable Audio Open模型部署教程:用AI打造独家节拍,让声音焕发新活力!

Stable Audio Open 是一个开源的文本到音频模型&#xff0c;允许用户从简单的文本提示中生成长达 47 秒的高质量音频数据。该模型非常适合创建鼓点、乐器即兴演奏、环境声音、拟音录音和其他用于音乐制作和声音设计的音频样本。用户还可以根据他们的自定义音频数据微调模型&…...

加油站-(贪心算法)

题目描述 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定两个整数数组 gas…...

k8s-持久化存储PV与PVC(1)

1、概述 为什么 kubernetes 要持久化存储&#xff1f; 在 kubernetes 中部署应用都是以 Pod 的容器运行的&#xff0c;而 Pod 是有生命周期&#xff0c;一旦 Pod 被删除或重启后&#xff0c;这些数据也会随着丢失&#xff0c;则需要对这些数据进行持久化存储。 PV&#xff1…...

Linux Red Hat Enterprise

下载 https://developers.redhat.com/products/rhel/download 安装...

《中型 Vue 项目:挑战与成长》

一、引言 在当今的前端开发领域&#xff0c;Vue 作为一款渐进式 JavaScript 框架&#xff0c;以其强大的功能和灵活性备受开发者青睐。对于中型 Vue 项目而言&#xff0c;其重要性不言而喻。中型 Vue 项目通常在功能复杂度和规模上介于小型项目和大型项目之间&#xff0c;既需要…...

配置 DNS over HTTPS阻止DNS污染

概念介绍 DOH简介 ​ DNS&#xff08;域名系统&#xff09;的主要功能是将域名解析成IP地址&#xff0c;域名的解析工作由DNS服务器完成。从安全角度来看&#xff0c;域名解析的请求传输时通常不进行任何加密&#xff0c;这导致第三方能够很容易拦截用户的DNS&#xff0c;将用…...

Facebook广告文案流量秘诀

Facebook 广告文案是制作有效 Facebook 广告的关键方面。它侧重于伴随广告视觉元素的文本内容。今天我们的博客将深入探讨成功的 Facebook 广告文案的秘密&#xff01; 一、广告文案怎么写&#xff1f; 正文&#xff1a;这是帖子的正文&#xff0c;出现在您姓名的正下方。它可…...

22. 五子棋小游戏

文章目录 概要整体架构流程技术名词解释技术细节小结 1. 概要 &#x1f50a; JackQiao 对 米粒 说&#xff1a;“今天咱们玩个五子棋小游戏&#xff0c;电脑与你轮流在一个 nn 的网格上放置棋子&#xff08;X 或 O&#xff09;&#xff0c;网格由你输入的正整数n决定&#xff0…...

fastadmin框架同时使用 阿里云oss和阿里云点播

背景 项目的实际需求中既要用到阿里云oss产品又用到阿里云点播系统&#xff0c;实现完美的统一。设置两个地址downUrl&#xff0c;thirdCode。分别代表阿里云oss上传路径和阿里云点播系统vId。 实现 默认框架你已经集成好阿里云oss集成工作&#xff0c;前端html页面实现 <…...

Java-JMX 组件架构即详解

JMX架构由三个主要组件构成&#xff1a; ‌MBeans&#xff08;Managed Beans&#xff09;‌&#xff1a;代表可管理的资源&#xff0c;是JMX的核心。MBean可以是Java类或接口&#xff0c;提供了管理操作的接口&#xff0c;如获取系统信息、设置参数等。‌MBeanServer‌&#x…...

unity打包web,发送post请求,获取地址栏参数,解决TypeError:s.replaceAll is not a function

发送post请求 public string url "http://XXXXXXXXX";// 请求数据public string postData "{\"user_id\": 1}";// Start is called before the first frame updatevoid Start(){// Post();StartCoroutine(PostRequestCoroutine(url, postData…...

java+ssm+mysql校园物品租赁网

项目介绍&#xff1a; 使用javassmmysql开发的校园物品租赁网&#xff0c;系统包含管理员、用户角色&#xff0c;功能如下&#xff1a; 管理员&#xff1a;用户管理&#xff1b;物品管理&#xff08;物品种类、物品信息、评论信息&#xff09;&#xff1b;订单管理&#xff1…...

Spring Boot中实现JPA多数据源配置指南

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;本文详细介绍了在Spring Boot项目中配置和使用JPA进行多数据源管理的步骤。从引入依赖开始&#xff0c;到配置数据源、创建DataSource bean、定义实体和Repository&#xff0c;最后到配置事务管理器和使用多数据…...

服务器加固

1.服务器密码复杂度 密码最小长度&#xff0c;密码复杂度策略 vim /etc/pam.d/system-auth --------------- #密码配置 #ucredit&#xff1a;大写字母个数&#xff1b;lcredit&#xff1a;小写字母个数&#xff1b;dcredit&#xff1a;数字个数&#xff1b;ocredit&#xff1a;…...

探索CSS中的背景图片属性,让你的网页更加美观

导语&#xff1a;在网页设计中&#xff0c;背景图片的运用能够丰富页面视觉效果&#xff0c;提升用户体验。本文将详细介绍CSS中背景图片的相关属性&#xff0c;帮助大家更好地掌握这一技能。 一、背景图片基本属性 1、background-image 该属性用于设置元素的背景图片。语法如…...

Oracle的打开游标(OPEN_CURSORS)

一、OPEN_CURSORS 概述 OPEN_CURSORS 指定会话一次可以拥有的打开游标&#xff08;私有 SQL 区域的句柄&#xff09;的最大数量。可以使用此参数来防止会话打开过多的游标。 OPEN_CURSORS参数说明 特性 描述 参数类型 Integer 默认值 50 修改方式 ALTER SYSTEM PDB级别…...

数值分析—数值积分

研究背景 积分的数学解法为牛顿莱布尼兹公式&#xff0c;数学表示为 ∫ a b f ( x ) d x F ( b ) − F ( a ) \int_{a}^{b} f(x)dxF(b)-F(a) ∫ab​f(x)dxF(b)−F(a)&#xff0c;但应用该方法有如下困难&#xff1a; 1&#xff0c; f ( x ) f(x) f(x)的原函数有时不能用初等函…...

克服大规模语言模型限制,构建新的应用方法——LangChain

大模型 大模型的出现和落地开启了人工智能(AI)新一轮的信息技术革命&#xff0c;改变了人们的生 活方式、工作方式和思维方式。大模型的落地需要数据、算力和算法三大要素。经过几 年发展&#xff0c;大模型的数据集(包括多模态数据集)制作已经形成了规约&#xff0c;Meta、Go…...

计算机网络 —— HTTPS 协议

前一篇文章&#xff1a;计算机网络 —— HTTP 协议&#xff08;详解&#xff09;-CSDN博客 目录 前言 一、HTTPS 协议简介 二、HTTPS 工作过程 1.对称加密 2.非对称加密 3.中间人攻击 4.引入证书 三、HTTPS 常见问题 1.中间人能否篡改证书&#xff1f; 2.中间人能否调…...

React第十七章(useRef)

useRef 当你在React中需要处理DOM元素或需要在组件渲染之间保持持久性数据时&#xff0c;便可以使用useRef。 import { useRef } from react; const refValue useRef(initialValue) refValue.current // 访问ref的值 类似于vue的ref,Vue的ref是.value&#xff0c;其次就是vu…...

React第十五节useReducer使用详解差异

useReducer() 的用法注意事项 1、 概述&#xff1a; useReducer() 常用于管理复杂的状态更新逻辑&#xff0c;特别是在状态更新依赖于多个条件或动作时&#xff0c;useReducer 提供了一种更加结构化和可维护的方式来处理状态。可以将更新函数写在组件外面 它与 useState() 相…...

NanoLog起步笔记-5-客户端简要描述

nonolog起步笔记-5-客户端简要描述 客户端的简要的设计图路notify模式服务端最好分两个核 NanoLog::setLogLevel(NOTICE);从 NANO_LOG 开始NANO_LOGcompiling time的语句getNumNibblesNeeded&#xff1a;得到prompt中&#xff0c;number的数量countFmtParams&#xff1a;得到所…...

Flink:入门介绍

目录 一、Flink简介 2.1 Flink 架构 2.2 Flink 应用程序 运行模式 二、Flink 集群 部署 2.1 本地集群模式 2.1.1 安装JDK​编辑 2.1.2 下载、解压 Flink 2.1.3 启动集群 2.1.4 停止集群 2.2 Standalone 模式 2.2.0 集群规划 2.2.1 安装JDK 2.2.2 设置免密登录 2…...

设计网网站/外贸网站建站和推广

1 集合 集合是一个无序的&#xff0c;不重复的数据组合&#xff0c;它的主要作用如下&#xff1a; 去重&#xff0c;把一个列表变成集合&#xff0c;就自动去重了关系测试&#xff0c;测试两组数据之前的交集、差集、并集等关系创建集合 a {3, 5, 9, 9, 10} print(a) b ([1, …...

网站建设报告实训步骤/百度客服电话号码

统一项目管理平台&#xff08;UMPlatForm.NET&#xff09; 4.10 用户权限管理模块 统一项目管理平台&#xff08;UMPlatForm.NET&#xff09;,基于.NET的快速开发、整合框架。 4.10用户权限管理模块 在实际应用中我们会发现&#xff0c;权限控制会经常变动&#xff0c;如&#…...

兰州 网站建设/手机搜索引擎排行榜

1、遇到的bug 我通过APP客户端上传图片时&#xff0c;却发现服务器根本没有接受到此图片&#xff0c;后来才发现图片是3.9M&#xff0c;超过tomcat对http的post请求的默认接收大小2M的限制。 2、问题的根源 tomcat默认设置能接收HTTP POST请求的大小最大为2M,如果你的POST请求传…...

wordpress 网址导航/怎么在百度上做广告推广

一、USB请求 在USB规范里&#xff0c;对命令一词提供的单词为“Request”&#xff0c;但这里为了更好的理解主机与设备之间的主从关系&#xff0c;将它定义成“命令”。 所有的USB设备都要求对主机发给自己的控制命令作出响应&#xff0c;USB规范定义了11个标准命令&#xff0c…...

wordpress siren主题/引流软件

我希望通过博客的形式记录自己项目和基础积累的过程&#xff0c;这篇是算法以及程序设计的开篇。 题目&#xff1a;poj1753 Flip Game Time:1000MS Mem:65536K 描述&#xff1a;黑白两面的棋子&#xff0c;给一个4*4棋盘&#xff0c;每轮可以翻动其中任意一个棋子&#xff0…...

衡阳市党政门户网站/移动广告联盟

前言最近电脑经常关机要关好长时间&#xff0c;老是需要长按电源键强行关机。也不知道是怎么回事。后来查看关机时的日志&#xff0c;发现是mysql停不掉。这可闹心了&#xff01;怎么办&#xff1f;上网搜了搜也没有找到什么好的解决办法。总不能每次关机都要长按电源键吧&…...