2023年1月10日15:11:00

main
wenbaoquan 2 years ago
parent e40d9d13c4
commit 3d6520e052
  1. 89
      src/main/java/com/zilber/boot/file/controller/FileUploadController.java
  2. 8
      src/main/java/com/zilber/boot/file/dao/FileDao.java
  3. 29
      src/main/java/com/zilber/boot/file/entity/Complete.java
  4. 21
      src/main/java/com/zilber/boot/file/entity/ComposeDTO.java
  5. 20
      src/main/java/com/zilber/boot/file/entity/ETag.java
  6. 38
      src/main/java/com/zilber/boot/file/entity/FileCheckDTO.java
  7. 27
      src/main/java/com/zilber/boot/file/entity/FileUploadDTO.java
  8. 38
      src/main/java/com/zilber/boot/file/entity/FileUploadRequestDTO.java
  9. 30
      src/main/java/com/zilber/boot/file/entity/FileUploadsDTO.java
  10. 47
      src/main/java/com/zilber/boot/file/entity/FileUploadsRequestDTO.java
  11. 2
      src/main/java/com/zilber/boot/file/entity/OssComplete.java
  12. 2
      src/main/java/com/zilber/boot/file/entity/OssListParts.java
  13. 21
      src/main/java/com/zilber/boot/file/entity/PartList.java
  14. 287
      src/main/java/com/zilber/boot/file/service/UploadUtils.java
  15. 158
      src/main/java/com/zilber/boot/utils/Base64Util.java
  16. 13
      src/main/resources/application.yml

@ -0,0 +1,89 @@
package com.zilber.boot.file.controller;
import com.aliyun.oss.model.*;
import com.zilber.boot.file.entity.*;
import com.zilber.boot.file.service.UploadUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import reactor.util.annotation.Nullable;
import java.io.IOException;
import java.util.Map;
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping("/file")
@Api(tags = "基本功能管理")
public class FileUploadController {
private final UploadUtils uploadUtils;
@ApiOperation("文件上传服务器")
@PostMapping("/upload")
public Map<String, String> uploadFile(MultipartFile file) {
return uploadUtils.upload(file);
}
@ApiOperation("分片上传服务器")
@PostMapping("/slice")
public ETag sliceUploads(FileUploadsRequestDTO param) {
return uploadUtils.sliceUploads(param);
}
@ApiOperation("分片上传检测-服务器")
@PostMapping("/check")
public PartList fileCheck(String fileMd5, String UUID) throws IOException {
return uploadUtils.fileCheck(fileMd5, UUID);
}
@ApiOperation("分片上传合成-服务器")
@PostMapping("/compose")
public Complete compose(@RequestBody ComposeDTO dto) {
return uploadUtils.compose(dto.getUuid(), dto.getType(), dto.getFileMd5());
}
@ApiOperation("文件上传oss服务器")
@PostMapping("/oss/upload")
public Map<String, String> uploadFileToOss(MultipartFile file) {
return uploadUtils.upload(file, null);
}
@ApiOperation("分片上传初始化-oss服务器")
@PostMapping("/oss/initiate")
public OssPartUpload initiate(String fileName) {
return uploadUtils.InitiateMultipartUpload(fileName, null, null);
}
@ApiOperation("分片上传-oss服务器")
@PostMapping("/oss/slice")
public PartETag sliceUploads(OssPartUpload upload) {
return uploadUtils.uploadPart(upload);
}
@ApiOperation("分片上传检测-oss服务器")
@PostMapping("/oss/check")
public PartListing PartListing(OssListParts parts) {
return uploadUtils.list(parts);
}
@ApiOperation("分片上传合成-oss服务器")
@PostMapping("/oss/compose")
public CompleteMultipartUploadResult compose(@RequestBody OssComplete complete) {
return uploadUtils.completeUpload(complete);
}
@ApiOperation("分片上传取消-oss服务器")
@PostMapping("/oss/abort")
public void abort(OssCancel cancel) {
uploadUtils.abortUpload(cancel);
}
}

@ -10,10 +10,10 @@ import java.util.Map;
@Mapper @Mapper
public interface FileDao { public interface FileDao {
@Select("SELECT url, type FROM file WHERE md5 = #{md5} LIMIT 1") @Select("SELECT url, type FROM file WHERE md5 = #{md5} AND location = #{location} LIMIT 1")
Map<String, Object> listFileUrl(@Param("md5") String md5); Map<String, String> listFileUrl(@Param("md5") String md5, @Param("location") Integer location);
@Insert("INSERT INTO file(md5, url, type) VALUES (#{md5}, #{url}, #{type})") @Insert("INSERT INTO file(md5, url, type, location) VALUES (#{md5}, #{url}, #{type},#{location})")
void addFile(@Param("md5") String md5,@Param("url") String url,@Param("type") Integer type); void addFile(@Param("md5") String md5,@Param("url") String url,@Param("type") Integer type,@Param("location") Integer location);
} }

