文件上传增删改查(CRUD)API接口示例

为了为文件上传增删改查(CRUD)API接口并带上版本号,可以按照以下方式设计URL和实现相应的功能。我们将为上传文件、获取文件列表、获取单个文件、删除文件和更新文件内容创建API端点。

API 设计

  • POST /api/v1/files/upload:上传文件
  • GET /api/v1/files:获取文件列表
  • GET /api/v1/files/{filename}:获取单个文件
  • DELETE /api/v1/files/{filename}:删除文件
  • PUT /api/v1/files/{filename}:更新文件

完整的实现

1. 创建控制器 FileController

package com.example.fileuploaddemo.controller;import com.example.fileuploaddemo.service.FileStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;@RestController
@RequestMapping("/api/v1/files")
public class FileController {@Autowiredprivate FileStorageService fileStorageService;@PostMapping("/upload")public ResponseEntity<Map<String, String>> uploadFile(@RequestParam("file") MultipartFile file) {String message;try {String fileName = fileStorageService.save(file);message = "Uploaded the file successfully: " + fileName;return ResponseEntity.status(HttpStatus.OK).body(Map.of("message", message));} catch (Exception e) {message = "Could not upload the file: " + file.getOriginalFilename() + "!";return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(Map.of("message", message));}}@GetMappingpublic ResponseEntity<List<String>> listFiles() {List<String> fileNames = fileStorageService.loadAll().map(Path::getFileName).map(Path::toString).collect(Collectors.toList());return ResponseEntity.status(HttpStatus.OK).body(fileNames);}@GetMapping("/{filename}")public ResponseEntity<Resource> getFile(@PathVariable String filename) {Resource file = fileStorageService.loadAsResource(filename);return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"").body(file);}@DeleteMapping("/{filename}")public ResponseEntity<Map<String, String>> deleteFile(@PathVariable String filename) {try {fileStorageService.delete(filename);return ResponseEntity.status(HttpStatus.OK).body(Map.of("message", "Deleted the file successfully: " + filename));} catch (Exception e) {return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(Map.of("message", "Could not delete the file: " + filename + "!"));}}@PutMapping("/{filename}")public ResponseEntity<Map<String, String>> updateFile(@PathVariable String filename, @RequestParam("file") MultipartFile file) {try {fileStorageService.update(filename, file);return ResponseEntity.status(HttpStatus.OK).body(Map.of("message", "Updated the file successfully: " + filename));} catch (Exception e) {return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(Map.of("message", "Could not update the file: " + filename + "!"));}}
}

2. 更新服务 FileStorageService

package com.example.fileuploaddemo.service;import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.nio.file.*;
import java.util.stream.Stream;@Service
public class FileStorageService {private final Path fileStorageLocation = Paths.get("uploads").toAbsolutePath().normalize();public FileStorageService() {try {Files.createDirectories(this.fileStorageLocation);} catch (Exception ex) {throw new RuntimeException("Could not create the directory where the uploaded files will be stored.", ex);}}public String save(MultipartFile file) {try {String fileName = file.getOriginalFilename();Path targetLocation = this.fileStorageLocation.resolve(fileName);Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);return fileName;} catch (IOException ex) {throw new RuntimeException("Could not store file " + file.getOriginalFilename() + ". Please try again!", ex);}}public Stream<Path> loadAll() {try {return Files.walk(this.fileStorageLocation, 1).filter(path -> !path.equals(this.fileStorageLocation)).map(this.fileStorageLocation::relativize);} catch (IOException ex) {throw new RuntimeException("Could not read the files!", ex);}}public Resource loadAsResource(String fileName) {try {Path filePath = this.fileStorageLocation.resolve(fileName).normalize();Resource resource = new UrlResource(filePath.toUri());if (resource.exists() || resource.isReadable()) {return resource;} else {throw new RuntimeException("Could not read the file: " + fileName);}} catch (MalformedURLException ex) {throw new RuntimeException("Could not read the file: " + fileName, ex);}}public void delete(String fileName) {try {Path filePath = this.fileStorageLocation.resolve(fileName).normalize();Files.deleteIfExists(filePath);} catch (IOException ex) {throw new RuntimeException("Could not delete the file: " + fileName, ex);}}public void update(String fileName, MultipartFile file) {try {Path targetLocation = this.fileStorageLocation.resolve(fileName);Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);} catch (IOException ex) {throw new RuntimeException("Could not update the file " + file.getOriginalFilename() + ". Please try again!", ex);}}
}

3. 主应用程序类

package com.example.fileuploaddemo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class FileUploadDemoApplication {public static void main(String[] args) {SpringApplication.run(FileUploadDemoApplication.class, args);}
}

4. 配置文件

src/main/resources 目录下的 application.properties 文件中添加任何需要的配置(通常不需要特别配置)。

测试

