一个sprinboot中的文件上传和下载的接口类

该文章展示了如何在SpringBoot应用中实现文件上传和下载功能。通过FileUploadUtil类处理文件上传,将文件存储在项目静态资源目录下,并返回URL。提供/image和/video接口供前端调用,下载文件时根据URL读取并返回文件内容,设置相应Content-Type。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个sprinboot中的文件上传和下载的接口类

1、接口

前端通过调用/image和/video方法即可获得媒体数据,
而其中url参数的传递则是通过upload返回的url来获取。

    @Resource
    FileUploadUtil fileUploadUtil;

    @Resource
    HttpServletResponse httpServletResponse;
	//上传文件接口
    @PostMapping("/upload")
    public String test(MultipartFile file) {
        String url = fileUploadUtil.upload(file);
        return url;
    }
	//下载图片接口
    @GetMapping(value = "/image", produces = MediaType.IMAGE_JPEG_VALUE)
    @ResponseBody
    public byte[] getImage(@RequestParam("url") String url) throws IOException {
        File file = new File(fileUploadUtil.getPictureUrl() + url);
        FileInputStream inputStream = new FileInputStream(file);
        byte[] bytes = new byte[inputStream.available()];
        inputStream.read(bytes, 0, inputStream.available());
        return bytes;
    }
	//下载视频接口
    @GetMapping(value = "/video")
    @ResponseBody
    public byte[] getVideos( @RequestParam("url") String url) throws IOException {
        File file = new File(fileUploadUtil.getPictureUrl() + url);
        httpServletResponse.setHeader("Content-Type", "video/MP4");
        FileInputStream inputStream = new FileInputStream(file);
        byte[] bytes = new byte[inputStream.available()];
        inputStream.read(bytes, 0, inputStream.available());
        return bytes;
    }
2、FileUploadUtil 类

将文件上传到根路径下/src/main/resources/static/位置中。


import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.UUID;
@Component
public class FileUploadUtil {

    FileUploadUtil (){
        String bootPath = System.getProperty("user.dir");
        bootPath = bootPath.replace("\\","/");
        this.pictureUrl = bootPath+"/src/main/resources/static/";

    }

    private String pictureUrl;

    public String getPictureUrl() {
        return pictureUrl;
    }

    public void setPictureUrl(String pictureUrl) {
        this.pictureUrl = pictureUrl;
    }

