- 备注
- 为了方便测试引入了vue.js和axios.js
- 数据库表
- java代码
- pom 依赖
- 实体类
- mapper
- mapper.xml
- service
- controller
- 前端代码
- html
CREATE TABLE `file_entity` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`file_name` varchar(64) DEFAULT NULL COMMENT '文件名称',
`file_url` varchar(255) DEFAULT NULL COMMENT '文件路径',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`type` int(11) DEFAULT NULL COMMENT '文件类型',
`del` bit(1) DEFAULT b'0' COMMENT '状态',
`shard_index` bigint(20) DEFAULT NULL COMMENT '已上传分片',
`shard_total` bigint(20) DEFAULT NULL COMMENT '分片总数',
`file_key` varchar(255) DEFAULT NULL COMMENT '文件标识',
`suffix` varchar(64) DEFAULT NULL COMMENT '文件名后缀',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
java代码
pom 依赖
mysql
mysql-connector-java
5.1.35
tk.mybatis
mapper-spring-boot-starter
2.1.2
com.alibaba
fastjson
1.2.78
实体类
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;
import java.util.Date;
/**
* @author zhaohanqing
* @createTime 2022-04-18 14:26
* @description
*/
@Data
public class FileEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "JDBC")
private Long id;
private String fileName;
/**
* 文件路径
*/
private String fileUrl;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime = new Date();
/**
* 修改时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime = new Date();
/**
* 文件类型 1 图片,2 视频
*/
private Integer type;
/**
* 状态0:正常, 1:禁用
*/
@JsonIgnore
private Boolean del = false;
/**
* 已上传分片
*/
private Long shardIndex;
/**
* 分片总数
*/
private Long shardTotal;
/**
* 文件标识
*/
@JsonIgnore
private String fileKey;
/**
* 文件名后缀
*/
@JsonIgnore
private String suffix;
}
mapper
import com.store.entity.FileEntity;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
/**
* @author zhaohanqing
* @createTime 2022-04-18 17:23
* @description
*/
public interface FileEntityMapper extends Mapper {
/**
* 根据fileKey修改上传下标
* @author zhaohanqing
* @createTime 2022/4/19 15:46
* @param fileEntity
* @return
*/
void updateShardIndexByFileKey(FileEntity fileEntity);
/**
* 查询所有fileKey
* @author zhaohanqing
* @createTime 2022/4/19 15:49
* @param
* @return
*/
@Select("SELECT file_key from file_entity where del = 0")
List selectFileKey();
/**
* 根据fileKey查询数据
* @author zhaohanqing
* @createTime 2022/4/19 15:41
* @param fileKey
* @return
*/
@Select("SELECT COUNT(*) FROM file_entity WHERE del = 0 AND file_key = #{fileKey}")
int selectByFileKey(@Param("fileKey") String fileKey);
}
mapper.xml
update file_entity
set shard_index = #{shardIndex},
update_time = #{updateTime}
where file_key = #{fileKey}
service
import com.store.entity.FileEntity;
import com.store.enums.FileTypeEnum;
import com.store.enums.HttpCodeEnum;
import com.store.mapper.FileEntityMapper;
import com.store.service.IFileEntityService;
import com.store.utils.ResultUtil;
import com.store.utils.UUIDUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author zhaohanqing
* @createTime 2022-04-18 14:31
* @description
*/
@Service
public class FileEntityServiceImpl {
private final Logger logger = LoggerFactory.getLogger(FileEntityServiceImpl.class);
@Value("${file.local.path}")
public String fileLocalPath;
@Resource
private FileEntityMapper fileEntityMapper;
/**
*
* @author zhaohanqing
* @createTime 2022/4/19 13:58
* @param fileEntity
* @param uploadFile
* @return
*/
public ResultUtil addFileEntity(FileEntity fileEntity, MultipartFile uploadFile) throws Exception {
if (uploadFile == null && null == fileEntity.getFileKey() && null == fileEntity.getShardIndex() && null == fileEntity.getSuffix()) {
ResultUtil.error(HttpCodeEnum.ILLEGAL_PARAMS);
}
String path = FileTypeEnum.keyOf(fileEntity.getType());
String localFileName = fileEntity.getFileKey() + "." + fileEntity.getShardIndex();
File file = new File(this.fileLocalPath + "/" + path);
if(!file.exists()){
file.mkdirs();
}
File targetFile = new File(this.fileLocalPath + "/" + path + "/", localFileName);
uploadFile.transferTo(targetFile);
fileEntity.setFileUrl(path + "/" + fileEntity.getFileKey() + "." + fileEntity.getSuffix());
/*
* 将数据持久化到数据库
*/
save(fileEntity);
/*
* 最后一片的时候合并分片
*/
if (fileEntity.getShardIndex().equals(fileEntity.getShardTotal())) {
mergeFileEntity(fileEntity);
}
return ResultUtil.success(HttpCodeEnum.OK);
}
/**
* 将数据写入数据库
* @author zhaohanqing
* @createTime 2022/4/19 15:24
* @param fileEntity
* @return
*/
private void save(FileEntity fileEntity) {
int byFileKey = this.fileEntityMapper.selectByFileKey(fileEntity.getFileKey());
fileEntity.setUpdateTime(new Date());
if (byFileKey == 0) {
fileEntity.setCreateTime(new Date());
this.fileEntityMapper.insert(fileEntity);
return;
}
this.fileEntityMapper.updateShardIndexByFileKey(fileEntity);
}
/**
* 合并分片
* @author zhaohanqing
* @createTime 2022/4/19 15:35
* @param fileEntity
* @return
*/
private void mergeFileEntity(FileEntity fileEntity) throws Exception {
String fileName = fileEntity.getFileKey();
Long shardTotal = fileEntity.getShardTotal();
String path = FileTypeEnum.keyOf(fileEntity.getType());
File newFile = new File(this.fileLocalPath + "/"+path+"/" + fileName + "." + fileEntity.getSuffix());
FileOutputStream outputStream = new FileOutputStream(newFile, true);
FileInputStream fileInputStream = null;
byte[] byt = new byte[10485760];
try {
for (int i = 0; i < shardTotal.longValue(); i++) {
fileInputStream = new FileInputStream(new File(this.fileLocalPath + "/"+path+"/" + fileName + "." + (i + 1)));
int len;
while ((len = fileInputStream.read(byt)) != -1) {
outputStream.write(byt, 0, len);
}
}
} catch (IOException e) {
logger.error("", e);
} finally {
try {
if (fileInputStream != null) {
fileInputStream.close();
}
outputStream.close();
logger.info("close");
} catch (Exception e) {
logger.error("Exception", e);
}
}
System.gc();
Thread.sleep(100L);
for (int i = 0; i < shardTotal; i++) {
String filePath = this.fileLocalPath + "/"+path+"/" + fileName + "." + (i + 1);
File file = new File(filePath);
boolean result = file.delete();
}
}
controller
import com.store.entity.FileEntity;
import com.store.enums.HttpCodeEnum;
import com.store.service.FileEntityServiceImpl;
import com.store.utils.ResultUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
/**
* @author zhaohanqing
* @createTime 2022-04-18 14:24
* @description 文件管理
*/
@RestController
@RequestMapping("/fileEntity")
public class FileEntityController extends BaseController {
@Resource
private FileEntityServiceImpl fileEntityService;
/**
* 文件分片上传
* @author zhaohanqing
* @createTime 2022/4/18 14:33
* @param fileEntity
* @param uploadFile
* @return
*/
@PostMapping("addFileEntity")
public ResultUtil addFileEntity(FileEntity fileEntity, MultipartFile uploadFile) throws Exception {
if (null == fileEntity || fileEntity.getType() == null) {
return ResultUtil.error(HttpCodeEnum.ILLEGAL_PARAMS);
}
return fileEntityService.addFileEntity(fileEntity, uploadFile);
}
}
前端代码
html
上传
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)