后端之路——文件本地上传

news2024/11/15 10:13:19

一、基础原理

文件上传是一个很基础的知识点,尤其是本地上传,在现实开发基本都是云上传,但是作为一个基础要简单了解一下

首先前端我就不多讲解了,网页开发里用<form>表单可以上传文件,只需要加上这三属性: 【action="接口路径"】   【method="post"】   【enctype="multipart/form-data"】就可以上传文件了,这里我不打算讲细,因为这主要是讲后端,有兴趣的自己额外研究一下

代码在这,自己直接复制粘贴就行:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
    <style>
        .submit{
            width: 100px;
            height: 30px;
            margin-top: 20px;
            margin-left: 120px;
        }
        input{
            height: 30px;
            margin-bottom: 20px;
        }
        form{
            width: 20%;
            border: 1px solid black;
            padding: 20px;
            margin: auto;
            margin-top: 250px;
            display: flex;
            flex-direction: column;
        }
    </style>

</head>
<body>
    <form action="/upload" method="post" enctype="multipart/form-data">
        姓名:<input type="text" name="userName">
        年龄:<input type="text" name="age">
        头像:<input type="file" name="image">
        <input type="submit" value="提交" class="submit">
    </form>
</body>
</html>

提示:

这里为了方便我就直接在【spring boot工程】里写了前端页面,如果要在spring boot工程写前端html页面,必须在【resources】的【static】目录下设置

而且注意,你的html文件的文件名是啥,你到时【接上后端服务之后】访问的前端页面的网址路径就是啥:

在接入后端之前,我们在html文件右上角浏览器临时运行一下就行,后期接上了后端的接口之后再【运行整个后端项目】,然后访问【后端的网址+html文件名】来运行页面

然后打开浏览器的【检查】,右边除了我们常用的Console控制台,还有一个Network网络,谷歌是【Network】,别的可能是中文【网络】

谷歌浏览器Edge浏览器

点到当我们点击【submit提交按钮】时,就会触发一个【请求】,点一下就能展开,就能看到【请求的详情】:

谷歌浏览器

Edge浏览器

然后找到【请求头】(Request Headers),勾选【原始】(Raw)就能看到原请求头代码信息

可以看到【Content-Type】这块有两信息:第一个是表单上传的内容形式,第二个是多个信息上传时,信息之间的分隔符

那么我们具体的信息在哪,可以点到【负载】(Payload)看到我们传过去的信息

上面就是在浏览器查看文件上传的一些基本原理

二、然后讲一下后端怎么获取到上传的资源

注意,前端用<form>的形式发送请求的时候,后端的【请求注解】对应【form的action属性】和【form的method请求方式】、后端的【请求方法的参数名】要对应【form的每个输入框的name属性】

—— 然后后端接收文件参数的数据类型得是【MultipartFile】

当然要是参数名跟form的name属性名不也一样也可以,加一个【@RequestParam(" ")】注解就可以

那么现在在controller层加一个【controller类】,就叫:UpLoadController吧

代码如下:

//写你们自己的路径
//package com.czm.tliaswebmanagement.controller;
//import com.czm.tliaswebmanagement.pojo.Result;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@Slf4j
@RestController
public class UpLoadController {
    @PostMapping("/upload")
    public Result uplaod(String userName, Integer age, MultipartFile image){
        log.info("上传过来的参数{}  {}  {}",userName, age, image);
        return Result.success();
    }
}

接着在运行整个后端项目之前,在你的log.info输出日志的部分打个断点

然后点击【调试】,不要点【运行】,【调试】的话日志才能捕捉到前端发来的请求

然后到前端页面发送一下请求,就会跳到后端看到信息

然后点开“文件”的【location】,这个路径就是我们本地文件的地址

把路径复制到电脑文件夹跳转,就能看到文件了,这里三个文件是对应userName、age、image三个数据

不过这里的原理是:每次上传的时候,后端虽然能接收到文件,但只会生成【临时文件】,再运行完之后就会删除临时文件

只要去掉断点,在重新放行让程序运行完,再回到那个文件夹就会发现那三个文件被清空了

那就需要【文件上传的本地储存

三、后端获取文件后本地储存

因为黑马讲得太细了,而且现实开发里本来本地储存就很少用,那我这里就简短高效讲了

其实上传文件的原理就是:前端把文件变为二进制编码数据,通过后端传送给服务器,然后服务器保存下来这个文件。

那么现在我们本地储存的话,就可以理解本机电脑就是一个服务器了,我们就可以指定将文件保存到哪个位置

代码很简单,逻辑就是1、【获取文件名】,2、调用【文件.transferTo()】方法来指定文件存储路径,然后存储,3、给transferTo()里传入一个【File对象】,参数就是结尾是【文件名】的【绝对路径】字符串

(简单了解不要记,我后面会放源代码在下面,以后直接复制粘贴即可)

写的时候如果报错,那就鼠标悬停,点一下那个提示的帮助方法,就会在方法头那加一个【throws IOException抛出异常】就OK了

