SpringBoot案例-文件上传

news2024/12/24 8:08:51

目录

简介

文件上传前端页面三要素

 服务端接收文件

小结

本地储存

实现

代码优化

小结 

阿里云OSS

阿里云

阿里云OSS

使用第三方服务--通用思路

 准备工作

参照官方SDK代码,编写入门程序

集成使用

阿里云OSS-使用步骤

阿里云OSS使用步骤

参照SDK编写入门程序

案例集成OSS (文件上传接口的实现)

 引入阿里云OSS工具类

控制类

测试 

前后端联调 

小结

文件上传介绍

前端页面三要素(file表单项、post方法、multipart/form-data)

服务端接口接收文件(Multipart)

文件存储方式


简介

  • 文件上传,是指将本地图片、视频、音频等文件上传至服务器,供其他用户浏览或者下载的过程
  • 文件上传在项目中应用非常广泛,我们经常发微博、发朋友圈都要用到文件上传功能。

文件上传前端页面三要素

表单项file

表单提交方式

表单的编码格式

上述页面运行结果为:

 服务端接收文件

控制类代码如下:

package com.example.tlias.controller;

import com.example.tlias.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;

@RestController
@Slf4j

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

}

 调试运行SpringBoot项目,在浏览器中访问html前端页面,设置程序断点,如果不设置断点,程序运行完成之后,接收的临时文件会自动删除。具体示意如下:

然后在浏览器中访问前端页面

点击提交后, 程序终端显示如下:

 显示接收到前端的数据以及数据临时存放的位置

小结

  • 前端页面三要素
    • 表单项 type=“file”
    • 表单提交方式 post
    • 表单的enctype属性 multipart/form-data
  • 服务端接收wenjian
    • MultipartFile

本地储存

实现

  • 在服务端,接收到上传上来的文件之后,将文件存储在本地服务器磁盘中
  • 具体控制类代码如下
    • package com.example.tlias.controller;
      
      import com.example.tlias.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;
      
      @RestController
      @Slf4j
      
      public class UpLoadController {
          @PostMapping("upload")
          public Result upload(String username, Integer age, MultipartFile image) throws IOException {
              log.info("文件上传,name:{},age:{},image:{}", username, age, image);
              //  todo 获取原始文件名
              String name = image.getOriginalFilename();
              //  todo 将文件存储在服务器指定的磁盘目录中
              image.transferTo(new File("D:\\downloadFile\\" + name));
              return Result.success();
          }
      
      }
      

使用psotman进行测试

具体请求路径以及请求参数如下

在对应的文件目录中显示如下:

成功将前端传递的文件存储到本地服务器的磁盘中 

代码优化

  • 存在的问题:当前端传递的文件名称相同时,就会出现文件覆盖的问题
  • 问题的解决:为每一个接收到的文件重新设置一个新的名字即可,新的名字由UUID以及该文件的后缀名组成,UUID使用java自带的aip进行生成,后缀名通过截取文件原名称所得
  • 具体代码如下:
    • package com.example.tlias.controller;
      
      import com.example.tlias.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;
      
      @RestController
      @Slf4j
      
      public class UpLoadController {
          @PostMapping("upload")
          public Result upload(String username, Integer age, MultipartFile image) throws IOException {
              log.info("文件上传,name:{},age:{},image:{}", username, age, image);
              //  todo 获取原始文件名,但是不同文件的原始文件名可能相同
              String name = image.getOriginalFilename();
              // todo 构造唯一文件名--uuid(通用唯一识别码)
              // 获取文件后缀名
              int index = name.lastIndexOf(".");//获取最后的.的索引位置
              String extname = name.substring(index);//进行截取
              String newName = UUID.randomUUID().toString() + extname;//创建唯一文件名
              log.info("获取到的新的文件名为:{}", newName);
              //  todo 将文件存储在服务器指定的磁盘目录中
              image.transferTo(new File("D:\\downloadFile\\" + newName));
              return Result.success();
          }
      
      }
      

使用postman重新发送相同的请求,运行结果如下:

 

问题成功解决 

在SpringBoot中,文件上传,默认单个文件允许最大大小为1M,如果需要上传大文件,可以进行如下配置

