スプリングブートファイルのアップロードとダウンロード

ファイルのアップロードとダウンロード

Maven の依存関係

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.4.0</version>
</dependency>

コード

ビジネスクラスのファイルコントローラー

package com.example.demo.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.entity.Files;
import com.example.demo.mapper.FilesMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

@RestController
@RequestMapping("/file")
public class FilesController {
    
    

    //获取项目路径
    private static final String demoDirectory=new File("").getAbsolutePath();

    //拼接文件存放目录
    private static final String currentDirectory=demoDirectory+"\\src\\main\\resources\\image\\";


    @Value("${server.ip:localhost}:${server.port}/${server.servlet.context-path:}")
    private String server;

    @Resource
    FilesMapper filesMapper;


    @PostMapping("/upload")
    public String saveFile(@RequestBody MultipartFile file) throws IOException {
    
    
        //文件大小(mb)
        long size = file.getSize()/1024;
        //文件名
        String name = file.getOriginalFilename();
        //根据文件名获取文件类型
        String type= FileUtil.extName(name);
        //定义一个文件唯一的表示码
        String FileUUID=IdUtil.fastSimpleUUID()+StrUtil.DOT+type;
        File uploadFile=new File(currentDirectory+FileUUID);
        //获取文件目录
        File parentFile=uploadFile.getParentFile();
        //判断文件路径是否存在
        if(!parentFile.exists()){
    
    
            parentFile.mkdirs();
        }
        String url;

        //获取文件的md5
        String md5= SecureUtil.md5(file.getInputStream());
        //从数据库查询md5是否有数据
        Files dbFiles=getFileByMd5(md5);
        if(dbFiles!=null){
    
    
            url=dbFiles.getUrl();
        }
        else {
    
    
            file.transferTo(uploadFile);
            url="http://"+server+"file/"+ FileUUID;
        }


        Files files=new Files();
        files.setName(name);
        files.setMd5(md5);
        files.setType(type);
        files.setSize(size);
        files.setUrl(url);
        filesMapper.insert(files);


        return url;
    }

    /**
     * 文件下载
     * @param FileUUID 文件名
     * @param response
     * @throws IOException
     */
    @GetMapping("/{FileUUID}")
    public void download(@PathVariable String FileUUID, HttpServletResponse response) throws IOException {
    
    
        File uploadFile=new File(currentDirectory+FileUUID);
        //设置输出流的格式
        ServletOutputStream os=response.getOutputStream();
        response.addHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(FileUUID,"TF-8"));
        response.setContentType("application/octet-stream");
        //写入流
        os.write(FileUtil.readBytes(uploadFile));
        //发送完成刷新管道
        os.flush();
        //关闭管道
        os.close();
    }

    /**
     * 获取数据库中的md5
     * @param md5
     * @return
     */
    private Files getFileByMd5(String md5) {
    
    
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5",md5);
        List<Files> files = filesMapper.selectList(queryWrapper);
        return files.size()==0? null: files.get(0);
    }
}

データベーステーブルの設計

/*
 Navicat Premium Data Transfer

 Source Server         : 我的远程服务器
 Source Server Type    : MySQL
 Source Server Version : 80032 (8.0.32-0ubuntu0.22.04.2)

 Target Server Type    : MySQL
 Target Server Version : 80032 (8.0.32-0ubuntu0.22.04.2)
 File Encoding         : 65001

 Date: 22/05/2023 10:58:03
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for sys_file
-- ----------------------------
DROP TABLE IF EXISTS `sys_file`;
CREATE TABLE `sys_file`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件名称',
  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件类型',
  `size` bigint NULL DEFAULT NULL COMMENT '文件大小(kb)',
  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '下载链接',
  `md5` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件md5',
  `is_delete` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除',
  `enable` tinyint(1) NULL DEFAULT 1 COMMENT '是否禁用链接',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 62 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;

SET FOREIGN_KEY_CHECKS = 1;

画像-20230522110057893

エンティティクラスファイル

package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@TableName("sys_file")
public class Files {
    
    
    
    @TableId(type = IdType.AUTO)
    private Integer id;
    
    @ApiModelProperty("文件名")
    private String name;
    
    @ApiModelProperty("文件类型")
    private String type;
    
    @ApiModelProperty("文件大小")
    private Long size;
    
    @ApiModelProperty("文件链接")
    private String url;
    
    @ApiModelProperty("文件的md5,用文件的输出流加密")
    private String md5;
    
    @ApiModelProperty("是否以删除文件")
    private Boolean isDelete;
    
    @ApiModelProperty("是否启用文件")
    private Boolean enable;
}

おすすめ

転載: blog.csdn.net/m0_57647880/article/details/130803114