但是如果要传递多个文件,如果存在相同文件名的文件,上一个就会被覆盖,比如原来上传了一个【1.png】的文件,后面又上传一个叫【1.png】的文件,就会把上一张覆盖了,所以我们要保证每个文件名要【不同】【唯一】,那么就调用【UUID.randomUUID.toString()】方法获得随机的唯一的乱码字符串,来作为文件名

完整代码:(这就是完整的本地文件存储的代码,以后用到直接来这【复制】就行)

//写你们自己的路径
//package com.czm.tliaswebmanagement.controller;
//import com.czm.tliaswebmanagement.pojo.Result;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Slf4j
@RestController
public class UpLoadController {
    @PostMapping("/upload")
    public Result uplaod(String userName, Integer age, MultipartFile image) throws IOException {
        log.info("上传过来的参数{}  {}  {}",userName, age, image);

        /*---------------------------------【本地存储】----------------------------------*/
        //获取本地文件名(比如:1.jpg、 xxx.txt、 qids.png...)
        String originalFileName = image.getOriginalFilename();


        //获取原文件名的后缀名【.jpg】、【.png】、【.html】...
        int index = originalFileName.lastIndexOf(".");
        String extname = originalFileName.substring(index);
        //然后生成一个新的文件名
        String newFileName = UUID.randomUUID().toString() + extname;


        //调用【文件的transferTo】方法,往里面传入一个【File对象】,就可以指定文件【存储的具体路径】
        //当然【存储的具体路径】包括了【前面的绝对路径】+【后面的文件名】
        //下面例子就是把“F:\images\”和“asjhwuhwndm.jpg”拼成“F:\images\asjhwuhwndm.jpg”
        image.transferTo(new File("F:\\images\\" + newFileName));
        /*----------------------------------------------------------------------------*/

        return Result.success();
    }
}

最后一步,去【application.properties】文件,把下面两个代码配置上去,因为文件保存默认限制了单个文件1M以内,多个文件上传也有大小限制,这两个配置你就可以根据自己需要上传大文件了

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

四、发请求试一下

注意发请求这里写接口时,参数换成body的【form-data】,然后类型选【file】

发送请求的时候就点那个【Upload】按钮,上传你的本地文件,这里我传来三次不同的图片,我就不一一演示了

点开文件夹,成功

缺点就是文件本地会爆,所以了解即可,可能会用到,但不多,大部分还是【云存储】

下一篇讲:阿里云OSS云存储文件

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

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

相关文章

Yolov8模型调参大全:超详细解读每一个参数

目录 1. 代码获取方式 2. YOLOv8网络配置 3. Yolov8使用 3.1. CLI 3.2. Python 4.default.yaml文件解读 1. 代码获取方式 Yolov8项目地址&#xff1a;https://github.com/ultralytics/ultralytics 这里就不详细介绍v8了 2. YOLOv8网络配置 # Ultralytics YOLO &…

超详细的 C++中的封装继承和多态的知识总结<1.封装与继承>

引言 小伙伴们都知道C面向对象难&#xff0c;可是大家都知道&#xff0c;这个才是C和C的真正区别的地方&#xff0c;也是C深受所有大厂喜爱的原因&#xff0c;它的原理更接近底层&#xff0c;它的逻辑更好&#xff0c;但是学习难度高&#xff0c;大家一定要坚持下来呀&#xff…

上海路演服务app开发的意义与主要功能

随着经济水平与互联网技术的飞速发展&#xff0c; 金融活动也逐渐深入人们的日常生活&#xff0c;各类公司也试图通过互联网获得金融机会&#xff0c;探寻新的发展。为了让企业具有更快捷&#xff0c;更便利的宣传途径与方法&#xff0c;上海路演服务app应运而生。 一&#xf…

SSM慢性病患者健康管理系统设计与实现-计算机毕业设计源码04877

目 录 摘要 1 绪论 1.1 研究意义 1.2研究目的 1.3论文结构与章节安排 2 慢性病患者健康管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分…

VS2019+QT VS tools:Debug下ok,relese下报错

报错界面 踩得坑&#xff1a; 尝试一下重装 QT VS tools&#xff0c;结果装不上。 尝试卸载原来的QT VS tools&#xff1a;卸载方法&#xff0c;到下面文件夹下可以看到有两个文件夹&#xff0c;分别是两个插件&#xff0c;找到QT的插件&#xff0c;删除文件夹即可。但是删除…

管理沟通能力测试,求职应聘和HR人才测评

什么是管理沟通能力&#xff1f; 管理沟通能力&#xff0c;包含两个方面&#xff0c;1方面是管理能力&#xff0c;另一方面是沟通能力&#xff0c;对于企业招聘来说基础管理管理、中高层管理必定会做管理和沟通能力测试。 这是从人的性格层面&#xff08;人格&#xff09;去评…

Java学习十二—Java8特性之Optional类

一、简介 Java 8 引入了 Optional​ 类作为一种容器&#xff0c;可以用来显式地表示一个值存在或不存在。它解决了传统上可能会遇到的空指针异常问题&#xff0c;同时提供了一种更优雅的方式来处理可能为null的情况。 Java 8 中引入 Optional​ 类的背景可以从以下几个方面来理…