小结 

  • String getOriginalFilename() -->获取原始文件名
  • void transferTo(File dest)-->将接受文件转存到磁盘文件中
  • long getSize() -->获取文件大小,单位字节(byte) 1KB=1024字节
  • byte[ ] getBytes() --> 获取文件内容的字节数组
  • InputStream getInputStream() -->获取接收到的文件内容的输入流

阿里云OSS

阿里云

  • 阿里云是阿里巴巴集团旗下全球领先的云计算公司,也是国内最大的云服务提供商

阿里云OSS

  • 阿里云对象存储OSS(Object Storage Service ),是一款海量、安全、低成本、高可靠的云存储服务。使用OSS,可以通过网路随时存储和调用包括文本、图片、音频和视频等在内的各种文件。

使用第三方服务--通用思路

 准备工作

参照官方SDK代码,编写入门程序

  • SDK是软件开发工具包(Software Development Kit)的缩写,它是一组用于开发特定软件应用或平台的工具、库和文档的集合。SDK提供了开发者所需的工具和资源,以便他们能够更轻松地创建、测试和部署软件应用。SDK通常包含编译器、调试器、API文档、示例代码和其他开发工具,以及与特定平台或操作系统交互的库和组件。开发者可以使用SDK来构建应用程序、插件、扩展或其他软件组件,以便与特定的软件、硬件或服务进行集成。

集成使用

阿里云OSS-使用步骤

阿里云OSS使用步骤

注册阿里云---充值(选做)---开通对象存储服务(OSS)---创建bucket---获取AccessKey(密钥)---参照官方SDK编写入门使用----案例集成OSS

  • Bucket:存储空间是用户用于存储对象(object,就是文件)的容器,所有对象都必须隶属于某个存储空间

具体使用步骤参照一下文件:

【腾讯文档】SpringBoot案例所需文档
https://docs.qq.com/doc/DUkRiTWVaUmFVck9N

参照SDK编写入门程序

根据阿里云官方提供的文档进行操作即可

  • 首先安装Java JDK
  • 然后进行需要进行的OSS操作 

     复制对应的代码即可,根据自己的信息修改其中的具体代码

我要使用文件上传的功能,具体代码如下:

package com.example.tlias;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;

import java.io.FileInputStream;
import java.io.InputStream;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        // todo 指定OSS服务地址

        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // todo 设置访问凭证

        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket名称,例如examplebucket。
        // todo 指定文件所存储的bucket名字(bucketName),以及文件的名称(objectName)

        String bucketName = "examplebucket";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "exampledir/exampleobject.txt";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
        // todo 指定本地要上传的文件

        String filePath = "D:\\localpath\\examplefile.txt";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            InputStream inputStream = new FileInputStream(filePath);
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
            // 创建PutObject请求。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
} 

修改完具体的参数之后,允许一下该java程序,允许结果如下:

运行成功 

 并且会为每一个文件设置一个访问的url地址

案例集成OSS (文件上传接口的实现)

 在员工案例中的对于新增员工接口功能的实现中,还没有实现对于员工头像信息的上传,头像上传功能的实现,参照接口文档中的文件上传接口,接口文档的具体链接如下:

https://hkm-web.oss-cn-beijing.aliyuncs.com/%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3

 引入阿里云OSS工具类

package com.example.tlias.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.UUID;

/**
 * 阿里云 OSS 工具类
 */
@Component
public class AliOSSUtils {

    // todo 指定OSS服务地址
    private String endpoint = "你自己的";
    // todo 设置密钥账号和密码
    private String accessKeyId = "你自己的";
    private String accessKeySecret = "你自己的";
    // todo 设置文件存储buket
    private String bucketName = "你自己的";

    /**
     * 实现上传图片到OSS
     */
    public String upload(MultipartFile file) throws IOException {
        // 获取上传的文件的输入流
        InputStream inputStream = file.getInputStream();

        // 避免文件覆盖
        String originalFilename = file.getOriginalFilename();
        String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));

        //上传文件到 OSS
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        ossClient.putObject(bucketName, fileName, inputStream);

        //文件访问路径
        String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
        // 关闭ossClient
        ossClient.shutdown();
        return url;// 把上传到oss的路径返回
    }

}

控制类

package com.example.tlias.controller;

import com.example.tlias.pojo.Result;
import com.example.tlias.utils.AliOSSUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
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;