启动应用程序后,可以使用工具(如Postman)进行如下测试:

  • 上传文件:POST http://localhost:8080/api/v1/files/upload,选择文件进行上传。
  • 获取文件列表:GET http://localhost:8080/api/v1/files
  • 获取单个文件:GET http://localhost:8080/api/v1/files/{filename}
  • 删除文件:DELETE http://localhost:8080/api/v1/files/{filename}
  • 更新文件:PUT http://localhost:8080/api/v1/files/{filename},选择新的文件进行更新。

总结

通过以上步骤,我们创建了一个文件上传接口并生成了增删改查的API。这个示例展示了如何使用Spring Boot处理文件的上传、存储、读取、删除和更新。可以根据需要扩展和调整此示例,以满足实际的业务需求。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mirai Bot初始化配置

RT其实本来我的bot已经因为自己手贱登陆qq nt直接报废了,但是论坛里有佬提供了新的协议库,那这不赶紧复活bot都对不起这个新的协议库。 本文写于2024年7月4日19:20:21,可能随着时间久远而无法实现功能。由于存在下载障碍,所以这里也搞了个存档,本帖中的相关标星*资源无法下…

量化曲线的平滑程度

思路 1. 对原始数据一阶求导,得到一阶导数数组。 2. 对一阶导数数组求标准差。导数的标准差提供了导数值的波动性,标准差越小,曲线越平滑。 平滑曲线import numpy as np import matplotlib.pyplot as plt from matplotlib import font_manager fname="/usr/local/pytho…

Android常见错误

错误1 A problem occurred configuring root project ����ʶ��. > Could not resolve all files for configuration :classpath.> Could not resolve com.android.tools.build:gradle:8.4.0.Required by:project : > com.android.application:com.android.appli…

MyBatis中的Where标签:提升你的SQL查询效率

哈喽,大家好,我是木头左!理解MyBatis的Where标签 MyBatis是一款优秀的持久层框架,它提供了许多强大的标签来帮助编写更优雅、高效的SQL语句。其中,<where>标签是使用频率极高的一个,它能够自动处理查询条件,使得的SQL语句更加简洁和高效。在这篇文章中,将深入探讨…

Java中的JSON神器,如何轻松玩转复杂数据结构

哈喽,大家好,我是木头左!一、揭秘JSON世界的基石 在Java的世界中,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它基于文本,易于阅读和编写,同时也易于机器解析和生成。JSON在日常开发中的应用非常广泛,无论是前后端的数据交互,还是配置文件的读取,…

《Python 第三方模块包安装指南》

在 Python 编程中,第三方模块包极大地丰富了其功能,让我们能够更高效地完成各种任务。下面将为您详细介绍如何安装 Python 的第三方模块包。 一、使用 pip 命令安装 pip 是 Python 的包管理工具,大多数情况下,我们可以通过以下命令来安装第三方模块包:pip install 模块包名…

巴图自动化Modbus转PN网关模块连智能仪表与PLC通讯

通过巴图自动化Modbus转Profinet协议网关模块,实现PLC对仪表设备的远程监控和数据传输,提高生产效率和运行稳定性。巴图自动化Modbus转Profinet协议转换BT-MDPN100网关模块的主要功能是实现Modbus协议和Profinet协议之间的转换和通信。Modbus 转 Profinet协议网关模块集成了M…

一文搞懂到底什么是 AQS

日常开发中,我们经常使用锁或者其他同步器来控制并发,那么它们的基础框架是什么呢?如何实现的同步功能呢?本文将详细用白话讲解构建锁和同步器的基础框架--AQS,并根据源码分析其原理。前言 日常开发中,我们经常使用锁或者其他同步器来控制并发,那么它们的基础框架是什么…

flutter状态管理 provider使用

provider是flutter官方推荐的状态管理插件,是基于InheritedWidget实现的。 下面我们来讲一个provider的使用方法。 1.在pubspec.yaml文件中添加 provider: ^6.1.2 开发文档:https://pub-web.flutter-io.cn/packages/provider 可以查看使用方法和最新版本号。 添加完成后…

企业数字化转型:顶层规划方法

随着数字化时代的到来,发生了以数字化、智能化为典型特征的新一轮科技革命,各行各业利用互联网、大数据、云计算、人工智能、区块链技术对传统产业进行全方位、全链条改造,实施“上云用数赋智”行动,全面推进各行业数字化转型。数字经济的大门已然开启,数字经济顶层战略规…

Nuxt3 的生命周期和钩子函数(十)

摘要:本文详细介绍了Nuxt3框架中的五个webpack钩子函数:webpack:configResolved用于在webpack配置解析后读取和修改配置;webpack:compile在编译开始前调用,可修改编译选项;webpack:compiled在编译完成后调用,可处理编译结果;webpack:change在开发模式下文件变化时触发,…

Jenkins汉化

1、Jenkins版本:版本2.426.3) Manage Jenkins->选择Plugins->切换到Availabled plugin->搜索local,然后选中安装,如下图所示 2、安装完成后重启Jenkins,汉化完成。如下图所示 像个小学生一样努力学习