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

Spring Boot教程之二十一:文件处理

Spring Boot – 文件处理

Spring Boot 是一种流行的、基于 Spring 的开源框架,用于开发强大的 Web 应用程序和微服务。由于它建立在 Spring 框架之上,因此它不仅具有 Spring 的所有功能,而且还包括某些特殊功能,例如自动配置、健康检查等。这使开发人员能够更轻松地以最少的配置设置基于 Spring 的应用程序,从而促进快速应用程序开发。

Spring Boot 文件处理是指使用 RESTful Web 服务下载和上传文件。本文将逐步介绍如何使用 Spring Boot 实现可用于上传和下载文件的 RESTful Web 服务。

Spring Boot 中文件处理的初始设置

需要使用 Spring Initializer 创建具有Spring Web依赖项的 Spring Boot 项目,

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

现在让我们开始开发 Spring Boot App。它将为以下对象提供 RESTful Web 服务:

  • 上传文件 
  • 下载文件
  • 获取已上传文件名列表

应用程序的实施

步骤 1:设置Application.Properties文件,其中包含分部分文件上传所需的配置。

spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

这些配置可以解释如下:

spring.servlet.multipart.enabled -> 确定是否必须启用 multipart
spring.servlet.multipart.max-file -> 指定允许上传的文件的最大大小。
spring.servlet.multipart.max-request-size -> 指定允许的 multipart/form-data 请求的最大大小。

步骤 2:创建一个 RestController FileController,处理以下 REST API:

1. 上传API

用法:可用于上传文件。它使用多部分请求。URL
/upload
HttpMethod:POST

实施细节:

为了开发此 API,我们使用 MultipartFile 作为请求参数。上传的文件以表单数据的形式发送,然后在 Rest 控制器中作为 Multipart 文件检索。因此,MultipartFile只不过是在多部分请求中收到的上传文件的一种表示。

2. 获取文件 API

用法:可用于获取已上传的文件名列表。URL
/getFIles
HttpMethod:GET

实施细节:

它可以简单地通过使用java.io.Filelist()方法来实现,该方法返回一个字符串数组,该数组命名由给定的抽象路径名表示的目录中的文件和目录。

3. 下载API

它可用于下载先前上传的文件。URL
/download/{filename}
HttpMethod:POST

实施细节:

要实现此 API,我们首先检查所请求下载的文件是否存在于上传的文件夹中。如果文件存在,我们使用InputStreamResource下载该文件。还需要将响应标头中的 Content-Disposition 设置为附件并将MediaType设置为application/octet-stream。 

Content -Disposition响应头作为附件,表示要下载内容。contentType设置为 application/octet-stream 这样当尝试下载缺少扩展名或格式未知的文件时,系统会将其识别为八位字节流文件。FileController 的实现如下所示: 

  • Java

// Java Program to Create Rest Controller 

// that Defines various API for file handling

package com.SpringBootFileHandling.controller;

  

// Importing required classes

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.util.Arrays;

  

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.core.io.InputStreamResource;

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpStatus;

import org.springframework.http.MediaType;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.multipart.MultipartFile;

  

// Annotation

@RestController

public class FileController {

      

    // Uploading a file

    @RequestMapping(value = "/upload", method = RequestMethod.POST)

    public String uploadFile(@RequestParam("file") MultipartFile file){

  

        // Setting up the path of the file

        String filePath = System.getProperty("user.dir") + "/Uploads" + File.separator + file.getOriginalFilename();

        String fileUploadStatus;

          

        // Try block to check exceptions

        try {

              

            // Creating an object of FileOutputStream class  

            FileOutputStream fout = new FileOutputStream(filePath);

            fout.write(file.getBytes());

              

            // Closing the connection 

            fout.close();

            fileUploadStatus = "File Uploaded Successfully";

              

        } 

        

        // Catch block to handle exceptions

        catch (Exception e) {

            e.printStackTrace();

            fileUploadStatus =  "Error in uploading file: " + e;

        }

        return fileUploadStatus;

    }

      

    // Getting list of filenames that have been uploaded

    @RequestMapping(value = "/getFiles", method = RequestMethod.GET)

    public String[] getFiles()

    {

        String folderPath = System.getProperty("user.dir") +"/Uploads";

          

          // Creating a new File instance

        File directory= new File(folderPath);

          

        // list() method returns an array of strings 

          // naming the files and directories 

          // in the directory denoted by this abstract pathname

        String[] filenames = directory.list();

          

        // returning the list of filenames

        return filenames;

          

    }

      

    // Downloading a file

    @RequestMapping(value = "/download/{path:.+}", method = RequestMethod.GET)