@RestController
@Slf4j

public class UpLoadController {
    // todo 文件存储到本地
//    @PostMapping("/upload")
//    public Result upload(String username, Integer age, MultipartFile image) throws IOException {
//        log.info("文件上传,name:{},age:{},image:{}", username, age, image);
//        //  todo 获取原始文件名,但是不同文件的原始文件名可能相同
//        String name = image.getOriginalFilename();
//        // todo 构造唯一文件名--uuid(通用唯一识别码)
//        // 获取文件后缀名
//        int index = name.lastIndexOf(".");//获取最后的.的索引位置
//        String extname = name.substring(index);//进行截取
//        String newName = UUID.randomUUID().toString() + extname;//创建唯一文件名
//        log.info("获取到的新的文件名为:{}", newName);
//        //  todo 将文件存储在服务器指定的磁盘目录中
//        image.transferTo(new File("D:\\downloadFile\\" + newName));
//        return Result.success();
//    }
// todo 文件存储至阿里云OSS
    @Autowired
    private AliOSSUtils aliOSSUtils;

    @PostMapping("/upload")
    public Result upload(MultipartFile image) throws IOException {
        log.info("文件上传至阿里云,文件名:{}", image.getOriginalFilename());
        // 调用阿里云OSS工具进行文件上传
        String url = aliOSSUtils.upload(image);
        log.info("文件上传完成,文件url地址为:{}", url);
        return Result.success(url);

    }
}

测试 

前后端联调 

 

运行成功  

小结

文件上传介绍

前端页面三要素(file表单项、post方法、multipart/form-data)

服务端接口接收文件(Multipart)

文件存储方式

  • 本地存储(无法直接访问、磁盘空间受限、磁盘损坏)
  • 云存储OSS

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

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

相关文章

【QT5-自我学习-线程qThread练习-两种使用方式-2:通过继承Qobject类-自己实现功能函数方式-基础样例】

