技术栈:vue+springboot+mybatis,其中后端省略service操作

1.数据库表设计

CREATE TABLE file_content (
    id INT PRIMARY KEY AUTO_INCREMENT,
    file_name VARCHAR(255) NOT NULL,
    file_type VARCHAR(50) NOT NULL,
    file_content LONGBLOB NOT NULL,
    upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  • file_name:文件名

  • file_type:文件类型(如application/pdfapplication/zip等)

  • file_content:文件内容,使用LONGBLOB类型存储二进制数据

  • upload_time:文件上传时间

2.后端实现

2.1 创建实体类

import java.util.Date;

public class FileContent {
    private Integer id;
    private String fileName;
    private String fileType;
    private byte[] fileContent;
    private Date uploadTime;

    // Getters and Setters
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getFileType() {
        return fileType;
    }

    public void setFileType(String fileType) {
        this.fileType = fileType;
    }

    public byte[] getFileContent() {
        return fileContent;
    }

    public void setFileContent(byte[] fileContent) {
        this.fileContent = fileContent;
    }

    public Date getUploadTime() {
        return uploadTime;
    }

    public void setUploadTime(Date uploadTime) {
        this.uploadTime = uploadTime;
    }
}

2.2创建Mapper接口

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface FileContentMapper {
    @Insert("INSERT INTO file_content(file_name, file_type, file_content) VALUES(#{fileName}, #{fileType}, #{fileContent})")
    void insertFileContent(FileContent fileContent);

    @Select("SELECT * FROM file_content WHERE id = #{id}")
    FileContent getFileContentById(Integer id);
}

2.3实现文件上传和下载接口

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;

@RestController
@RequestMapping("/api/file")
public class FileController {

    @Autowired
    private FileContentMapper fileContentMapper;

    @PostMapping("/upload")
    public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {
        try {
            // 将文件内容转换为字节数组
            byte[] fileContent = file.getBytes();

            // 创建FileContent对象
            FileContent fileContentEntity = new FileContent();
            fileContentEntity.setFileName(file.getOriginalFilename());
            fileContentEntity.setFileType(file.getContentType());
            fileContentEntity.setFileContent(fileContent);
            fileContentEntity.setUploadTime(new Date());

            // 将文件内容存入数据库
            fileContentMapper.insertFileContent(fileContentEntity);

            return ResponseEntity.ok("File uploaded successfully: " + file.getOriginalFilename());
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to upload file");
        }
    }

    @GetMapping("/download/{id}")
    public ResponseEntity<ByteArrayResource> downloadFile(@PathVariable Integer id) {
        // 从数据库获取文件内容
        FileContent fileContent = fileContentMapper.getFileContentById(id);

        if (fileContent != null) {
            // 返回文件内容
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(fileContent.getFileType()))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileContent.getFileName() + "\"")
                    .body(new ByteArrayResource(fileContent.getFileContent()));
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
        }
    }
}

3.前端实现

3.1文件上传

使用vue实现文件上传

<template>
  <div>
    <input type="file" @change="handleFileUpload" />
    <button @click="uploadFile">Upload</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      file: null,
    };
  },
  methods: {
    handleFileUpload(event) {
      this.file = event.target.files[0];
    },
    async uploadFile() {
      if (!this.file) {
        alert("Please select a file first.");
        return;
      }

      const formData = new FormData();
      formData.append("file", this.file);

      try {
        const response = await this.$http.post("/api/file/upload", formData, {
          headers: {
            "Content-Type": "multipart/form-data",
          },
        });
        alert(response.data);
      } catch (error) {
        alert("Failed to upload file.");
      }
    },
  },
};
</script>

3.2文件下载

使用a标签进行文件下载

<template>
  <div>
    <a :href="downloadLink" download>Download File</a>
  </div>
</template>

<script>
export default {
  data() {
    return {
      fileId: 1, // 文件ID
    };
  },
  computed: {
    downloadLink() {
      return `/api/file/download/${this.fileId}`;
    },
  },
};
</script>

4.注意事项

  1. 性能问题:将大文件存入数据库可能会导致性能问题,建议仅对小文件使用此方法。

  2. 数据库配置:确保数据库支持BLOBLONGBLOB类型,并调整数据库的最大包大小(如MySQL的max_allowed_packet)。

  3. 文件大小限制:Spring Boot默认的文件上传大小限制是1MB,可以通过以下配置调整,properties文件或者yml文件

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

一站式 AI 云服务平台

更多推荐