java+js实现文件分片上传

java+js实现文件分片上传,第1张

java+vue文件分片上传
  • 备注
    • 为了方便测试引入了vue.js和axios.js
  • 数据库表
  • java代码
    • pom 依赖
    • 实体类
    • mapper
    • mapper.xml
    • service
    • controller
  • 前端代码
    • html

备注 为了方便测试引入了vue.js和axios.js 数据库表
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


	
		
		
		
		
		
	
	
		
			
			上传
		
	
	

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/739181.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存