@ -0,0 +1,29 @@
package com.zilber.boot.file.entity;
import lombok.Data;
/**
* @Author LJX
* @TIME 2023-01-10 14:32
* @PROJECT boot
* created by Intellij IDEA
* Description
*/
@Data
public class Complete {
private String bucketName;
private String key;
private String location;
private String eTag;
private String versionId;
private String name;
private Integer type;
}

@ -0,0 +1,21 @@
package com.zilber.boot.file.entity;
import lombok.Data;
/**
* @Author LJX
* @TIME 2022-10-12 13:16
* @PROJECT cppcc
* created by Intellij IDEA
* Description
*/
@Data
public class ComposeDTO {
private String uuid;
private String fileMd5;
private String type;
}

@ -0,0 +1,20 @@
package com.zilber.boot.file.entity;
import lombok.Data;
/**
* @Author LJX
* @TIME 2023-01-10 14:18
* @PROJECT boot
* created by Intellij IDEA
* Description
*/
@Data
public class ETag {
private int partNumber;
private String eTag;
private long partSize;
private Long partCRC;
}

@ -0,0 +1,38 @@
package com.zilber.boot.file.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Map;
/**
* @Author LJX
* @TIME 2022-10-11 11:04
* @PROJECT cppcc
* created by Intellij IDEA
* Description
*/
@Data
@ApiModel("文件检测")
public class FileCheckDTO {
@ApiModelProperty(name = "文件路径")
private String url;
@ApiModelProperty(name = "文件类型")
private Integer type;
@ApiModelProperty(name = "文件是否存在")
private Boolean exist;
@ApiModelProperty(name = "文件是否已上传")
private Boolean uploaded;
@ApiModelProperty(name = "文件总块数")
private Long chunks;
@ApiModelProperty(name = "文件块信息")
private Map<String, Boolean> chunkInfo;
}

@ -0,0 +1,27 @@
package com.zilber.boot.file.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import java.util.Map;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("文件上传返回")
public class FileUploadDTO {
@ApiModelProperty("文件状态:1-完成 0-失败或未完成")
private Integer uploadComplete;
private Map<Long, String> chunkMd5Info;
@ApiModelProperty("文件名")
private String name;
@ApiModelProperty("文件地址")
private String url;
}

@ -0,0 +1,38 @@
package com.zilber.boot.file.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
@Data
@ApiModel("文件切片")
public class FileUploadRequestDTO {
//文件
@ApiModelProperty("文件")
private MultipartFile file;
//块大小
@ApiModelProperty("文件块大小")
private Long chunkSize;
//当前块数
@ApiModelProperty("当前文件块")
private Long chunk;
//总块数
@ApiModelProperty("文件总块数")
private Long chunks;
@ApiModelProperty("文件类型")
private String type;
@ApiModelProperty("文件名称")
private String name;
@ApiModelProperty("md5")
private String md5;
/*private String path;*/
}

@ -0,0 +1,30 @@
package com.zilber.boot.file.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("文件上传返回")
public class FileUploadsDTO {
@ApiModelProperty("文件状态:1-完成 0-失败或未完成")
private Integer uploadComplete;
//块大小
@ApiModelProperty("文件块大小")
private Long chunkSize;
//当前块数
@ApiModelProperty("当前文件块")
private Long chunk;
//总块数
@ApiModelProperty("文件总块数")
private Long chunks;
}

@ -0,0 +1,47 @@
package com.zilber.boot.file.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
@Data
@ApiModel("文件切片")
public class FileUploadsRequestDTO {
//文件
@ApiModelProperty("文件")
private MultipartFile file;
//块大小
@ApiModelProperty("文件块大小")
private Long chunkSize;
//当前块数
@ApiModelProperty("当前文件块")
private Long chunk;
//总块数
@ApiModelProperty("文件总块数")
private Long chunks;
@ApiModelProperty("文件类型")
private String type;
@ApiModelProperty("文件名称")
private String name;
@ApiModelProperty("文件大小")
private Long size;
// @ApiModelProperty("分片md5")
// private String sliceMd5;
//
// @ApiModelProperty("md5")
// private String md5;
@ApiModelProperty("uuid")
private String UUID;
/*private String path;*/
}