    public ResponseEntity downloadFile(@PathVariable("path") String filename) throws FileNotFoundException {

      

        // Checking whether the file requested for download exists or not

        String fileUploadpath = System.getProperty("user.dir") +"/Uploads";

        String[] filenames = this.getFiles();

        boolean contains = Arrays.asList(filenames).contains(filename);

        if(!contains) {

            return new ResponseEntity("FIle Not Found",HttpStatus.NOT_FOUND);

        }

          

        // Setting up the filepath

        String filePath = fileUploadpath+File.separator+filename;

          

        // Creating new file instance

        File file= new File(filePath);

          

        // Creating a new InputStreamResource object

        InputStreamResource resource = new InputStreamResource(new FileInputStream(file));

          

        // Creating a new instance of HttpHeaders Object

        HttpHeaders headers = new HttpHeaders();

          

        // Setting up values for contentType and headerValue

        String contentType = "application/octet-stream";

        String headerValue = "attachment; filename=\"" + resource.getFilename() + "\"";

               

        return ResponseEntity.ok()

                .contentType(MediaType.parseMediaType(contentType))

                .header(HttpHeaders.CONTENT_DISPOSITION, headerValue)

                .body(resource); 

          

    }

}

步骤3:运行Spring Boot应用程序并使用postman测试API,如下所示。

1. 上传API

为了上传文件,我们需要在 Postman 中点击http://localhost:8080/upload,并使用如下所示的表单数据:

 

文件上传成功后,我们可以在Uploads文件夹中看到该文件,如下所示:

2. 获取文件 API

我们需要在 postman 中点击http://localhost:8080/getFiles来获取已上传的文件名列表。

 

3. 下载API

为了下载文件,我们需要在 postman 中点击http://localhost:8080/download/{filename},如下所示。

可以通过单击“保存响应”->“保存到文件”将 Postman 中收到的响应下载为文件。也可以在浏览器中点击下载 URL 以直接下载文件。如果我们尝试下载不存在的文件,则会在响应中收到“文件未找到”以及HttpStatusNOT_FOUND

相关文章:

Spring Boot教程之二十一:文件处理

Spring Boot – 文件处理 Spring Boot 是一种流行的、基于 Spring 的开源框架&#xff0c;用于开发强大的 Web 应用程序和微服务。由于它建立在 Spring 框架之上&#xff0c;因此它不仅具有 Spring 的所有功能&#xff0c;而且还包括某些特殊功能&#xff0c;例如自动配置、健康…...

【Linux】Linux的基本常识+指令

目录 1. 整体学习思维导图 2. 常见快捷键操作 3. 基本指令 pwd指令 whoami指令 ls 指令 touch指令 cd 指令 Stat 指令 mkdir 指令 alias指令 nano 指令 rmdir 和 rm 指令 man 指令手册 cp 命令 cat/echo/tac 指令 mv 指令 less 指令 head/tail 指令 date…...

Rocky Linux 9.3系统搭建Slurm环境【笔记】

实践环境:Rocky Linux 9.3 [root@m1 ~]# cat /etc/redhat-release Rocky Linux release 9.3 (Blue Onyx) [root@m1 ~]# uname -r 5.14.0-362.8.1.el9_3.x86_64 [root@m1 ~]#主机名和IP ● 控制节点m1:10.1.1.10 ● 计算节点c1:10.1.1.11 ● 计算节点c2:10.1.1.12 一、…...

原生微信小程序使用原子化tailwindcss

这里使用了第三方库来实现:https://weapp-tw.icebreaker.top/ 官方配置步骤一: https://weapp-tw.icebreaker.top/docs/quick-start/native/install 官方配置步骤二:https://weapp-tw.icebreaker.top/docs/quick-start/native/install-plugin 我下面的操作步骤跟官方步骤…...

《掌握Nmap:全面解析网络扫描与安全检测的终极指南》

 nmap # 简介&#xff08;帮助&#xff09; 用法&#xff1a;nmap [扫描类型] [选项] {目标指定内容} 简介&#xff08;帮助&#xff09; 用法&#xff1a;nmap [扫描类型] [选项] {目标指定内容} 一、目标指定&#xff1a; 可以传入主机名、IP 地址、网络等。 例如&a…...

k8s-Informer概要解析(2)

Client-go 主要用在 k8s 控制器中 什么是 k8s Informer Informer 负责与 kubernetes APIServer 进行 Watch 操作&#xff0c;Watch 的资源&#xff0c;可以是 kubernetes 内置资源对象&#xff0c;也可以 CRD。 Informer 是一个带有本地缓存以及索引机制的核心工具包&#x…...

UE5基本数据类型

bool: 表示布尔值&#xff0c;只有两个取值&#xff1a;true 或 false&#xff0c;用于表示逻辑条件。int8: 表示 8 位的有符号整数&#xff0c;范围是 −128−128 到 127127。uint8: 表示 8 位的无符号整数&#xff0c;范围是 00 到 255255。int16: 表示 16 位的有符号整数&am…...

