公用文件上传设计
1.问题描述
18年初跳槽来到新公司,在开发中惊奇的发现公司项目中的文件上传功能竟然存在好几个版本,他们为每个需要文件上传的业务实现了接口,仔细看了下这些上传文件代码,他们主要区别在于每个业务存储的文件类型、文件大小、是否要压缩需要限制或者是文件路径需要指定不同。这几个特性完全可以配置化解决问题(上家公司就是这么做的,配置化实现公用文件上传接口是一个正确的选择)。究其原因可能大家害怕更改之前的接口会照成bug,索性自己重写一个上传接口(反正是复制粘贴过来改下内容吧)。
那么文件上传如何通过配置化实现公用呢?下面直接进入主题
技术与接口定义
后端服务我们直接使用springboot2.X框架,文件上传相关配置信息将入数据库,这样可支持动态修改。测试用例我提供一个html页面,或者你可以直接使用postman。更详细的内容处理请看代码(实现很简单的)
api信息:
接口地址:http://127.0.0.1:8080/uploadFile
请求格式:post | multipart/form-data;
参数名 | 必填/类型 | 说明 |
---|---|---|
bizType | 是/String | 不同业务对应不同的类型,根据此类型查找文件上传的配置 |
bizId | 否/Long | 业务id,可以通过该id找到对于的业务信息 |
isShrink | 否(默认false)/boolean | 是否需要压缩代码为了简介,暂未实现支持是否压缩 |
file | 是 | 文件信息,支持多文件上传 |
返回列表 JSON: [FileInfo]
2.数据库设计
文件信息配置表 file_conf , 不同业务对应不同的配置,这里主要考虑了文件类型、文件大小、文件存储路径等
字段 | 类型 | 约束 | 说明 |
---|---|---|---|
id | int(11) | 必填 | 自增主键id |
bize_type | varchar(20) | 必填 | 业务类型,不同业务不同的类型 |
file_type_limit | varchar(200) | 非必填 | 允许上传的文件类型(mine-type标准),为空时不限制类型 |
file_size_limit | varchar(20) | 非必填 | 允许上传的文件大小(kb),为空时不限制大小 |
path | varchar(50) | 必填 | 服务器存储文件的路径 |
description | varchar(100) | 非必填 | 描述,如描述该业务类型对应的文件上传业务功能的业务表 |
resource_realm | varchar (100) | 必填 | 外部访问文件资源相对根路径 |
enabled | tinyint(4) | 必填 | 是否可用(默认1可用,0禁用),用于禁止某个业务上传文件的功能 |
creat_time | datetime | 必填 | 创建时间 |
last_update_time | datetime | 非必填 | 最近修改时间 |
文件信表 file_info ,主要作用保存文件存储的相关信息,方便某些业务需要统计上传文件或删除文件时需要
字段 | 类型 | 约束 | 说明 |
---|---|---|---|
id | int(11) | 必填 | 自增主键id |
bize_type | varchar(20) | 必填 | 业务类型 |
bize_id | int(11) | 非必填 | 业务id |
original_name | varchar (255) | 必填 | 文件原名称 |
new_name | varchar(50) | 必填(唯一) | 文件新名称(随机码 |
file_type | varchar(20) | 必填 | 文件类型 |
file_size | varchar(20) | 必填 | 文件大小(kb) |
file_path | varchar(200) | 必填 | 文件服务器存储绝对路径 |
relative_path | varchar(200) | 必填 | 文件相对路径,域名+此字段为该资源的请求地址 |
creat_time | datetime | 必填 | 创建时间 |
last_update_time | datetime | 非必填 | 最近修改时间 |
del_flag | tinyint(1) | 必填 | 逻辑删除(默认0正常,1文件已被物理删除) |
3.主要代码实现
3.1.model
对应数据库表结构建立对应实体类
/**
* 文件配置信息</p>
* table: file_conf
* @author lilee
* @version 1.0.0
* @date 2018/12/20 14:55
*/
public class FileConf {
private Long id; // 主键ID
private String bizType; // 上传服务类型
private String fileTypeLimit; // 文件类型(mine-type标准),为空不限制上传类型
private String fileSizeLimit; //(kb)文件限制大小,为空不限制上传大小(但要满足框架支持的上传文件大小)
private String path; // 服务器文件夹路径
private String description; // 描述
private String resourceRealm; // 访问资源路径
private Boolean enabled; // 是否可用(默认1可用,0禁用)
private Date createTime; // 创建时间
private Date lastUpdateTime; // 最后修改时间
// setter & getter
}
/**
* 文件信息</p>
* table: file_info
* @author lilee
* @version 1.0.0
* @date 2018/12/20 14:55
*/
public class FileInfo {
private Long id; // 主键ID
private String originalName; // 文件原名称
private String newName; // 文件新名称
private String fileType; // 文件类型(image/jpg, image/png, video/mp4, xsl,doc等)
private String fileSize; // 文件大小(kb)
private String filePath; // 文件服务器存储路径
private String relativePath; // 文件相对路径
private Long bizId; // 业务ID
private String bizType; // 上传服务类型(业务类型)
private Date createTime; // 创建时间
private Date lastUpdateTime; // 最后修改时间
private Boolean delFlag; // 数据删除标记0=正常,1=文件已物理删除
// setter & getter
3.2.dao
dao层,本实例为了简单,并未提供数据库操作相关代码,该模块需要用户根据自己项目架构自己实现
当前文件存储到/home/data下
@Repository
public class FileConfDao {
// 根据业务类型bizType获取该业务的配置信息
public FileConf selectByBizType(String bizType) {
// todo 为了简单,未正真的对数据库操作
// FileConf fileConf = dbdao.findByBizType(bizType);
FileConf fileConf = new FileConf();
fileConf.setBizType(bizType);
fileConf.setPath("/home/data");
fileConf.setResourceRealm("/res");
fileConf.setEnabled(true);
return fileConf;
}
// 存储文件的信息
public FileInfo insert(FileInfo fileInfo) {
// dbdao.insert(fileInfo)
return fileInfo;
}
}
3.3.service
该模块实现文件上传主体,主要包括对文件参数信息