Minio+Vue+Springboot:网页文件上传-对象文件存储实战

一、场景分析

技术架构

  1. 前端:Vue + Axios
  2. 后端:Spring Boot
  3. 存储:MinIO对象存储

实现步骤

1. Spring Boot配置

在application.yml中添加MinIO配置:

yaml 复制代码
minio:
  url: http://localhost:9000
  access-key: your-access-key
  secret-key: your-secret-key
  bucket-name: mybucket
  secure: false

2. 文件上传实现

前端核心代码:

html 复制代码
<template>
  <div>
    <input type="file" @change="handleFileUpload">
    <button @click="uploadFile">上传</button>
    <div v-if="progress > 0">进度:{{progress}}%</div>
  </div>
</template>

3. 后端处理逻辑

使用MinIO Java Client实现文件存储:

  • 自动创建存储桶
  • 支持多种文件类型
  • 返回可访问URL

最佳实践

  1. 文件命名使用UUID避免重复
  2. 限制上传文件大小
  3. 前端添加文件类型校验
  4. 后端配置CORS策略

二、前端代码(Vue实现)

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>文件上传</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">
        <div>
            <input type="file" ref="fileInput" @change="onFileSelect">
            <button @click="upload">上传文件</button>
            <div v-if="uploadProgress > 0">
                上传进度:{{ uploadProgress }}%
            </div>
            <div v-if="fileUrl">
                文件地址:<a :href="fileUrl" target="_blank">{{ fileUrl }}</a>
            </div>
        </div>
    </div>

    <script>
        const { createApp } = Vue;
        
        createApp({
            data() {
                return {
                    selectedFile: null,
                    uploadProgress: 0,
                    fileUrl: ''
                };
            },
            methods: {
                onFileSelect(event) {
                    this.selectedFile = event.target.files[0];
                },
                async upload() {
                    if (!this.selectedFile) return;
                    
                    const formData = new FormData();
                    formData.append('file', this.selectedFile);
                    
                    try {
                        const response = await axios.post('/api/upload', formData, {
                            headers: { 'Content-Type': 'multipart/form-data' },
                            onUploadProgress: (progressEvent) => {
                                this.uploadProgress = Math.round(
                                    (progressEvent.loaded * 100) / progressEvent.total
                                );
                            }
                        });
                        
                        this.fileUrl = response.data.url;
                        alert('上传成功!');
                    } catch (error) {
                        console.error('上传失败:', error);
                        alert('上传失败!');
                    }
                }
            }
        }).mount('#app');
    </script>
</body>
</html>

三、Spring Boot配置

application.yml配置示例:

yaml 复制代码
server:
  port: 8080

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

minio:
  url: http://localhost:9000
  access-key: minioadmin
  secret-key: minioadmin
  bucket-name: mybucket
  secure: false

四、后端Java代码

FileStorageController.java:

java 复制代码
@RestController
@RequestMapping("/api")
public class FileStorageController {

    @Autowired
    private FileStorageService fileStorageService;

    @PostMapping("/upload")
    public ResponseEntity<Map<String, String>> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            String url = fileStorageService.uploadFile(file);
            return ResponseEntity.ok().body(Collections.singletonMap("url", url));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(Collections.singletonMap("error", e.getMessage()));
        }
    }
}

FileStorageService.java:

java 复制代码
@Service
public class FileStorageService {

    @Value("${minio.url}")
    private String minioUrl;
    
    @Value("${minio.access-key}")
    private String accessKey;
    
    @Value("${minio.secret-key}")
    private String secretKey;
    
    @Value("${minio.bucket-name}")
    private String bucketName;

    private MinioClient minioClient;

    @PostConstruct
    public void init() throws Exception {
        minioClient = MinioClient.builder()
                .endpoint(minioUrl)
                .credentials(accessKey, secretKey)
                .build();
                
        createBucketIfNotExists();
    }

    private void createBucketIfNotExists() throws Exception {
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder()
                .bucket(bucketName)
                .build());
        if (!found) {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        }
    }

    public String uploadFile(MultipartFile file) throws Exception {
        String fileName = UUID.randomUUID() + "-" + file.getOriginalFilename();
        
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(bucketName)
                .object(fileName)
                .stream(file.getInputStream(), file.getSize(), -1)
                .contentType(file.getContentType())
                .build());
                
        return minioUrl + "/" + bucketName + "/" + fileName;
    }
}

五、系统要求

  1. 添加MinIO Java客户端依赖(pom.xml):
xml 复制代码
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.5.6</version>
</dependency>
  1. 启动MinIO服务:
bash 复制代码
minio server /data --console-address ":9001"

该方案实现了:

  1. 前端文件上传进度显示
  2. 自动生成唯一文件名
  3. 支持多种文件类型
  4. 返回可直接访问的URL
  5. 完善的异常处理机制

建议根据实际需求添加:

  1. 文件类型白名单校验
  2. 文件大小限制
  3. 用户身份验证
  4. 文件管理功能(删除、列表等)
相关推荐
坚定信念,勇往无前1 小时前
springboot单机支持1w并发,需要做哪些优化
java·spring boot·后端
后端小肥肠1 小时前
【AI编程】Java程序员如何用Cursor 3小时搞定CAS单点登录前端集成
前端·后端·cursor
老友@1 小时前
OnlyOffice:前端编辑器与后端API实现高效办公
前端·后端·websocket·编辑器·onlyoffice
风月歌3 小时前
基于springboot校园健康系统的设计与实现(源码+文档)
java·spring boot·后端·mysql·毕业设计·mybatis·源码
m0_748239473 小时前
Spring Boot框架知识总结(超详细)
java·spring boot·后端
m0_748236113 小时前
Spring Boot 实战:轻松实现文件上传与下载功能
linux·spring boot·后端
m0_748245923 小时前
Spring Boot(七):Swagger 接口文档
java·spring boot·后端
青灯文案14 小时前
如何在 SpringBoot 项目使用 Redis 的 Pipeline 功能
spring boot·redis·后端
m0_748249545 小时前
SpringBoot教程(三十二) SpringBoot集成Skywalking链路跟踪
spring boot·后端·skywalking
小咕聊编程5 小时前
【含文档+PPT+源码】基于Django的新闻推荐系统的设计与实现
后端·python·django