css flex 子元素溢出时,父元素被撑开解决方案

当父元素使用flex: 1;自适应填满时&#xff0c;子元素内容溢出&#xff0c;父元素内容撑大&#xff0c;导致页面显示问题&#xff0c;或设置了overflow 为scroll 的元素没出现滚动条等问题 解决方案&#xff1a; 1.如果是横向排列&#xff0c;flex: 1;的元素加上width: 0; 此…

【Matlab 路径优化】基于蚁群算法的XX市旅游景点线路优化系统

基于蚁群算法的XX市旅游景点线路优化系统 &#xff08;一&#xff09;客户需求&#xff1a; ①考虑旅游景点的空间分布、游客偏好等因素&#xff0c;实现了旅游线路的智能规划 ②游客选择一景点出发经过所要游览的所有景点只一次&#xff0c;最后回到出发点的前提下&#xf…

实验4 宏指令及子程序设计实验

从键盘输入10个无符号十进制数&#xff08;小于256&#xff09;&#xff0c;将其转换为二进制数并存放在NUM字节型变量中&#xff0c;找出其中的最大数&#xff0c;并将找出的最大数在屏幕上显示出来。 要求&#xff1a; 1&#xff09;在屏幕上显示字符串提示信息的功能由宏指…

【PB案例学习笔记】-28制作一个右键菜单

写在前面 这是PB案例学习笔记系列文章的第28篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gite…

多态相关知识2

多态相关知识2 抽象基类和纯虚函数纯虚函数和多继承虚析构函数虚析构函数作用纯虚析构函数 重写 重载 重定义 抽象基类和纯虚函数 在设计时&#xff0c;常常希望基类仅仅作为其派生类的一个接口。这就是说&#xff0c;仅想对基类进行向上类型转换&#xff0c;使用它的接口&…

Wing FTP Server

文章目录 1.Wing FTP Server简介1.1主要特点1.2使用教程 2.高级用法2.1Lua脚本,案例1 1.Wing FTP Server简介 Wing FTP Server&#xff0c;是一个专业的跨平台FTP服务器端&#xff0c;它拥有不错的速度、可靠性和一个友好的配置界面。它除了能提供FTP的基本服务功能以外&#…

据阿谱尔APO Research统计,2023年全球皮肤科药物市场价值为 751.7 亿美元

据阿谱尔 (APO Research&#xff09;统计&#xff0c;2023 年全球皮肤科药物市场价值估计为 751.7 亿美元&#xff0c;预计到 2030 年将达到 1622.1 亿美元&#xff0c;预测期内&#xff08;2024-2030 年&#xff09;的复合年增长率为 11.44%。 全球最大的单一类别皮肤科药物是…

TheBrain 14:AI增强的视觉知识管理工具

TheBrain是一款与众不同的思维导图软件&#xff0c;其所有信息通过一个又一个的节点进行联系&#xff0c;最终形成一个杂而不乱的网状结构。与传统的树形思维导图相较而言&#xff0c;TheBrain更有助于整合零散的资源&#xff0c;激发创意和锻炼思维。此次thebrain13带来了很多…

基因组学系列3:基因分型Phasing与单倍型参考序列HRC

1. 基因分型Phasing概念 基因分型&#xff0c;也称为基因定相、单倍体分型、单倍体构建等&#xff0c;即将一个二倍体&#xff08;或多倍体&#xff09;基因组上的等位基因&#xff08;或杂合位点&#xff09;正确定位到父亲或母亲的染色体上&#xff0c;最终使得来自同一亲本…

HMI 的 UI 风格成就经典

HMI 的 UI 风格成就经典

【自动驾驶仿真在做什么——初学者总结(陆续补充)】

文章目录 基础概念自动驾驶级别再稍提一下ODD是什么&#xff1f; 自动驾驶仿真分类软件在环仿真硬件仿真 仿真究竟难在哪&#xff1f;一些名词解释 最近也是学习自动驾驶仿真相关知识&#xff0c;习惯去总结一下&#xff0c;方便自己回顾和总结&#xff0c;主要包括了自动驾驶框…

登 Cell 子刊!清华大学张强锋课题组开发 SPACE 算法,组织模块发现能力领先同类工具

多细胞生物中的细胞尽管共享相同的基因组&#xff0c;但因其内部基因调控网络的差异以及与周围微环境中相邻细胞的外部信号交流&#xff0c;使得它们在形态、基因表达和功能上展现出显著的多样性。为了将细胞类型信息与其在组织内的空间位置相关联&#xff0c;空间转录组学 (Sp…

OpenLCA、GREET、R语言的生命周期评价方法、模型构建

原文链接&#xff1a;OpenLCA、GREET、R语言的生命周期评价方法、模型构建教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247608240&idx6&sn1b5758206d500399fe7cc69e800f61fe&chksmfa826657cdf5ef413d31557941a1c5db5cc84bba8d0f408c469e05a4118c…