【QT5-自我学习-线程qThread练习-两种使用方式-2:通过继承Qobject类-自己实现功能函数方式-基础样例】 1、前言2、实验环境3-1、学习链接-参考文章3-2、先前了解-自我总结(1)线程处理逻辑事件,不能带有主窗口的事件(2&…

攻防世界-base÷4

原题 解题思路 base644,莫不是base16,base16解码网站: 千千秀字

k8s 安装istio (一)

前置条件 已经完成 K8S安装过程十:Kubernetes CNI插件与CoreDNS服务部署 部署 istio 服务网格与 Ingress 服务用到了 helm 与 kubectl 这两个命令行工具,这个命令行工具依赖 ~/.kube/config 这个配置文件,目前只在 kubernetes master 节点中…

postgres数据常用SQL语句

-- 系统信息函数 select version(),user,current_user; -- 创建表 CREATE TABLE biao(id INT primary key,name VARCHAR(25) not null,sex VARCHAR(25) unique,salary FLOAT default 9000 ); -- 更换表名 ALTER TABLE biaoRename to biao1; -- 更换字段类型 ALTER TABLE biao1 …

Tushare入门小册

Tushare入门小册 一、Tushare平台介绍 Pro版数据更稳定质量更好了,我们提供的不再是直接从互联网抓取,而是通过社区的采集和整理存入数据库经过质量控制后再提供给用户。但Pro依然是个开放的,免费的平台,不带任何商业性质和目的…

红黑树的调整图解

讲的很好 的红黑树原理 上面的视频讲解的红黑树很好。尤其是关于红黑树的调整。画图做了下总结,谢谢。

AVL——平衡搜索树

✅<1>主页&#xff1a;我的代码爱吃辣&#x1f4c3;<2>知识讲解&#xff1a;数据结构——AVL树☂️<3>开发环境&#xff1a;Visual Studio 2022&#x1f4ac;<4>前言&#xff1a;AVL树是对二叉搜索树的严格高度控制&#xff0c;所以AVL树的搜索效率很高…

微服务中间件--统一网关Gateway

统一网关Gateway 8.统一网关Gatewaya.搭建网关服务b.路由断言工厂c.路由过滤器GatewayFilterd.全局过滤器GlobalFiltere.过滤器的执行顺序f.网关的cors跨域配置 8.统一网关Gateway 网关功能&#xff1a; 身份认证和权限校验服务路由、负载均衡请求限流 网关的技术实现 在Spr…

基于大数据+django+mysql的银行信用卡用户的数仓系统

系统阐述的是银行信用卡用户的数仓系统的设计与实现&#xff0c;对于Python、B/S结构、MySql进行了较为深入的学习与应用。主要针对系统的设计&#xff0c;描述&#xff0c;实现和分析与测试方面来表明开发的过程。开发中使用了 django框架和MySql数据库技术搭建系统的整体架构…

国民新旅游时代拉开大幕,OTA平台迎来新红利和新任务

高温轮番而至&#xff0c;这个燥热的夏天&#xff0c;旅游业也躁动不已。 上半年是旅游业丰收的半年&#xff0c;各地旅游盛况频上热搜。文旅部公布的旅游数据显示&#xff0c;2023年上半年&#xff0c;国内旅游总人次23.84亿&#xff0c;同比增长63.9%&#xff1b;国内旅游收…

IO day 7

1、使用消息队列完成两个进程间相互通信 msgsnd #include <myhead.h>typedef struct {long msgtype;char data[1024]; }Msg_ds;#define SIZE sizeof(Msg_ds)-sizeof(long)int main(int argc, const char *argv[]) {//创建key值key_t key;if((key ftok("/",k…

Feign:使用接口方式调用服务

创建一个新的消费者模块并导入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://ma…

创建k8s operator

目录 1.前提条件 2.进一步准备 2.1.安装golang 2.2.安装code&#xff08;vscode的linux版本&#xff09; 2.3.安装kubebuilder 3.开始创建Operator 3.1.什么是operator? 3.2.GV & GVK & GVR 3.3.创建operator 3.3.1. 生成工程框架 3.3.2.生成api(GVK) …

C++设计模式之适配器模式

一、适配器模式 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;用于将一个类的接口转换成另一个类所期望的接口&#xff0c;以便两个类能够协同工作。 适配器模式可以解决现有类接口与所需接口不匹配的问题&#xff0c;使得原本因接口不…

JavaScript下载excel文件

文章目录 通过链接下载a标签下载方法注意 获取文件流请求体配置下载文件流 总结 通过链接下载 a标签 对于已知地址的目标文件&#xff0c;前端可以使用 a标签 来直接下载&#xff0c;使用a标签下载使用到两个属性 download&#xff1a;下载文件名href&#xff1a;目标文件下…

ORA-01174: DB_FILES be compatible RAC rolling fashion complete outage

How to change the DB_FILES parameter in RAC (Doc ID 1636681.1)​编辑To Bottom In this Document Goal Solution APPLIES TO: Oracle Database - Enterprise Edition - Version 10.1.0.2 and later Oracle Database Cloud Schema Service - Version N/A and later Oracle…

【业务功能篇75】微服务项目环境搭建docker-mysql-redisSpringCloudAlibaba

项目环境准备 1.虚拟机环境 我们可以通过VMWare来安装&#xff0c;但是通过VMWare安装大家经常会碰到网络ip连接问题&#xff0c;为了减少额外的环境因素影响&#xff0c;Docker内容的讲解我们会通过VirtualBox结合Vagrant来安装虚拟机。 VirtualBox官网&#xff1a;https:/…

《热题101》链表篇

思路&#xff1a;之前有反转链表前n个值、以及反转指定区间的链表&#xff0c;所以这个我只想在这两个基础上实现。用左右指针来确定当前反转的区间&#xff0c;每次反转之前都检查一下当前区间是否足够k&#xff0c;即区间之后的节点cur&#xff0c;足够就可以反转&#xff0c…

【Flink】Flink架构及组件

我们学习大数据知识的时候&#xff0c;需要知道大数据组件如何安装以及架构组件&#xff0c;这将帮助我们更好的了解大数据组件 对于大数据Flink&#xff0c;架构图图下&#xff1a; 整个架构图有三种关键组件 1、Client&#xff1a;负责作业的提交。调用程序的 main 方法&am…

基于乌鸦算法优化的BP神经网络(预测应用) - 附代码

基于乌鸦算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于乌鸦算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.乌鸦优化BP神经网络2.1 BP神经网络参数设置2.2 乌鸦算法应用 4.测试结果&#xff1a;5.Matlab代码 摘要…