@ -32,6 +32,6 @@ public class OssComplete extends OssProperties{
@NotNull(message = "tag列表不能为空") @NotNull(message = "tag列表不能为空")
@ApiModelProperty("tag列表") @ApiModelProperty("tag列表")
private List<PartETag> tags; private List<ETag> tags;
} }

@ -31,6 +31,6 @@ public class OssListParts extends OssProperties {
private Integer maxParts = 100; private Integer maxParts = 100;
@ApiModelProperty(value = "开始块数") @ApiModelProperty(value = "开始块数")
private Integer partNumberMarker = 0; private Integer partNumberMarker = 1;
} }

@ -0,0 +1,21 @@
package com.zilber.boot.file.entity;
import lombok.Data;
import java.util.List;
/**
* @Author LJX
* @TIME 2023-01-10 14:51
* @PROJECT boot
* created by Intellij IDEA
* Description
*/
@Data
public class PartList {
private Long total;
private List<ETag> tags;
}

@ -3,13 +3,14 @@ package com.zilber.boot.file.service;
import com.aliyun.oss.*; import com.aliyun.oss.*;
import com.aliyun.oss.model.*; import com.aliyun.oss.model.*;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.cppcc.common.validator.ValidatorUtils; import com.zilber.boot.file.dao.FileDao;
import com.cppcc.files.*;
import com.cppcc.files.dao.FileDao;
import com.zilber.boot.file.entity.*; import com.zilber.boot.file.entity.*;
import com.zilber.boot.utils.file.FileUtils;
import com.zilber.boot.utils.sign.Md5Utils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.security.MD5Encoder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -33,7 +34,7 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
public class UploadUtils { public class UploadUtils {
@Value("${cppcc.localtion}") @Value("${zilber.localtion}")
private String localtion; private String localtion;
@Resource @Resource
@ -44,13 +45,20 @@ public class UploadUtils {
public Map<String, String> upload(MultipartFile file) { public Map<String, String> upload(MultipartFile file) {
try { try {
Map<String, String> objectMap = fileDao.listFileUrl(MD5Encoder.encode(file.getBytes()), 1);
if ( objectMap != null ){
objectMap.put("name", file.getOriginalFilename());
return objectMap;
}
String type = "." + FilenameUtils.getExtension(file.getOriginalFilename()); String type = "." + FilenameUtils.getExtension(file.getOriginalFilename());
String name = FilenameUtils.getName(file.getOriginalFilename()); String name = FilenameUtils.getName(file.getOriginalFilename());
String filePath = localtion + "/upload"; String filePath = localtion + "/upload";
String fileName = UUID.randomUUID() + type; String fileName = UUID.randomUUID() + type;
File desc = getAbsoluteFile(filePath, fileName); File desc = getAbsoluteFile(filePath, fileName);
file.transferTo(desc); file.transferTo(desc);
return getPathFileName(filePath, fileName, name, type); Map<String, String> pathFileName = getPathFileName(filePath, fileName, name, type);
fileDao.addFile(MD5Encoder.encode(file.getBytes()), filePath, Integer.parseInt(pathFileName.get("type")), 1);
return pathFileName;
} catch (Exception e) { } catch (Exception e) {
log.error(e.getLocalizedMessage()); log.error(e.getLocalizedMessage());
return new ConcurrentHashMap<>(); return new ConcurrentHashMap<>();
@ -64,7 +72,7 @@ public class UploadUtils {
String pathFileName = "/profile" + "/" + currentDir + "/" + fileName; String pathFileName = "/profile" + "/" + currentDir + "/" + fileName;
map.put("url", pathFileName); map.put("url", pathFileName);
map.put("name", name); map.put("name", name);
map.put("type", String.valueOf(SliceUploadsTemplate.getFileType(type))); map.put("type", String.valueOf(getFileType(type)));
return map; return map;
} }
@ -86,7 +94,16 @@ public class UploadUtils {
* @param module oss目录 * @param module oss目录
* @return * @return
*/ */
public PutObjectResult upload(MultipartFile file, @Nullable String module) { public Map<String, String> upload(MultipartFile file, @Nullable String module) {
try {
Map<String, String> objectMap = fileDao.listFileUrl(MD5Encoder.encode(file.getBytes()), 2);
if ( objectMap != null ){
objectMap.put("name", file.getOriginalFilename());
return objectMap;
}
} catch (IOException e) {
e.printStackTrace();
}
/** /**
* 获取oss的属性 * 获取oss的属性
*/ */
@ -97,8 +114,9 @@ public class UploadUtils {
if ( StringUtils.isBlank(module) ){ if ( StringUtils.isBlank(module) ){
module = ossProperties.getModule(); module = ossProperties.getModule();
} }
String extension = file.getName().substring(file.getName().lastIndexOf(".")); String extension = "." + FilenameUtils.getExtension(file.getOriginalFilename());
String objectName = module + "/" + UUID.randomUUID().toString() + extension; String objectName = module + "/" + UUID.randomUUID().toString() + extension;
Map<String, String> resultMap = new HashMap<>();
// 创建OSSClient实例。 // 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
@ -110,7 +128,15 @@ public class UploadUtils {
putObjectRequest.setProcess("true"); putObjectRequest.setProcess("true");
// 上传字符串。 // 上传字符串。
PutObjectResult result = ossClient.putObject(putObjectRequest); PutObjectResult result = ossClient.putObject(putObjectRequest);
return result; if ( result.getResponse().getStatusCode() == 200 ){
Integer fileType = getFileType(extension);
String uri = result.getResponse().getUri();
resultMap.put("url", uri);
resultMap.put("name", file.getOriginalFilename());
resultMap.put("type", String.valueOf(fileType));
fileDao.addFile(MD5Encoder.encode(file.getBytes()), uri, fileType, 2);
return resultMap;
}
} catch (OSSException oe) { } catch (OSSException oe) {
throw new ServiceException(oe.getMessage()); throw new ServiceException(oe.getMessage());
} catch (ClientException ce) { } catch (ClientException ce) {
@ -145,7 +171,7 @@ public class UploadUtils {
/********************************************************************************************/ /********************************************************************************************/
public FileUploadDTO sliceUploads(FileUploadsRequestDTO param) { public ETag sliceUploads(FileUploadsRequestDTO param) {
boolean isOk = true; boolean isOk = true;
File root = new File(localtion + "/upload", param.getUUID()); File root = new File(localtion + "/upload", param.getUUID());
if (!root.exists() || !root.isDirectory()) { if (!root.exists() || !root.isDirectory()) {
@ -163,40 +189,98 @@ public class UploadUtils {
map.put(param.getChunk(), param.getUUID()); map.put(param.getChunk(), param.getUUID());
if (isOk) { if (isOk) {
String sliceName = param.getChunk().toString(); String sliceName = param.getChunk().toString();
upload(root, sliceName, param); return upload(root, sliceName, param);
} }
return FileUploadDTO.builder().chunkMd5Info(map).build(); return null;
} }
/** /**
* 文件检测 * 文件检测
* * {
* "requestId": "63BD04BA1253C53638A9F751",
* "bucketName": "zilber-public",
* "key": "upload/3a3cd46a-d966-4258-a6e7-a3b318cbe133.jpg",
* "uploadId": "70F44C7139E14DE0AB6BD7442F0F4AFE",
* "maxParts": 100,
* "partNumberMarker": 1,
* "storageClass": "Standard",
* "nextPartNumberMarker": 2,
* "parts": [
* {
* "partNumber": 2,
* "lastModified": "2023-01-10T14:08:37.000+0800",
* "size": 566470,
* "etag": "21DE9DD8AE549FF2285DDC5E23B67867"
* }
* ],
* "truncated": false
* }
* @param md5 md5 * @param md5 md5
* @param UUID UUID * @param UUID UUID
* @return * @return
* @throws IOException * @throws IOException
*/ */
public FileCheckDTO fileCheck(String md5, String UUID) throws IOException { public PartList fileCheck(String md5, String UUID) throws IOException {
FileCheckDTO fileCheckDTO = new FileCheckDTO(); PartList list = new PartList();
//根据文件md5查询文件是否存在,如果存在,则直接返回文件路径,否则返回块信息 List<ETag> eTags = new ArrayList<>();
//TODO File root = new File(localtion + "/upload", UUID);
Map<String, Object> objectMap = fileDao.listFileUrl(md5); if (!root.exists()) {
if (objectMap != null) { return null;
fileCheckDTO.setUrl(objectMap.get("url").toString()); }
fileCheckDTO.setType(Integer.parseInt(objectMap.get("type").toString())); //获取总块数
fileCheckDTO.setExist(true); // File aConf = new File(root.getAbsolutePath(), UUID + ".conf");
return fileCheckDTO; // FileReader fr = new FileReader(aConf);
} // char[] chunkCs = new char[(int) aConf.length()];
//不存在 // fr.read(chunkCs);
return checkUnexist(UUID, fileCheckDTO); Long chunks = chunks(root, UUID);
list.setTotal(chunks);
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File file, String s) {
return s.endsWith(".conf") && !s.contains("-");
}
};
String[] fileNames = root.list(filter);
if (fileNames == null) {
return null;
}
List<String> fileNameList = Arrays.asList(fileNames)
.stream().distinct().collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(fileNameList)) {
for (String fileName : fileNameList) {
String prefix = fileName.split("\\.")[0];
ETag tag = new ETag();
tag.setPartSize(new File(root.getAbsolutePath(), fileName).getTotalSpace());
tag.setPartNumber(Integer.parseInt(prefix));
eTags.add(tag);
}
list.setTags(eTags);
return list;
}
return list;
} }
/** /**
* {
* "partNumber": 2,
* "partSize": 566470,
* "partCRC": 997575365254752264,
* "etag": "21DE9DD8AE549FF2285DDC5E23B67867"
* }
* @return * @return
* @author liuao * @author liuao
*/ */
public boolean upload(File root, String name, FileUploadsRequestDTO param) { public ETag upload(File root, String name, FileUploadsRequestDTO param) {
//保存最大块数 //保存最大块数
ETag tag = new ETag();
try {
tag.setPartNumber(param.getChunk().intValue());
tag.setPartSize(param.getChunkSize());
tag.setETag(MD5Encoder.encode(param.getFile().getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
File aConfFile = new File(root.getAbsolutePath(), param.getUUID() + ".conf"); File aConfFile = new File(root.getAbsolutePath(), param.getUUID() + ".conf");
File sizeFile = new File(root.getAbsolutePath(), "size.conf"); File sizeFile = new File(root.getAbsolutePath(), "size.conf");
if (!aConfFile.exists()) { if (!aConfFile.exists()) {
@ -229,7 +313,7 @@ public class UploadUtils {
accessTmpFile = new RandomAccessFile(tmpFile, "rw"); accessTmpFile = new RandomAccessFile(tmpFile, "rw");
accessTmpFile.write(param.getFile().getBytes()); accessTmpFile.write(param.getFile().getBytes());
log.info(param.getUUID() + "文件块" + param.getChunk() + "上传完成"); log.info(param.getUUID() + "文件块" + param.getChunk() + "上传完成");
return true; return tag;
} catch (IOException e) { } catch (IOException e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
if (tmpConfFile.exists()) { if (tmpConfFile.exists()) {
@ -251,28 +335,40 @@ public class UploadUtils {
} }
} }
} }
return false; return null;
} }
public FileCheckDTO compose(String UUID, String type, String md5) { /**
* {
* "requestId": "63BD05267FFDC23733FE3B95",
* "clientCRC": -1453100417491105764,
* "serverCRC": -1453100417491105764,
* "bucketName": "zilber-public",
* "key": "upload/3a3cd46a-d966-4258-a6e7-a3b318cbe133.jpg",
* "location": "http://zilber-public.oss-cn-beijing.aliyuncs.com/upload/3a3cd46a-d966-4258-a6e7-a3b318cbe133.jpg",
* "etag": "8DDB27878F7D65485F8E83A2B5E7F11E-2"
* }
* @param UUID
* @param type
* @param md5
* @return
*/
public Complete compose(String UUID, String type, String md5) {
long startTime = 0, endTime = 0; long startTime = 0, endTime = 0;
log.info(String.valueOf(System.currentTimeMillis())); log.info(String.valueOf(System.currentTimeMillis()));
FileCheckDTO fileCheckDTO = new FileCheckDTO(); Complete complete = new Complete();
File root = new File(localtion + "/upload", UUID); File root = new File(localtion + "/upload", UUID);
File targetFile = new File(localtion + "/upload", UUID + type); File targetFile = new File(localtion + "/upload", UUID + type);
Long chunks = chunks(root, UUID); Long chunks = chunks(root, UUID);
File[] fileNames = root.listFiles((file1, s1) -> !s1.endsWith(".conf")); File[] fileNames = root.listFiles((file1, s1) -> !s1.endsWith(".conf"));
if (fileNames == null || fileNames.length < chunks) { if (fileNames == null || fileNames.length < chunks) {
return checkUnexist(UUID, new FileCheckDTO()); return null;
} }
List<File> collect = Arrays.asList(fileNames) List<File> collect = Arrays.asList(fileNames)
.stream().sorted(new Comparator<File>() { .stream().sorted((file, t1) -> {
@Override int f = Integer.parseInt(file.getName());
public int compare(File file, File t1) { int t = Integer.parseInt(t1.getName());
int f = Integer.parseInt(file.getName()); return f < t ? -1 : 1;
int t = Integer.parseInt(t1.getName());
return f < t ? -1 : 1;
}
}).collect(Collectors.toList()); }).collect(Collectors.toList());
FileOutputStream fos; FileOutputStream fos;
FileInputStream fis; FileInputStream fis;
@ -304,54 +400,11 @@ public class UploadUtils {
String currentDir = StringUtils.substring(localtion + "/upload", dirLastIndex); String currentDir = StringUtils.substring(localtion + "/upload", dirLastIndex);
String pathFileName = "/profile" + "/" + currentDir + "/" + UUID + type; String pathFileName = "/profile" + "/" + currentDir + "/" + UUID + type;
Integer t = getFileType(type); Integer t = getFileType(type);
fileDao.addFile(md5, pathFileName, t); fileDao.addFile(md5, pathFileName, t, 1);
fileCheckDTO.setUrl(pathFileName); complete.setLocation(pathFileName);
fileCheckDTO.setType(t); complete.setType(t);
fileCheckDTO.setExist(true);
clearTempFiles(root); clearTempFiles(root);
return fileCheckDTO; return complete;
}
private FileCheckDTO checkUnexist(String UUID, FileCheckDTO fileCheckDTO) {
//不存在
fileCheckDTO.setExist(false);
File root = new File(localtion + "/upload", UUID);
if (!root.exists()) {
fileCheckDTO.setUploaded(false);
return fileCheckDTO;
}
//获取总块数
// File aConf = new File(root.getAbsolutePath(), UUID + ".conf");
// FileReader fr = new FileReader(aConf);
// char[] chunkCs = new char[(int) aConf.length()];
// fr.read(chunkCs);
Long chunks = chunks(root, UUID);
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File file, String s) {
return s.endsWith(".conf") && !s.contains("-");
}
};
String[] fileNames = root.list(filter);
if (fileNames == null) {
fileCheckDTO.setUploaded(false);
return fileCheckDTO;
}
List<String> fileNameList = Arrays.asList(fileNames)
.stream().distinct().collect(Collectors.toList());
Map<String, Boolean> chunkInfo = new HashMap<>();
if (CollectionUtils.isNotEmpty(fileNameList)) {
for (String fileName : fileNameList) {
String prefix = fileName.split("\\.")[0];
chunkInfo.put(prefix, true);
}
fileCheckDTO.setChunkInfo(chunkInfo);
fileCheckDTO.setUploaded(true);
fileCheckDTO.setChunks(chunks);
return fileCheckDTO;
}
fileCheckDTO.setUploaded(false);
return fileCheckDTO;
} }
private Long chunks(File root, String UUID) { private Long chunks(File root, String UUID) {
@ -396,7 +449,7 @@ public class UploadUtils {
* @param module 目标文件夹 * @param module 目标文件夹
* @return 文件唯一标识 * @return 文件唯一标识
*/ */
public OssPartUpload InitiateMultipartUpload(String fileName, @Nullable String module, OssProperties provided) { public OssPartUpload InitiateMultipartUpload(String fileName, @Nullable String module,@Nullable OssProperties provided) {
/** /**
* 获取oss的属性 * 获取oss的属性
*/ */
@ -404,30 +457,38 @@ public class UploadUtils {
String accessKeyId = ""; String accessKeyId = "";
String accessKeySecret = ""; String accessKeySecret = "";
String bucketName = ""; String bucketName = "";
if ( StringUtils.isNotBlank(provided.getEndpoint())){ if ( provided != null ){
endpoint = provided.getEndpoint(); if ( StringUtils.isNotBlank(provided.getEndpoint())){
endpoint = provided.getEndpoint();
}else {
endpoint = ossProperties.getEndpoint();
}
if ( StringUtils.isNotBlank(provided.getKeyId())){
accessKeyId = provided.getKeyId();
}else {
accessKeyId = ossProperties.getKeyId();
}
if ( StringUtils.isNotBlank(provided.getKeySecret())){
accessKeySecret = provided.getKeySecret();
}else {
accessKeySecret = ossProperties.getKeySecret();
}
if ( StringUtils.isNotBlank(provided.getBucketName())){
bucketName = provided.getBucketName();
}else {
bucketName = ossProperties.getBucketName();
}
}else { }else {
endpoint = ossProperties.getEndpoint(); endpoint = ossProperties.getEndpoint();
}
if ( StringUtils.isNotBlank(provided.getKeyId())){
accessKeyId = provided.getKeyId();
}else {
accessKeyId = ossProperties.getKeyId(); accessKeyId = ossProperties.getKeyId();
}
if ( StringUtils.isNotBlank(provided.getKeySecret())){
accessKeySecret = provided.getKeySecret();
}else {
accessKeySecret = ossProperties.getKeySecret(); accessKeySecret = ossProperties.getKeySecret();
}
if ( StringUtils.isNotBlank(provided.getBucketName())){
bucketName = provided.getBucketName();
}else {
bucketName = ossProperties.getBucketName(); bucketName = ossProperties.getBucketName();
} }
if ( StringUtils.isBlank(module) ){ if ( StringUtils.isBlank(module) ){
module = ossProperties.getModule(); module = ossProperties.getModule();
} }
String extension = fileName.substring(fileName.lastIndexOf(".")); String extension = "." + FilenameUtils.getExtension(fileName);
String objectName = module + "/" + UUID.randomUUID().toString() + extension; String objectName = module + "/" + UUID.randomUUID().toString() + extension;
Map<String, String> resultMap = new HashMap<>(); Map<String, String> resultMap = new HashMap<>();
@ -449,8 +510,8 @@ public class UploadUtils {
* @param upload 分片信息 * @param upload 分片信息
* @return * @return
*/ */
public UploadPartResult uploadPart(OssPartUpload upload) { public PartETag uploadPart(OssPartUpload upload) {
ValidatorUtils.validateEntity(upload, DefaultGroup.class); //ValidatorUtils.validateEntity(upload);
/** /**
* 获取oss的属性 * 获取oss的属性
*/ */
@ -493,7 +554,7 @@ public class UploadUtils {
// 设置分片号。每一个上传的分片都有一个分片号,取值范围是1~10000,如果超出此范围,OSS将返回InvalidArgument错误码。 // 设置分片号。每一个上传的分片都有一个分片号,取值范围是1~10000,如果超出此范围,OSS将返回InvalidArgument错误码。
uploadPartRequest.setPartNumber(upload.getPartNumber()); uploadPartRequest.setPartNumber(upload.getPartNumber());
// 每个分片不需要按顺序上传,甚至可以在不同客户端上传,OSS会按照分片号排序组成完整的文件。 // 每个分片不需要按顺序上传,甚至可以在不同客户端上传,OSS会按照分片号排序组成完整的文件。
return ossClient.uploadPart(uploadPartRequest); return ossClient.uploadPart(uploadPartRequest).getPartETag();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -506,7 +567,7 @@ public class UploadUtils {
* @return * @return
*/ */
public PartListing list(OssListParts parts) { public PartListing list(OssListParts parts) {
ValidatorUtils.validateEntity(parts, DefaultGroup.class); //ValidatorUtils.validateEntity(parts);
/** /**
* 获取oss的属性 * 获取oss的属性
*/ */
@ -558,7 +619,7 @@ public class UploadUtils {
* @return * @return
*/ */
public CompleteMultipartUploadResult completeUpload(OssComplete complete) { public CompleteMultipartUploadResult completeUpload(OssComplete complete) {
ValidatorUtils.validateEntity(complete, DefaultGroup.class); //ValidatorUtils.validateEntity(complete, DefaultGroup.class);
/** /**
* 获取oss的属性 * 获取oss的属性
*/ */
@ -586,7 +647,13 @@ public class UploadUtils {
}else { }else {
bucketName = ossProperties.getBucketName(); bucketName = ossProperties.getBucketName();
} }
List<PartETag> partETags = new ArrayList<>();
if ( CollectionUtils.isNotEmpty(complete.getTags())){
for ( ETag e : complete.getTags()){
PartETag partETag = new PartETag(e.getPartNumber(), e.getETag(), e.getPartSize(), e.getPartCRC());
partETags.add(partETag);
}
}
// 创建OSSClient实例。 // 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 在执行完成分片上传操作时,需要提供所有有效的partETags。OSS收到提交的partETags后,会逐一验证每个分片的有效性。当所有的数据分片验证通过后,OSS将把这些分片组合成一个完整的文件。 // 在执行完成分片上传操作时,需要提供所有有效的partETags。OSS收到提交的partETags后,会逐一验证每个分片的有效性。当所有的数据分片验证通过后,OSS将把这些分片组合成一个完整的文件。
@ -594,7 +661,7 @@ public class UploadUtils {
new CompleteMultipartUploadRequest(bucketName, new CompleteMultipartUploadRequest(bucketName,
complete.getKey(), complete.getKey(),
complete.getUploadId(), complete.getUploadId(),
complete.getTags()); partETags);
// 完成分片上传。 // 完成分片上传。
return ossClient.completeMultipartUpload(completeMultipartUploadRequest); return ossClient.completeMultipartUpload(completeMultipartUploadRequest);
} }
@ -604,7 +671,7 @@ public class UploadUtils {
* @param cancel * @param cancel
*/ */
public void abortUpload(OssCancel cancel) { public void abortUpload(OssCancel cancel) {
ValidatorUtils.validateEntity(cancel, DefaultGroup.class); //ValidatorUtils.validateEntity(cancel, DefaultGroup.class);
/** /**
* 获取oss的属性 * 获取oss的属性
*/ */

@ -1,79 +1,79 @@
package com.zilber.boot.utils; //package com.zilber.boot.utils;
//
import sun.misc.BASE64Decoder; //import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; //import sun.misc.BASE64Encoder;
//
import javax.imageio.stream.FileImageInputStream; //import javax.imageio.stream.FileImageInputStream;
import java.io.ByteArrayOutputStream; //import java.io.ByteArrayOutputStream;
import java.io.File; //import java.io.File;
import java.io.IOException; //import java.io.IOException;
import java.util.regex.Matcher; //import java.util.regex.Matcher;
import java.util.regex.Pattern; //import java.util.regex.Pattern;
//
public class Base64Util{ //public class Base64Util{
/** // /**
* 字符串转图片 // * 字符串转图片
* @param base64Str // * @param base64Str
* @return // * @return
*/ // */
public static byte[] decode(String base64Str){ // public static byte[] decode(String base64Str){
byte[] b = null; // byte[] b = null;
BASE64Decoder decoder = new BASE64Decoder(); // BASE64Decoder decoder = new BASE64Decoder();
try { // try {
b = decoder.decodeBuffer(replaceEnter(base64Str)); // b = decoder.decodeBuffer(replaceEnter(base64Str));
} catch (IOException e) { // } catch (IOException e) {
e.printStackTrace(); // e.printStackTrace();
} // }
return b; // return b;
} // }
//
/** // /**
* 图片转字符串 // * 图片转字符串
* @param image // * @param image
* @return // * @return
*/ // */
public static String encode(byte[] image){ // public static String encode(byte[] image){
BASE64Encoder decoder = new BASE64Encoder(); // BASE64Encoder decoder = new BASE64Encoder();
return replaceEnter(decoder.encode(image)); // return replaceEnter(decoder.encode(image));
} // }
//
public static String encode(String uri){ // public static String encode(String uri){
BASE64Encoder encoder = new BASE64Encoder(); // BASE64Encoder encoder = new BASE64Encoder();
return replaceEnter(encoder.encode(uri.getBytes())); // return replaceEnter(encoder.encode(uri.getBytes()));
} // }
//
/** // /**
* // *
* @path 图片路径 // * @path 图片路径
* @return // * @return
*/ // */
//
public static byte[] imageTobyte(String path){ // public static byte[] imageTobyte(String path){
byte[] data = null; // byte[] data = null;
FileImageInputStream input = null; // FileImageInputStream input = null;
try { // try {
input = new FileImageInputStream(new File(path)); // input = new FileImageInputStream(new File(path));
ByteArrayOutputStream output = new ByteArrayOutputStream(); // ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buf = new byte[1024]; // byte[] buf = new byte[1024];
int numBytesRead = 0; // int numBytesRead = 0;
while((numBytesRead = input.read(buf)) != -1){ // while((numBytesRead = input.read(buf)) != -1){
output.write(buf, 0, numBytesRead); // output.write(buf, 0, numBytesRead);
} // }
data = output.toByteArray(); // data = output.toByteArray();
output.close(); // output.close();
input.close(); // input.close();
//
} catch (Exception e) { // } catch (Exception e) {
e.printStackTrace(); // e.printStackTrace();
} // }
//
return data; // return data;
} // }
//
public static String replaceEnter(String str){ // public static String replaceEnter(String str){
String reg ="[\n-\r]"; // String reg ="[\n-\r]";
Pattern p = Pattern.compile(reg); // Pattern p = Pattern.compile(reg);
Matcher m = p.matcher(str); // Matcher m = p.matcher(str);
return m.replaceAll(""); // return m.replaceAll("");
} // }
} //}

@ -16,7 +16,7 @@ zilberboot:
# 开发环境配置 # 开发环境配置
server: server:
# 服务器的HTTP端口,默认为8080 # 服务器的HTTP端口,默认为8080
port: 8080 port: 8081
servlet: servlet:
# 应用的访问路径 # 应用的访问路径
context-path: / context-path: /
@ -153,3 +153,14 @@ xss:
excludes: /system/notice excludes: /system/notice
# 匹配链接 # 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/* urlPatterns: /system/*,/monitor/*,/tool/*
zilber:
localtion: D:/
aliyun:
oss:
endpoint: oss-cn-beijing.aliyuncs.com
keyId: LTAI5t8p8JcfHgs1xsHDhbTS
keySecret: a2NgvAo2EXy4UbUTQm3xtirHSQbPiO
bucketName: zilber-public
module: upload

Loading…
Cancel
Save