SpringBoot实现文件上传(详细步骤+图解)

文件上传相信大家都不陌生,无论是学习还是工作当中都是必学也是必会的。

下面给大家安排一套SpringBoot实现文件上传的demo,从数据库到测试,非常的完善详细。

废话不多说,直接上步骤。

  • 先上数据库脚本(注:MySQL)
CREATE TABLE `file`  (
  `id` bigint(225) NOT NULL AUTO_INCREMENT COMMENT '文件ID',
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件名',
  `suffix` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件类型',
  `path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件相对路径',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1942 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文件表' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
  • 在项目的yml文件中配置好上传路径和读取路径(上传服务器改下路径打包就可以了)
file:
  #上传路径
  path: d:/file/
access:
  base-url:
  	#访问路径
    file: d:/file/
  • 封装实体类
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class File implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 文件ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 文件名
     */
    private String name;

    /**
     * 文件类型
     */
    private String suffix;

    /**
     * 文件相对路径
     */
    private String path;

    /**
     * 文件原名字
     */
    @TableField(exist = false)
    private String oldName;
}
  • 创建文件返回视图类
@Data
@ApiModel("文件")
public class FileVO {
    @ApiModelProperty(value = "文件ID")
    private Long id;
    @ApiModelProperty(value = "源文件名")
    private String oldName;
    @ApiModelProperty(value = "现文件名")
    private String name;
    @ApiModelProperty(value = "文件类型")
    private String suffix;
    @ApiModelProperty(value = "访问地址")
    private String url;
}
  • 编写文件上传Controller类
@Slf4j
@RestController
@Api(tags = "文件上传接口")
@RequestMapping("/file")
public class FileController {

    @Resource
    private FileService fileService;

    @ApiOperation("根据id查询单个")
    @GetMapping("/getById")
    public R getById(Integer id) {
        return R.ok(fileService.getVOById(id));
    }

    @ApiOperation("文件单个上传")
    @PostMapping("/uploadByOne")
    public R uploadByOne(@RequestParam("file") MultipartFile file) {
        try (InputStream is = file.getInputStream();
             ByteArrayOutputStream os = new ByteArrayOutputStream()) {
            IOUtils.copy(is, os);
            byte[] bytes = os.toByteArray();
            FileVO vo = fileService.storeFile(bytes, file.getOriginalFilename());
            return R.ok(vo);
        } catch (IOException e) {
            log.error("文件上传发生异常 -> {}", e.getMessage());
            return R.failed("文件上传失败");
        }
    }

}
  • 编写Service接口
public interface FileService extends IService<File> {

    /**
     * 根据ID获取视图对象
     * @param id
     * @return
     */
    FileVO getVOById(Integer id);

    /**
     * 文件上传
     * @param content
     * @param originFileName
     * @return
     */
    FileVO storeFile(byte[] content, String originFileName);

    /**
     * 存储文件到本地
     * @param content
     * @param path
     * @param fileName
     */
    void storeFileWithFileName(byte[] content, String path, String fileName);
}
  • 编写Service接口实现类
@Service
public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements FileService {

    @Value("${file.path}")
    private String FILE_PATH;
    @Value("${access.base-url.file}")
    private String ACCESS_BASE_URL;

    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");

    @Override
    public FileVO getVOById(Integer id) {
        if (id != null) {
            File file = this.getById(id);
            if (file != null) {
                FileVO result = BeanUtil.toBean(file, FileVO.class);
                result.setUrl(genAccessUrl(file.getPath(), file.getName()));

                return result;
            }
        }
        return null;
    }

    @Override
    public FileVO storeFile(byte[] content, String originFileName) {
        // 获取文件后缀 生成目录路径
        // 配置文件里的file.path + yyyyMMdd 格式组成文件夹路径
        String folder = LocalDateTime.now().format(dateTimeFormatter);
        String suffix = originFileName.substring(originFileName.lastIndexOf(".")),
                filePath = FILE_PATH + folder + java.io.File.separatorChar;
        // 保存文件并返回文件名
        String fileName = this.storeFile(content, filePath, suffix);

        // 入库
        File file = new File();
        file.setName(fileName);
        file.setSuffix(suffix);
        file.setPath(folder);
        file.setOldName(originFileName);
        baseMapper.insert(file);
        FileVO result = BeanUtil.toBean(file, FileVO.class);
        result.setUrl(genAccessUrl(folder, fileName));
        result.setId(file.getId());
        return result;
    }

    @Override
    public void storeFileWithFileName(byte[] content, String path, String fileName) {
        // 目录不存在则创建
        java.io.File file = new java.io.File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        try (FileOutputStream os = new FileOutputStream(path + fileName);
             ByteArrayInputStream is = new ByteArrayInputStream(content)) {
            IOUtils.copy(is, os);
        } catch (IOException e) {
            log.error("存储文件到本地时发生异常:{}", e);
        }
    }

    private String storeFile(byte[] content, String path, String suffix) {
        String fileName = generateFileName(suffix);
        storeFileWithFileName(content, path, fileName);
        return fileName;
    }

    private String generateFileName(String suffix) {
        return generateFileName() + suffix;
    }

    private String genAccessUrl(String folder, String name) {
        return ACCESS_BASE_URL + folder + "/" + name;
    }

    private String generateFileName() {
        return System.currentTimeMillis() + "_" + RandomUtil.randomNumbers(6);
    }
}
  • 使用Swagger进行测试

上传文件
在这里插入图片描述
查询文件
在这里插入图片描述

注:此demo使用了Lombok插件,在线接口文档Swagger,持久层框架MyBatis-Plus,详情见下列文章:

个人总结在平时工作用的比较多的一些Lombok注解(详解)
SpringBoot集成Swagger3–在线API文档(详细步骤+图解)
SpringBoot集成MyBatis-Plus以及MyBatis-Plus代码生成工具类(详细步骤+图解)

有什么疑问可评论区提问!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