    public String upload(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        File saveFile = new File(pictureUrl);
        if (!saveFile.exists()) {
            //若不存在该目录,则创建目录
            saveFile.mkdir();
        }
        //拼接url,采用随机数,保证每个图片的url不同
        UUID uuid = UUID.randomUUID();
        //拼接后的url
        String url = uuid+fileName.substring(fileName.lastIndexOf("."));

        try {
            //将文件保存指定目录
            file.transferTo(new File(pictureUrl + url));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return url;
    }
}

<think>我们被要求实现一个基于Spring Boot的文件上传接口。根据引用的资料,我们需要以下步骤: 1. 配置Spring Boot项目,包括在application.properties中设置文件上传的相关配置。 2. 创建一个Controller来处理文件上传的请求。 引用[1]提到需要配置Spring Boot项目,引用[3]给出了具体的配置示例: spring.servlet.multipart.enabled=true file.upload-dir=./uploads # 指定上传文件的存储目录 同时,引用[3]也提到了需要创建Controller。 因此,我们将按照以下步骤进行: 1. 在application.properties(或application.yml)中配置上传目录启用multipart。 2. 创建一个Controller类,编写一个处理文件上传的接口。 注意:由于我们是在开发环境中,可以将上传目录设置为相对路径(如./uploads),但生产环境中需要设置为绝对路径,并确保有写入权限。 示例代码: 首先,配置文件(application.properties): spring.servlet.multipart.enabled=true spring.servlet.multipart.max-file-size=10MB # 可选,限制单个文件大小 spring.servlet.multipart.max-request-size=10MB # 可选,限制整个请求大小 # 设置上传目录,这里使用引用[3]中的配置,但注意引用[3]中写的是file.upload-dir,我们需要在代码中获取这个属性 file.upload-dir=./uploads 然后,创建一个FileUploadController: 在Controller中,我们需要: - 使用`@PostMapping`注解来映射上传请求。 - 使用`MultipartFile`来接收上传文件。 - 将文件保存到配置的目录中。 另外,为了安全,我们可以对文件名进行处理,避免覆盖路径安全问题。 参考引用[3]的示例,我们编写如下: 注意:我们需要在类中通过`@Value`注入配置的上传目录。 代码示例: ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; 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.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; @RestController public class FileUploadController { @Value("${file.upload-dir}") private String uploadDir; // 从配置文件中读取上传目录 @PostMapping("/upload") public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return ResponseEntity.badRequest().body("请选择文件上传"); } try { // 确保上传目录存在 File dir = new File(uploadDir); if (!dir.exists()) { dir.mkdirs(); } // 为了避免文件名冲突,使用UUID重命名文件 String originalFilename = file.getOriginalFilename(); String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")); String newFilename = UUID.randomUUID().toString() + fileExtension; // 构建文件路径 Path filePath = Paths.get(uploadDir, newFilename); // 保存文件 file.transferTo(filePath.toFile()); return ResponseEntity.ok("文件上传成功: " + newFilename); } catch (IOException e) { e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("文件上传失败: " + e.getMessage()); } } } ``` 上述代码中,我们使用了UUID来生成新的文件名,避免原始文件名可能带来的冲突安全问题。同时,我们创建了上传目录(如果不存在)。 但是,请注意,上述代码中获取文件扩展名的方式在原始文件名为空或没有扩展名时可能会出错。我们可以做一下改进: 改进点: - 检查原始文件名是否包含扩展名,如果没有,则不加扩展名。 - 或者,我们可以保留原始文件名,但为了避免覆盖,我们也可以使用时间戳+原始文件名(但原始文件名可能包含非法字符,所以使用UUID更安全)。 因此,我们保持使用UUID作为文件名,然后加上原始文件的扩展名(如果有的话)。如果没有扩展名,则不加。 改进后的文件名处理: ```java String originalFilename = file.getOriginalFilename(); String newFilename = UUID.randomUUID().toString(); if (originalFilename != null && originalFilename.contains(".")) { String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")); newFilename += fileExtension; } ``` 但是,注意:原始文件名可能为null,所以需要判断。 另外,我们也可以使用`StringUtils`(Spring提供的)来获取扩展名,但这里为了简单,直接使用字符串操作。 因此,调整后的代码为: ```java import org.springframework.util.StringUtils; // ... 其他导入 @RestController public class FileUploadController { @Value("${file.upload-dir}") private String uploadDir; @PostMapping("/upload") public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return ResponseEntity.badRequest().body("请选择文件上传"); } try { File dir = new File(uploadDir); if (!dir.exists()) { dir.mkdirs(); } String originalFilename = StringUtils.cleanPath(file.getOriginalFilename()); String fileExtension = ""; if (originalFilename != null && originalFilename.contains(".")) { fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")); } String newFilename = UUID.randomUUID().toString() + fileExtension; Path filePath = Paths.get(uploadDir, newFilename); file.transferTo(filePath.toFile()); return ResponseEntity.ok("文件上传成功: " + newFilename); } catch (IOException e) { e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("文件上传失败: " + e.getMessage()); } } } ``` 这里使用了`StringUtils.cleanPath(originalFilename)`来清理路径,避免路径安全问题(如包含..),但我们在保存时并没有使用原始文件名,所以这里清理主要是为了获取扩展名?其实我们只用了扩展名,所以影响不大。 另外,我们也可以考虑使用`Files.copy`来保存文件,但`transferTo`方法也是可行的。 注意:在WindowsLinux系统中,路径分隔符不同,我们使用`Paths.get`可以自动处理。 最后,我们需要确保上传目录有写入权限。 这样,一个简单的文件上传接口就完成了。 我们可以使用Postman或curl进行测试: curl -X POST -F "file=@/path/to/local/file.jpg" http://localhost:8080/upload 另外,根据引用[2][3],我们还可以提供文件下载接口,但用户目前只要求上传。 因此,我们只实现上传接口。 注意:在实际项目中,可能还需要考虑: - 文件类型检查(白名单) - 文件大小限制(已经在配置中设置,但Controller中也可以再次检查) - 存储文件信息到数据库(如文件名、存储路径、上传时间等) - 分布式存储(如果应用是集群部署,则需要考虑共享存储,如NAS、对象存储等) 但根据当前需求,我们只提供基础的上传功能。 总结步骤: 1. 配置application.properties 2. 创建FileUploadController,编写上传接口 请根据实际项目结构创建相应的类配置文件。 相关问题: 根据要求,生成相关问题: 1. 如何限制Spring Boot文件上传的类型(例如只允许图片)? 2. 在Spring Boot中如何实现文件下载功能? 3. 如何处理Spring Boot文件上传中的文件或断点续传? 4. Spring Boot文件上传时如何记录文件信息到数据库?</think>### Spring Boot 文件上传接口实现 以下是基于 Spring Boot 实现文件上传接口的完整示例代码,包含配置详细注释: #### 1. 配置文件 (`application.properties`) ```properties # 启用文件上传功能 spring.servlet.multipart.enabled=true # 设置单个文件最大大小(10MB) spring.servlet.multipart.max-file-size=10MB # 设置单次请求最大大小(10MB) spring.servlet.multipart.max-request-size=10MB # 设置文件存储目录(相对路径) file.upload-dir=./uploads ``` #### 2. 文件上传控制器 (`FileUploadController.java`) ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; 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.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.UUID; @RestController public class FileUploadController { // 从配置文件中注入上传目录 @Value("${file.upload-dir}") private String uploadDir; @PostMapping("/upload") public ResponseEntity<String> uploadFile( @RequestParam("file") MultipartFile file) { // 检查文件是否为空 if (file.isEmpty()) { return ResponseEntity.badRequest().body("请选择要上传文件"); } try { // 确保上传目录存在 Path uploadPath = Paths.get(uploadDir); if (!Files.exists(uploadPath)) { Files.createDirectories(uploadPath); } // 生成唯一文件名(防止覆盖) String originalFilename = file.getOriginalFilename(); String fileExtension = ""; if (originalFilename != null && originalFilename.contains(".")) { fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")); } String uniqueFilename = UUID.randomUUID() + fileExtension; // 保存文件到服务器 Path filePath = uploadPath.resolve(uniqueFilename); file.transferTo(filePath.toFile()); return ResponseEntity.ok("文件上传成功: " + uniqueFilename); } catch (IOException e) { e.printStackTrace(); return ResponseEntity.internalServerError().body("文件上传失败: " + e.getMessage()); } } } ``` #### 3. 启动类 (`Application.java`) ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` ### 实现说明: 1. **文件存储目录**: - 通过 `file.upload-dir` 配置上传路径(默认为项目根目录下的 `uploads` 文件夹) - 程序会自动创建目录(如果不存在) 2. **文件重命名**: - 使用 UUID 生成唯一文件名,避免文件名冲突安全风险 - 保留原始文件扩展名(如 `.jpg`, `.pdf`) 3. **安全限制**: - 配置文件大小限制(防止大文件攻击) - 空文件检查 4. **错误处理**: - 返回详细的错误响应(400/500状态码) - 捕获并处理 IO 异常 ### 测试方法: 使用 Postman 或 curl 测试接口: ```bash curl -X POST -F "file=@/path/to/yourfile.jpg" http://localhost:8080/upload ``` ### 注意事项: 1. 生产环境建议: - 使用绝对路径(如 `/var/uploads`) - 添加文件类型白名单验证 - 实现病毒扫描功能 - 添加身份验证权限控制 2. 高级优化: - 分片上传(大文件支持) - 进度条显示 - 云存储集成(如 AWS S3) - 文件元数据存储到数据库 Spring Boot 的文件上传功能通过 `MultipartFile` 接口简化了文件处理流程,配合自动配置可快速实现可靠的文件上传服务[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值