新增文件MD5校验,去除重复文件
This commit is contained in:
parent
966141e943
commit
cb98c405f4
@ -32,6 +32,7 @@ public interface IFileDao {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除文件
|
* 删除文件
|
||||||
|
*
|
||||||
* @param params
|
* @param params
|
||||||
* @throws RemoveException
|
* @throws RemoveException
|
||||||
*/
|
*/
|
||||||
@ -39,6 +40,7 @@ public interface IFileDao {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除文件(物理删除)
|
* 删除文件(物理删除)
|
||||||
|
*
|
||||||
* @param params
|
* @param params
|
||||||
* @throws RemoveException
|
* @throws RemoveException
|
||||||
*/
|
*/
|
||||||
@ -73,9 +75,18 @@ public interface IFileDao {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件列表(带路径)
|
* 获取文件列表(带路径)
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws SearchException
|
* @throws SearchException
|
||||||
*/
|
*/
|
||||||
List<FileInfoWithPathDTO> listFileInfoWithPath(Map<String, Object> params) throws SearchException;
|
List<FileInfoWithPathDTO> listFileInfoWithPath(Map<String, Object> params) throws SearchException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件列表
|
||||||
|
*
|
||||||
|
* @param fileMd5 文件MD5值
|
||||||
|
* @return
|
||||||
|
* @throws SearchException
|
||||||
|
*/
|
||||||
|
List<FileInfoDTO> listFileByMd5(String fileMd5) throws SearchException;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ import io.swagger.annotations.ApiModelProperty;
|
|||||||
@ApiModel
|
@ApiModel
|
||||||
public class FileInfoDTO extends FileDTO {
|
public class FileInfoDTO extends FileDTO {
|
||||||
|
|
||||||
|
@ApiModelProperty(name = "filePath", value = "文件全路径")
|
||||||
|
private String filePath;
|
||||||
@ApiModelProperty(name = "fileUrl", value = "文件链接")
|
@ApiModelProperty(name = "fileUrl", value = "文件链接")
|
||||||
private String fileUrl;
|
private String fileUrl;
|
||||||
@ApiModelProperty(name = "fileSummary", value = "文件说明")
|
@ApiModelProperty(name = "fileSummary", value = "文件说明")
|
||||||
@ -24,6 +26,14 @@ public class FileInfoDTO extends FileDTO {
|
|||||||
@ApiModelProperty(name = "isBack", value = "是否备份")
|
@ApiModelProperty(name = "isBack", value = "是否备份")
|
||||||
private Integer isBack;
|
private Integer isBack;
|
||||||
|
|
||||||
|
public String getFilePath() {
|
||||||
|
return filePath == null ? "" : filePath.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilePath(String filePath) {
|
||||||
|
this.filePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFileUrl() {
|
public String getFileUrl() {
|
||||||
return fileUrl == null ? "" : fileUrl.trim();
|
return fileUrl == null ? "" : fileUrl.trim();
|
||||||
@ -53,7 +63,9 @@ public class FileInfoDTO extends FileDTO {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder sb = new StringBuilder("{");
|
final StringBuilder sb = new StringBuilder("{");
|
||||||
sb.append("\"fileUrl\":\"")
|
sb.append("\"filePath\":\"")
|
||||||
|
.append(filePath).append('\"');
|
||||||
|
sb.append(",\"fileUrl\":\"")
|
||||||
.append(fileUrl).append('\"');
|
.append(fileUrl).append('\"');
|
||||||
sb.append(",\"fileSummary\":\"")
|
sb.append(",\"fileSummary\":\"")
|
||||||
.append(fileSummary).append('\"');
|
.append(fileSummary).append('\"');
|
||||||
|
@ -42,6 +42,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
import java.security.MessageDigest;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,6 +56,7 @@ import java.util.*;
|
|||||||
public class FileServiceImpl extends AbstractService implements IFileService {
|
public class FileServiceImpl extends AbstractService implements IFileService {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(FileServiceImpl.class);
|
private static final Logger LOG = LoggerFactory.getLogger(FileServiceImpl.class);
|
||||||
|
private static final char[] HEX_CODE = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private FileProperties fileProperties;
|
private FileProperties fileProperties;
|
||||||
@ -153,9 +155,26 @@ public class FileServiceImpl extends AbstractService implements IFileService {
|
|||||||
String uploadPath = getUploadPath(baseUploadPath, uploadTypeEnum, fileType);
|
String uploadPath = getUploadPath(baseUploadPath, uploadTypeEnum, fileType);
|
||||||
// 文件保存名称
|
// 文件保存名称
|
||||||
String uploadFileName = getUploadFileName(fileType);
|
String uploadFileName = getUploadFileName(fileType);
|
||||||
if (!uploadFile(uploadFile, uploadPath, uploadFileName)) {
|
String fileMd5 = uploadFile(uploadFile, uploadPath, uploadFileName);
|
||||||
|
if (fileMd5 == null) {
|
||||||
throw new SaveException("文件上传失败");
|
throw new SaveException("文件上传失败");
|
||||||
}
|
}
|
||||||
|
// 获取MD5相同的文件
|
||||||
|
List<FileInfoDTO> fileInfoDTOs = fileDao.listFileByMd5("MD5:" + fileMd5);
|
||||||
|
if (fileInfoDTOs.size() > 0) {
|
||||||
|
// 删除新增的文件
|
||||||
|
File uploadedFile = new File(uploadPath + File.separator + uploadFileName);
|
||||||
|
if (uploadedFile.exists()) {
|
||||||
|
uploadedFile.delete();
|
||||||
|
}
|
||||||
|
// 保存记录,但文件信息都是原有的文件
|
||||||
|
params.clear();
|
||||||
|
FileInfoDTO fileInfoDTO = fileInfoDTOs.get(0);
|
||||||
|
params.put("fileSummary", "REF:" + fileInfoDTO.getFileId());
|
||||||
|
saveFile(token, params, fileInfoDTO.getFileName(), fileInfoDTO.getFilePath(), fileInfoDTO.getFileUrl(), fileInfoDTO.getFileType(), fileInfoDTO.getFileSize());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
params.put("fileSummary", "MD5:" + fileMd5);
|
||||||
saveUploadFileInfo(token, fileName, uploadPath, uploadFileName, fileType, fileSize, params);
|
saveUploadFileInfo(token, fileName, uploadPath, uploadFileName, fileType, fileSize, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,10 +224,25 @@ public class FileServiceImpl extends AbstractService implements IFileService {
|
|||||||
File photo = new File(fileFullPath);
|
File photo = new File(fileFullPath);
|
||||||
fileSize = photo.length();
|
fileSize = photo.length();
|
||||||
}
|
}
|
||||||
|
saveFile(token, params, fileName, fileFullPath, String.format("files/%s/%s", fixPath, uploadFileName), fileType, fileSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存文件
|
||||||
|
*
|
||||||
|
* @param token token
|
||||||
|
* @param params 参数
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @param fileFullPath 文件全路径
|
||||||
|
* @param fileUrl 文件相对地址
|
||||||
|
* @param fileType 文件类型
|
||||||
|
* @param fileSize 文件大小
|
||||||
|
*/
|
||||||
|
private void saveFile(String token, Map<String, Object> params, String fileName, String fileFullPath, String fileUrl, String fileType, long fileSize) {
|
||||||
params.put("fileId", UUIDUtil.getUUID());
|
params.put("fileId", UUIDUtil.getUUID());
|
||||||
params.put("fileName", fileName);
|
params.put("fileName", fileName);
|
||||||
params.put("filePath", fileFullPath);
|
params.put("filePath", fileFullPath);
|
||||||
params.put("fileUrl", String.format("files/%s/%s", fixPath, uploadFileName));
|
params.put("fileUrl", fileUrl);
|
||||||
params.put("fileType", fileType);
|
params.put("fileType", fileType);
|
||||||
params.put("fileSize", fileSize);
|
params.put("fileSize", fileSize);
|
||||||
params.put("isBack", 0);
|
params.put("isBack", 0);
|
||||||
@ -596,7 +630,8 @@ public class FileServiceImpl extends AbstractService implements IFileService {
|
|||||||
* @param uploadFileName
|
* @param uploadFileName
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private boolean uploadFile(MultipartFile uploadFile, String filePath, String uploadFileName) throws FileException {
|
private String uploadFile(MultipartFile uploadFile, String filePath, String uploadFileName) throws FileException {
|
||||||
|
String fileMd5;
|
||||||
File uploadFolder = new File(filePath);
|
File uploadFolder = new File(filePath);
|
||||||
if (!uploadFolder.exists()) {
|
if (!uploadFolder.exists()) {
|
||||||
uploadFolder.mkdirs();
|
uploadFolder.mkdirs();
|
||||||
@ -606,10 +641,20 @@ public class FileServiceImpl extends AbstractService implements IFileService {
|
|||||||
try {
|
try {
|
||||||
uploadFileInputStream = uploadFile.getInputStream();
|
uploadFileInputStream = uploadFile.getInputStream();
|
||||||
uploadFileOutputStream = new FileOutputStream(new File(uploadFolder + "/" + uploadFileName));
|
uploadFileOutputStream = new FileOutputStream(new File(uploadFolder + "/" + uploadFileName));
|
||||||
|
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
|
||||||
for (byte[] buf = new byte[INPUT_STREAM_SIZE]; uploadFileInputStream.read(buf) > -1; ) {
|
for (byte[] buf = new byte[INPUT_STREAM_SIZE]; uploadFileInputStream.read(buf) > -1; ) {
|
||||||
uploadFileOutputStream.write(buf, 0, buf.length);
|
uploadFileOutputStream.write(buf, 0, buf.length);
|
||||||
|
messageDigest.update(buf, 0, buf.length);
|
||||||
}
|
}
|
||||||
uploadFileOutputStream.flush();
|
uploadFileOutputStream.flush();
|
||||||
|
// 计算文件的MD5
|
||||||
|
byte[] data = messageDigest.digest();
|
||||||
|
StringBuilder fileMd5SB = new StringBuilder(data.length * 2);
|
||||||
|
for (byte b : data) {
|
||||||
|
fileMd5SB.append(HEX_CODE[(b >> 4) & 0xF]);
|
||||||
|
fileMd5SB.append(HEX_CODE[(b & 0xF)]);
|
||||||
|
}
|
||||||
|
fileMd5 = fileMd5SB.toString();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error(e.getMessage(), e);
|
LOG.error(e.getMessage(), e);
|
||||||
throw new FileException("文件上传失败");
|
throw new FileException("文件上传失败");
|
||||||
@ -626,7 +671,7 @@ public class FileServiceImpl extends AbstractService implements IFileService {
|
|||||||
throw new FileException("文件上传失败");
|
throw new FileException("文件上传失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return fileMd5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<result property="fileUrl" column="file_url"/>
|
<result property="fileUrl" column="file_url"/>
|
||||||
<result property="fileType" column="file_type"/>
|
<result property="fileType" column="file_type"/>
|
||||||
<result property="fileSize" column="file_size"/>
|
<result property="fileSize" column="file_size"/>
|
||||||
<result property="fileUrl" column="file_url"/>
|
<result property="filePath" column="file_path"/>
|
||||||
<result property="fileSummary" column="file_summary"/>
|
<result property="fileSummary" column="file_summary"/>
|
||||||
<result property="isBack" column="is_back"/>
|
<result property="isBack" column="is_back"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
@ -111,7 +111,19 @@
|
|||||||
<!-- 获取文件 -->
|
<!-- 获取文件 -->
|
||||||
<select id="getFile" parameterType="map" resultMap="filePO">
|
<select id="getFile" parameterType="map" resultMap="filePO">
|
||||||
SELECT
|
SELECT
|
||||||
*
|
file_id,
|
||||||
|
file_name,
|
||||||
|
file_path,
|
||||||
|
file_url,
|
||||||
|
file_type,
|
||||||
|
file_size,
|
||||||
|
file_summary,
|
||||||
|
is_back,
|
||||||
|
creator,
|
||||||
|
gmt_create,
|
||||||
|
modifier,
|
||||||
|
gmt_modified,
|
||||||
|
is_delete
|
||||||
FROM
|
FROM
|
||||||
sys_file
|
sys_file
|
||||||
WHERE
|
WHERE
|
||||||
@ -123,7 +135,19 @@
|
|||||||
<!-- 文件列表 -->
|
<!-- 文件列表 -->
|
||||||
<select id="listFile" parameterType="map" resultMap="fileDTO">
|
<select id="listFile" parameterType="map" resultMap="fileDTO">
|
||||||
SELECT
|
SELECT
|
||||||
*
|
file_id,
|
||||||
|
file_name,
|
||||||
|
file_path,
|
||||||
|
file_url,
|
||||||
|
file_type,
|
||||||
|
file_size,
|
||||||
|
file_summary,
|
||||||
|
is_back,
|
||||||
|
creator,
|
||||||
|
gmt_create,
|
||||||
|
modifier,
|
||||||
|
gmt_modified,
|
||||||
|
is_delete
|
||||||
FROM
|
FROM
|
||||||
sys_file
|
sys_file
|
||||||
WHERE
|
WHERE
|
||||||
@ -132,6 +156,10 @@
|
|||||||
AND
|
AND
|
||||||
file_name LIKE CONCAT('%', #{keywords}, '%')
|
file_name LIKE CONCAT('%', #{keywords}, '%')
|
||||||
</if>
|
</if>
|
||||||
|
<if test="fileSummary != null and fileSummary != ''">
|
||||||
|
AND
|
||||||
|
file_summary = #{fileSummary}
|
||||||
|
</if>
|
||||||
<if test="startTime != null and startTime != ''">
|
<if test="startTime != null and startTime != ''">
|
||||||
AND
|
AND
|
||||||
LEFT(gmt_create, 10) <![CDATA[ >= ]]> #{startTime}
|
LEFT(gmt_create, 10) <![CDATA[ >= ]]> #{startTime}
|
||||||
@ -156,7 +184,19 @@
|
|||||||
<!-- 文件列表 -->
|
<!-- 文件列表 -->
|
||||||
<select id="listFileInfo" parameterType="map" resultMap="fileInfoDTO">
|
<select id="listFileInfo" parameterType="map" resultMap="fileInfoDTO">
|
||||||
SELECT
|
SELECT
|
||||||
*
|
file_id,
|
||||||
|
file_name,
|
||||||
|
file_path,
|
||||||
|
file_url,
|
||||||
|
file_type,
|
||||||
|
file_size,
|
||||||
|
file_summary,
|
||||||
|
is_back,
|
||||||
|
creator,
|
||||||
|
gmt_create,
|
||||||
|
modifier,
|
||||||
|
gmt_modified,
|
||||||
|
is_delete
|
||||||
FROM
|
FROM
|
||||||
sys_file
|
sys_file
|
||||||
WHERE
|
WHERE
|
||||||
@ -185,7 +225,19 @@
|
|||||||
<!-- 获取文件列表(带路径) -->
|
<!-- 获取文件列表(带路径) -->
|
||||||
<select id="listFileInfoWithPath" parameterType="map" resultMap="fileInfoWithPathDTO">
|
<select id="listFileInfoWithPath" parameterType="map" resultMap="fileInfoWithPathDTO">
|
||||||
SELECT
|
SELECT
|
||||||
*
|
file_id,
|
||||||
|
file_name,
|
||||||
|
file_path,
|
||||||
|
file_url,
|
||||||
|
file_type,
|
||||||
|
file_size,
|
||||||
|
file_summary,
|
||||||
|
is_back,
|
||||||
|
creator,
|
||||||
|
gmt_create,
|
||||||
|
modifier,
|
||||||
|
gmt_modified,
|
||||||
|
is_delete
|
||||||
FROM
|
FROM
|
||||||
sys_file
|
sys_file
|
||||||
WHERE
|
WHERE
|
||||||
@ -199,4 +251,28 @@
|
|||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 文件列表 -->
|
||||||
|
<select id="listFileByMd5" parameterType="java.lang.String" resultMap="fileInfoDTO">
|
||||||
|
SELECT
|
||||||
|
file_id,
|
||||||
|
file_name,
|
||||||
|
file_path,
|
||||||
|
file_url,
|
||||||
|
file_type,
|
||||||
|
file_size,
|
||||||
|
file_summary,
|
||||||
|
is_back,
|
||||||
|
creator,
|
||||||
|
gmt_create,
|
||||||
|
modifier,
|
||||||
|
gmt_modified,
|
||||||
|
is_delete
|
||||||
|
FROM
|
||||||
|
sys_file
|
||||||
|
WHERE
|
||||||
|
is_delete = 0
|
||||||
|
AND
|
||||||
|
file_summary = #{_parameter}
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
Loading…
Reference in New Issue
Block a user