Java后端实现文件的上传与下载

前言

在WEB应用开发过程中,文件的上传与下载功能可以说是基础必备的了,在这里就SpringBoot、Vue、Axios前后端分离的项目环境下,简单模拟一下通用的文件上传与下载需求的后端实现。

实现

所需依赖坐标

<!--MyBatis-Plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>
<!--HuTool工具类-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.0.M4</version>
</dependency>

 

上传接口

Contrroller

@PostMapping("/upload")
public Result<Boolean> save(MultipartFile file) throws IOException {
    fileService.saveFile(file);
    return Result.success("上传成功!");
}

 

Service

public interface FileService extends IService<Files> {
    void saveFile(MultipartFile file) throws IOException;
}

 

ServiceImpl

@Service
public class FileServiceImpl extends ServiceImpl<FileMapper, Files> implements FileService {

    @Autowired
    private FileMapper fileMapper;

    @Value("${files.upload.path}")
    private String fileUploadPath;

    @Value("${server.ip}")
    private String serverIp;

    @Value("${server.port}")
    private String serverPort;

    public Files getFileByMd5(String md5) {
        // 查询文件的md5是否存在
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5", md5);
        List<Files> filesList = fileMapper.selectList(queryWrapper);
        return filesList.size() == 0 ? null : filesList.get(0);
    }

    @Override
    public void saveFile(MultipartFile file) throws IOException {
        String originalFilename = "";
        String type = "";
        String originType = "";

        String url = "";
        long size = 0;
        String md5 = "";

        try {
            originalFilename = file.getOriginalFilename();  // 获取原文件名称
            type = FileUtil.extName(originalFilename);  // 获取文件类型
            size = file.getSize();  // 获取文件大小单位b
        } catch (Exception e){
            e.printStackTrace();
            throw new ServerException("获取上传文件信息失败!");
        }

        try {
            // 定义一个文件唯一的标识码
            String fileUUID = IdUtil.fastSimpleUUID() + StrUtil.DOT + originType;
            File uploadFile = new File(fileUploadPath + fileUUID);
            // 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
            File parentFile = uploadFile.getParentFile();
            if(!parentFile.exists()) {
                parentFile.mkdirs();
            }
            // 获取上传原文件的md5
            md5 = SecureUtil.md5(file.getInputStream());
            // 从数据库查询是否存在相同的记录
            Files dbFiles = getFileByMd5(md5);
            if (dbFiles != null) {
                url = dbFiles.getUrl();
            } else {
                // 上传文件到磁盘
                file.transferTo(uploadFile);
                // 数据库若不存在重复文件,则不删除刚才上传的文件
                url = "http://" + serverIp + ":" + serverPort + "/files/" + fileUUID;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServerException("文件持久化到服务器失败!" );
        }
        // 存储数据库
        try {
            Files saveFile = new Files();
            saveFile.setFileName(originalFilename);
            saveFile.setType(type);
            saveFile.setSize(size/1024); // 单位 kb
            saveFile.setUrl(url);
            saveFile.setMd5(md5);
            saveFile.setCreateTime(new Date());
            ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
            saveFile.setUserId(activeUser.getUser().getId());
            saveFile.setDownloadCount(0L);
            fileMapper.insert(saveFile);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServerException("保存文件到数据库失败!");
        }
    }
}

 

下载接口

Controller

@GetMapping("/download/{fileUUID}")
public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
    // 根据文件的唯一标识码获取文件
    File uploadFile = new File(fileUploadPath + fileUUID);
    // 设置输出流的格式
    ServletOutputStream os = response.getOutputStream();
    response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
    response.setContentType("application/octet-stream");
    // 读取文件的字节流
    os.write(FileUtil.readBytes(uploadFile));
    os.flush();
    os.close();
}

 

微信关注

编程那点事儿

本站为非盈利性站点,所有资源、文章等仅供学习参考,并不贩卖软件且不存在任何商业目的及用途,如果您访问和下载某文件,表示您同意只将此文件用于参考、学习而非其他用途。
本站所发布的一切软件资源、文章内容、页面内容可能整理来自于互联网,在此郑重声明本站仅限用于学习和研究目的;并告知用户不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
如果本站相关内容有侵犯到您的合法权益,请仔细阅读本站公布的投诉指引页相关内容联系我,依法依规进行处理!
作者:理想
链接:https://www.imyjs.cn/archives/830
THE END
二维码
Java后端实现文件的上传与下载
前言 在WEB应用开发过程中,文件的上传与下载功能可……
<<上一篇
下一篇>>
文章目录
关闭
目 录