当前位置: 首页 > 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操作符用来确定某个字段的值是否存在于给定…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...