SpringBoot整合Hutool实现文件上传的使用示例

 更新时间:2023年11月13日 14:11:14   作者:晚上睡不着!  
文件上传在项目经常会用到,本文主要介绍了SpringBoot整合Hutool实现文件上传的使用示例,具有一定的参考价值,感兴趣的可以了解一下

前言

我相信我们在日常开发中,难免会遇到对各种媒体文件的操作,由于业务需求的不同对文件操作的代码实现也大不相同

数据库设计

/*
 Navicat Premium Data Transfer

 Source Server         : MySQL 5.5
 Source Server Type    : MySQL
 Source Server Version : 50554 (5.5.54)
 Source Host           : localhost:3306
 Source Schema         : tgadmin

 Target Server Type    : MySQL
 Target Server Version : 50554 (5.5.54)
 File Encoding         : 65001

 Date: 20/06/2023 03:07:47
*/

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(11) NOT NULL AUTO_INCREMENT COMMENT '文件id',
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件名',
  `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件类型',
  `size` bigint(20) NULL DEFAULT NULL COMMENT '文件大小(kb)',
  `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '访问路径',
  `location` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件地址',
  `download` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '下载地址',
  `md5` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件md5',
  `is_Delete` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除 0:未删除 1:删除',
  `enable` tinyint(1) NULL DEFAULT 1 COMMENT '是否禁用链接  1:可用  0:禁用用',
  `upload_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '上传时间',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `uni_md5`(`md5`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 64 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文件表' ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;

yaml配置我们的上传路径

# 文件上传配置
files:
  ip: localhost
  upload:
    location: file:F:/项目/SpringBoot+vue/tg-admin/server/files/
    path: /img/**

上传

maven配置

<!--        hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.15</version>
        </dependency>
<!--        MybatisPlus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>

文件类

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

import java.io.Serializable;
import java.sql.Timestamp;

/**
 * @Program: admin
 * @ClassName File
 * @Author: liutao
 * @Description: 文件
 * @Create: 2023-03-16 18:51
 * @Version 1.0
 **/

@Data
@TableName("sys_file")
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("文件表")
public class Files implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty("文件id")
    @TableId(type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty("文件名称")
    private String name;

    @ApiModelProperty("文件类型")
    private String type;

    @ApiModelProperty("文件大小")
    private Long size;

    @ApiModelProperty("文件地址")
    private String location;

    @ApiModelProperty("访问url")
    private String url;

    @ApiModelProperty("开启状态")
    private String download;

    @ApiModelProperty("是否删除")
    private Boolean isDelete;

    @ApiModelProperty("文件md5")
    private String md5;

    @ApiModelProperty("开启状态")
    private Boolean enable;

    @ApiModelProperty("上传时间")
    private Timestamp uploadTime;
}

文件接口 

import cn.hutool.core.date.DateUtil;
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.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tg.admin.common.Result;
import com.tg.admin.entity.Files;
import com.tg.admin.entity.User;
import com.tg.admin.service.FileService;
import com.tg.admin.utils.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * @Program: admin
 * @ClassName: FileController
 * @Author: liutao
 * @Description: 文件处理
 * @Create: 2023-03-16 18:15
 * @Version 1.0
 **/
@Api(tags = "文件接口")
@RestController
@RequestMapping("/file")
public class FileController {
    private static final Logger log = LoggerFactory.getLogger(FileController.class);
    @Value("${files.ip}")
    private String ip;
    @Value("${server.port}")
    private String port;
    @Value("${files.upload.path}")
    private String path;
    @Value("${files.upload.location}")
    private String fileUploadPath;

    @Autowired
    private FileService fileService;

    @ApiOperation("分页查询所有文件信息")
    @GetMapping("/page")
    public Result<Files> findPage(@RequestParam Integer pageNum,
                                  @RequestParam Integer pageSize,
                                  @RequestParam String name,
                                  @RequestParam String type) {
        IPage<Files> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_Delete", false);
        if (!"".equals(name)) {
            queryWrapper.like("name", name);
        }
        if (!"".equals(type)) {
            queryWrapper.like("type", type);
        }
        User currentUser = JwtUtil.getCurrentUser();
        log.info("当前用户------{}", currentUser);
        return Result.success(fileService.page(page, queryWrapper));
    }


    @ApiOperation("根据id删除文件")
    @DeleteMapping("/{id}")
    public Result<Files> delete(@PathVariable Integer id) {
        Files files = fileService.getById(id);
        files.setIsDelete(true);
        fileService.updateById(files);
        return Result.success();
    }


    @ApiOperation("根据id批量删除文件")
    @PostMapping("del/batch")
    public Result<Files> deleteBatch(@RequestBody List<Integer> ids) {
        QueryWrapper<Files> queryWrapper = new QueryWrapper<Files>();
        queryWrapper.in("id", ids);
        List<Files> files = fileService.list(queryWrapper);
        files.forEach(file -> {
            file.setIsDelete(true);
            fileService.updateById(file);
        });
        return Result.success();
    }

    @ApiOperation(value = "更新或新增", httpMethod = "POST")
    @PostMapping("/update")
    public Result<Files> save(@RequestBody Files files) {
        return Result.success(fileService.saveOrUpdate(files));
    }


    /**
     * @MethodName: upload
     * @description: 文件上传
     * @Author: LiuTao
     * @Param: [file]
     * @UpdateTime: 2023/3/16 18:39
     * @Return: java.lang.String
     * @Throw: IOException
     **/
    @ApiOperation("上传文件接口")
    @PostMapping("/upload")
    public Result<Files> upload(@RequestParam MultipartFile file,
                                HttpServletRequest request) throws IOException {
        // 文件原始名
        String originalFilename = file.getOriginalFilename();
        // 文件类型
        String type = FileUtil.extName(originalFilename);
        // 文件大小
        long size = file.getSize();
        String today = DateUtil.today().replace("-", "/");
        // 定义一个文件唯一的标识码
        String fileUUID = IdUtil.fastSimpleUUID() + StrUtil.DOT + type;
        // 下载地址
        String download = request.getScheme() + "://" + ip + ":" + port + "/file/" + fileUUID;
        // 重命名文件
        fileUploadPath = fileUploadPath.replace("file:", "");
        path = path.replace("**", "") + today + StrUtil.C_SLASH;
        // 判断目录是否存在。不存在就创建
        if (!FileUtil.exist(fileUploadPath + today)) {
            FileUtil.mkdir(fileUploadPath + today);
        }
        // 上传的文件
        File uploadFile = new File(fileUploadPath + today + StrUtil.C_SLASH + fileUUID);
        System.out.println(fileUploadPath);
        // 文件存入磁盘
        file.transferTo(uploadFile);
        // 获取文件md5
        String md5 = SecureUtil.md5(uploadFile);
        // 查询数据库有没有当前md5
        Files one = getFileMd5(md5);
        String url;
        if (one != null) {
            uploadFile.delete();
            return Result.waring("文件重复", one.getUrl());
        } else {
            url = request.getScheme() + "://" + ip + ":" + port + path + fileUUID;
        }
        // 存入数据库
        Files saveFile = new Files();
        saveFile.setName(originalFilename);
        saveFile.setType(type);
        saveFile.setSize(size / 1024);
        saveFile.setLocation(uploadFile.getCanonicalPath());
        saveFile.setUrl(url);
        saveFile.setDownload(download);
        saveFile.setMd5(md5);
        fileService.save(saveFile);
        return Result.success(url);
    }

    @ApiOperation("下载文件接口")
    @GetMapping("/{fileUUID}")
    public void download(@PathVariable String fileUUID,
                         HttpServletResponse response) throws IOException {
        Files one = fileService
                .lambdaQuery()
                .like(Files::getLocation, fileUUID)
                .one();
        File uploadFile = new File(one.getLocation());
        ServletOutputStream outputStream = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename =" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");
        byte[] bytes = FileUtil.readBytes(uploadFile);
        outputStream.write(bytes);
        outputStream.flush();
        outputStream.close();
    }

    private Files getFileMd5(String md5) {
        QueryWrapper<Files> wrapper = new QueryWrapper<>();
        wrapper.eq("md5", md5);
        List<Files> list = fileService.list(wrapper);
        return list.size() == 0 ? null : list.get(0);
    }
}

配置静态资源映射

    @Value("${files.upload.path}")
    private String filePath;
    @Value("${files.upload.location}")
    private String fileLocation;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //注册配置类,使用addResourceHandlers方法,将本地路径fileLocation映射到filePath路由上。
        registry.addResourceHandler(filePath).addResourceLocations(fileLocation);
        WebMvcConfigurer.super.addResourceHandlers(registry);
    }

到此这篇关于SpringBoot整合Hutool实现文件上传的使用示例的文章就介绍到这了,更多相关SpringBoot Hutool文件上传内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 剑指Offer之Java算法习题精讲数组与二叉树

    剑指Offer之Java算法习题精讲数组与二叉树

    跟着思路走,之后从简单题入手,反复去看,做过之后可能会忘记,之后再做一次,记不住就反复做,反复寻求思路和规律,慢慢积累就会发现质的变化
    2022-03-03
  • 一文带你深入了解Guava的缓存机制

    一文带你深入了解Guava的缓存机制

    缓存在现代编程中的作用非常大,它能提高应用性能,减少数据库压力,简直就是性能优化的利器,本文主要来和大家聊聊Google Guava的缓存机制,感兴趣的小伙伴可以了解下
    2023-12-12
  • 很多人竟然不知道Java线程池的创建方式有7种

    很多人竟然不知道Java线程池的创建方式有7种

    本文主要介绍了很多人竟然不知道Java线程池的创建方式有7种,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • java代码规范之不合理命名与重复代码示例详解

    java代码规范之不合理命名与重复代码示例详解

    这篇文章主要为大家介绍了java代码规范之不合理命名与重复代码示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 使用Springboot自定义转换器实现参数去空格功能

    使用Springboot自定义转换器实现参数去空格功能

    这篇文章主要介绍了使用Springboot自定义转换器实现参数去空格功能,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • java编程两种树形菜单结构的转换代码

    java编程两种树形菜单结构的转换代码

    这篇文章主要介绍了java编程两种树形菜单结构的转换代码,首先介绍了两种树形菜单结构的代码,然后展示了转换器实例代码,最后分享了相关实例及结果演示,具有一定借鉴价值,需要的朋友可以了解下。
    2017-12-12
  • SpringBoot打War包上传到阿里云的LINUX服务器的操作方法

    SpringBoot打War包上传到阿里云的LINUX服务器的操作方法

    这篇文章主要介绍了SpringBoot打War包上传到阿里云的LINUX服务器,本文通过图文并茂的形式给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • Mybatis利用OGNL表达式处理动态sql的方法教程

    Mybatis利用OGNL表达式处理动态sql的方法教程

    这篇文章主要给大家介绍了关于Mybatis利用OGNL表达式处理动态sql的方法教程的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。
    2017-06-06
  • HttpClient POST请求第三方接口问题(多参数传参)

    HttpClient POST请求第三方接口问题(多参数传参)

    这篇文章主要介绍了HttpClient POST请求第三方接口问题(多参数传参),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java 将Word转为HTML的方法

    Java 将Word转为HTML的方法

    本文介绍如何在JAVA程序中将Word文档通过Document.saveToFile()方法转换为HTML文档,导入jar的两种方法,文中给大家详细介绍,感兴趣的朋友一起看看吧
    2021-10-10

最新评论