Next.js 系统性教学:中间件与国际化功能深入剖析

更多有关Next.js教程&#xff0c;请查阅&#xff1a; 【目录】Next.js 独立开发系列教程-CSDN博客 目录 一、Next.js 中间件 (Middleware) 功能解析 1.1 什么是中间件&#xff1f; 1.2 Next.js 中间件的工作机制 1.3 中间件的功能应用 身份验证与授权 请求重定向 修改请…...

鸿蒙HarmonyOS元服务应用开发实战完全指导

内容提要 元服务概述 元服务开发流程 第一个元服务开发 元服务部署与运行 一、服务概述 1、什么是元服务 在万物互联时代&#xff0c;人均持有设备量不断攀升&#xff0c;设备种类和使用场景更加多样&#xff0c;使得应用开发、应用入口变得更加复杂。在此背景下&#x…...

CT中的2D、MPR、VR渲染、高级临床功能

CT中的2D、MPR、VR渲染 在CT&#xff08;计算机断层扫描&#xff09;中&#xff0c;2D、MPR&#xff08;多平面重建&#xff09;、VR&#xff08;体积渲染&#xff09;是不同的图像显示和处理技术&#xff0c;它们各自有独特的用途和优势。下面分别介绍这三种技术&#xff1a;…...

利用docker-compose来搭建flink集群

1.前期准备 &#xff08;1&#xff09;把docker&#xff0c;docker-compose&#xff0c;kafka集群安装配置好 参考文章&#xff1a; 利用docker搭建kafka集群并且进行相应的实践-CSDN博客 这篇文章里面有另外两篇文章的链接&#xff0c;点进去就能够看到 &#xff08;2&…...

力扣打卡10:K个一组翻转链表

链接&#xff1a;25. K 个一组翻转链表 - 力扣&#xff08;LeetCode&#xff09; 这道题需要在链表上&#xff0c;每k个为一组&#xff0c;翻转&#xff0c;链接。 乍一看好像比较容易&#xff0c;其实有很多细节。比如每一组反转后怎么找到上一组的新尾&#xff0c;怎么找到…...

深度学习详解

深度学习&#xff08;Deep Learning&#xff0c;DL&#xff09;是机器学习&#xff08;Machine Learning&#xff0c;ML&#xff09;中的一个子领域&#xff0c;利用多层次&#xff08;深层&#xff09;神经网络来自动从数据中提取特征和规律&#xff0c;模仿人脑的神经系统来进…...

鸿蒙分享(一):添加模块,修改app名称图标

码仓库&#xff1a;https://gitee.com/linguanzhong/share_harmonyos 鸿蒙api:12 新建公共模块common 在entry的oh-package.json5添加dependencies&#xff0c;引入common模块 "dependencies": {"common": "file:../common" } 修改app名称&…...

【Redis】not support: redis

1、查看redis进程 2、查看是否安装redis扩展&#xff0c;此处以宝塔为例...

【集群划分】含分布式光伏的配电网集群电压控制【33节点】

目录 主要内容 模型研究 1.节点电压灵敏度的计算 2.Kmeans聚类划分 3.集群K值 部分代码 运行结果 下载链接 主要内容 该程序参考文献《含分布式光伏的配电网集群划分和集群电压协调控制》&#xff0c;基于社团检测算法&#xff0c;实现基于电气距离和区域电压调节能…...

嵌入式蓝桥杯学习5 定时中断实现按键

Cubemx配置 打开cubemx。 前面的配置与前文一样&#xff0c;这里主要配置基本定时器的定时功能。 1.在Timer中点击TIM6&#xff0c;勾选activated。配置Parameter Settings中的预分频器&#xff08;PSC&#xff09;和计数器&#xff08;auto-reload Register&#xff09; 补…...

【Java】类似王者荣耀游戏

r77683962/WangZheYouDianRongYao 运行效果图&#xff1a; 类似王者荣耀游戏运行效果图_哔哩哔哩_bilibili...

C++<基本>:union是没有构造函数和析构函数的

今天发现当我在union中包含了多个结构体时&#xff0c;结构体有默认构造函数时&#xff0c;编译报错。 问题点&#xff1a; union不支持构造函数和析构函数union中的元素本身也是不支持构造函数和析构函数的。包含union的结构体也不支持构造函数和析构函数。 出错代码如下&a…...

SQL中IN和NOT操作符的用法

1. IN操作符&#xff08;布尔逻辑&#xff09; 在SQL中&#xff0c;IN 是一个用于检查某个字段值是否包含在给定的多个可能值中的布尔操作符。它经常与条件表达式一起使用&#xff0c;通常出现在WHERE子句中。 用法&#xff1a; IN操作符用来确定某个字段的值是否存在于给定…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...