代码优化
This commit is contained in:
parent
adc841020e
commit
748cb763ef
@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.qiwenshare</groupId>
|
||||
<artifactId>file</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.qiwenshare</groupId>
|
||||
<artifactId>file-common</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.junrar</groupId>
|
||||
<artifactId>junrar</artifactId>
|
||||
<version>7.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>commons-fileupload</groupId>-->
|
||||
<!-- <artifactId>commons-fileupload</artifactId>-->
|
||||
<!-- <version>1.3.3</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!--图片压缩-->
|
||||
<dependency>
|
||||
<groupId>net.coobird</groupId>
|
||||
<artifactId>thumbnailator</artifactId>
|
||||
<version>0.4.13</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>3.10.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<version>0.9.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.tobato</groupId>
|
||||
<artifactId>fastdfs-client</artifactId>
|
||||
<version>1.26.2</version>
|
||||
</dependency>
|
||||
|
||||
<!--redis-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
@ -1,11 +0,0 @@
|
||||
package com.qiwenshare.common.config;
|
||||
|
||||
import com.qiwenshare.common.domain.AliyunOSS;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AliyunConfig {
|
||||
private AliyunOSS oss = new AliyunOSS();
|
||||
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.qiwenshare.common.config;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.qiwenshare.common.util.PropertiesUtil;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
@Configuration
|
||||
public class PropertiesConfig {
|
||||
|
||||
@Resource
|
||||
private Environment env;
|
||||
|
||||
@PostConstruct
|
||||
public void setProperties() {
|
||||
PropertiesUtil.setEnvironment(env);
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package com.qiwenshare.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "qiwen-file")
|
||||
public class QiwenFileConfig {
|
||||
|
||||
private boolean shareMode;
|
||||
|
||||
private String storageType;
|
||||
private String cacheMode;
|
||||
private String localStoragePath;
|
||||
|
||||
private AliyunConfig aliyun = new AliyunConfig();
|
||||
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.qiwenshare.common.constant;
|
||||
|
||||
public class FileConstant {
|
||||
/**
|
||||
* 路径分隔符
|
||||
*/
|
||||
public static final String pathSeparator = "/";
|
||||
public static final int deleteFileRandomSize = 999999;
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.qiwenshare.common.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AliyunOSS {
|
||||
|
||||
private String endpoint;
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
private String bucketName;
|
||||
private String objectName;
|
||||
private String domain;
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.qiwenshare.common.exception;
|
||||
|
||||
public class NotLoginException extends RuntimeException{
|
||||
public NotLoginException() {
|
||||
super("未登录");
|
||||
}
|
||||
public NotLoginException(Throwable cause) {
|
||||
super("未登录", cause);
|
||||
}
|
||||
|
||||
public NotLoginException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotLoginException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.qiwenshare.common.exception;
|
||||
|
||||
public class NotSameFileExpection extends Exception {
|
||||
public NotSameFileExpection() {
|
||||
super("File MD5 Different");
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.qiwenshare.common.exception;
|
||||
|
||||
public abstract class UploadException extends RuntimeException{
|
||||
|
||||
protected UploadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
protected UploadException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package com.qiwenshare.common.exception;
|
||||
|
||||
public class UploadGeneralException extends UploadException{
|
||||
|
||||
public UploadGeneralException(Throwable cause) {
|
||||
super("上传出现了异常", cause);
|
||||
}
|
||||
|
||||
public UploadGeneralException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public UploadGeneralException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package com.qiwenshare.common.factory;
|
||||
|
||||
|
||||
import com.qiwenshare.common.operation.delete.Deleter;
|
||||
import com.qiwenshare.common.operation.delete.product.AliyunOSSDeleter;
|
||||
|
||||
import com.qiwenshare.common.operation.download.Downloader;
|
||||
import com.qiwenshare.common.operation.download.product.AliyunOSSDownloader;
|
||||
import com.qiwenshare.common.operation.upload.Uploader;
|
||||
import com.qiwenshare.common.operation.upload.product.AliyunOSSUploader;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Component
|
||||
public class AliyunOSSOperationFactory implements FileOperationFactory {
|
||||
@Resource
|
||||
AliyunOSSUploader aliyunOSSUploader;
|
||||
@Resource
|
||||
AliyunOSSDownloader aliyunOSSDownloader;
|
||||
@Resource
|
||||
AliyunOSSDeleter aliyunOSSDeleter;
|
||||
@Override
|
||||
public Uploader getUploader() {
|
||||
return aliyunOSSUploader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Downloader getDownloader() {
|
||||
return aliyunOSSDownloader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deleter getDeleter() {
|
||||
return aliyunOSSDeleter;
|
||||
}
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.qiwenshare.common.factory;
|
||||
|
||||
import com.qiwenshare.common.operation.delete.Deleter;
|
||||
import com.qiwenshare.common.operation.delete.product.FastDFSDeleter;
|
||||
import com.qiwenshare.common.operation.download.Downloader;
|
||||
import com.qiwenshare.common.operation.download.product.FastDFSDownloader;
|
||||
import com.qiwenshare.common.operation.upload.Uploader;
|
||||
import com.qiwenshare.common.operation.upload.product.FastDFSUploader;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Component
|
||||
public class FastDFSOperationFactory implements FileOperationFactory {
|
||||
|
||||
@Resource
|
||||
FastDFSUploader fastDFSUploader;
|
||||
@Resource
|
||||
FastDFSDownloader fastDFSDownloader;
|
||||
@Resource
|
||||
FastDFSDeleter fastDFSDeleter;
|
||||
@Override
|
||||
public Uploader getUploader() {
|
||||
return fastDFSUploader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Downloader getDownloader() {
|
||||
return fastDFSDownloader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deleter getDeleter() {
|
||||
return fastDFSDeleter;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.qiwenshare.common.factory;
|
||||
|
||||
import com.qiwenshare.common.operation.delete.Deleter;
|
||||
import com.qiwenshare.common.operation.download.Downloader;
|
||||
import com.qiwenshare.common.operation.upload.Uploader;
|
||||
|
||||
public interface FileOperationFactory {
|
||||
Uploader getUploader();
|
||||
Downloader getDownloader();
|
||||
Deleter getDeleter();
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.qiwenshare.common.factory;
|
||||
|
||||
import com.qiwenshare.common.operation.delete.Deleter;
|
||||
import com.qiwenshare.common.operation.delete.product.LocalStorageDeleter;
|
||||
import com.qiwenshare.common.operation.download.Downloader;
|
||||
import com.qiwenshare.common.operation.download.product.LocalStorageDownloader;
|
||||
import com.qiwenshare.common.operation.upload.product.LocalStorageUploader;
|
||||
import com.qiwenshare.common.operation.upload.Uploader;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Component
|
||||
public class LocalStorageOperationFactory implements FileOperationFactory{
|
||||
|
||||
@Resource
|
||||
LocalStorageUploader localStorageUploader;
|
||||
@Resource
|
||||
LocalStorageDownloader localStorageDownloader;
|
||||
@Resource
|
||||
LocalStorageDeleter localStorageDeleter;
|
||||
@Override
|
||||
public Uploader getUploader() {
|
||||
return localStorageUploader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Downloader getDownloader() {
|
||||
return localStorageDownloader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deleter getDeleter() {
|
||||
return localStorageDeleter;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,425 +0,0 @@
|
||||
package com.qiwenshare.common.operation;
|
||||
|
||||
import com.github.junrar.Archive;
|
||||
import com.github.junrar.rarfile.FileHeader;
|
||||
import com.qiwenshare.common.util.FileUtil;
|
||||
import com.qiwenshare.common.util.PathUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* 文件操作
|
||||
*/
|
||||
@Slf4j
|
||||
public class FileOperation {
|
||||
private static Logger logger = LoggerFactory.getLogger(FileOperation.class);
|
||||
private static Executor executor = Executors.newFixedThreadPool(20);
|
||||
/**
|
||||
* 创建文件
|
||||
*
|
||||
* @param fileUrl 文件路径
|
||||
* @return 新文件
|
||||
*/
|
||||
public static File newFile(String fileUrl) {
|
||||
File file = new File(fileUrl);
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param file 文件
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
public static boolean deleteFile(File file) {
|
||||
if (file == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file.exists()) {
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (file.isFile()) {
|
||||
return file.delete();
|
||||
} else {
|
||||
for (File newfile : file.listFiles()) {
|
||||
deleteFile(newfile);
|
||||
}
|
||||
}
|
||||
return file.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param fileUrl 文件路径
|
||||
* @return 删除是否成功
|
||||
*/
|
||||
public static boolean deleteFile(String fileUrl) {
|
||||
File file = newFile(fileUrl);
|
||||
return deleteFile(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到文件大小
|
||||
*
|
||||
* @param fileUrl 文件路径
|
||||
* @return 文件大小
|
||||
*/
|
||||
public static long getFileSize(String fileUrl) {
|
||||
File file = newFile(fileUrl);
|
||||
if (file.exists()) {
|
||||
return file.length();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到文件大小
|
||||
*
|
||||
* @param file 文件
|
||||
* @return 文件大小
|
||||
*/
|
||||
public static long getFileSize(File file) {
|
||||
if (file == null) {
|
||||
return 0;
|
||||
}
|
||||
return file.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建目录
|
||||
*
|
||||
* @param file 文件
|
||||
* @return 是否创建成功
|
||||
*/
|
||||
public static boolean mkdir(File file) {
|
||||
if (file == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.exists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return file.mkdirs();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建目录
|
||||
*
|
||||
* @param fileUrl 文件路径
|
||||
* @return 是否创建成功
|
||||
*/
|
||||
public static boolean mkdir(String fileUrl) {
|
||||
if (fileUrl == null) {
|
||||
return false;
|
||||
}
|
||||
File file = newFile(fileUrl);
|
||||
if (file.exists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return file.mkdirs();
|
||||
}
|
||||
|
||||
/**
|
||||
* 拷贝文件
|
||||
*
|
||||
* @param fileInputStream 文件输入流
|
||||
* @param fileOutputStream 文件输出流
|
||||
* @throws IOException io异常
|
||||
*/
|
||||
public static void copyFile(FileInputStream fileInputStream, FileOutputStream fileOutputStream) throws IOException {
|
||||
try {
|
||||
byte[] buf = new byte[4096]; //8k的缓冲区
|
||||
|
||||
int len = fileInputStream.read(buf); //数据在buf中,len代表向buf中放了多少个字节的数据,-1代表读不到
|
||||
while (len != -1) {
|
||||
|
||||
fileOutputStream.write(buf, 0, len); //读多少个字节,写多少个字节
|
||||
|
||||
len = fileInputStream.read(buf);
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (fileInputStream != null) {
|
||||
try {
|
||||
fileInputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (fileOutputStream != null) {
|
||||
try {
|
||||
fileOutputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 拷贝文件
|
||||
*
|
||||
* @param src 源文件
|
||||
* @param dest 目的文件
|
||||
* @throws IOException io异常
|
||||
*/
|
||||
public static void copyFile(File src, File dest) throws IOException {
|
||||
FileInputStream in = new FileInputStream(src);
|
||||
FileOutputStream out = new FileOutputStream(dest);
|
||||
|
||||
copyFile(in, out);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 拷贝文件
|
||||
*
|
||||
* @param srcUrl 源路径
|
||||
* @param destUrl 目的路径
|
||||
* @throws IOException io异常
|
||||
*/
|
||||
public static void copyFile(String srcUrl, String destUrl) throws IOException {
|
||||
if (srcUrl == null || destUrl == null) {
|
||||
return;
|
||||
}
|
||||
File srcFile = newFile(srcUrl);
|
||||
File descFile = newFile(destUrl);
|
||||
copyFile(srcFile, descFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件解压缩
|
||||
*
|
||||
* @param sourceFile 需要解压的文件
|
||||
* @param destDirPath 目的路径
|
||||
* @return 解压目录列表
|
||||
*/
|
||||
public static List<String> unzip(File sourceFile, String destDirPath) {
|
||||
ZipFile zipFile = null;
|
||||
Set<String> set = new HashSet<String>();
|
||||
// set.add("/");
|
||||
List<String> fileEntryNameList = new ArrayList<>();
|
||||
try {
|
||||
zipFile = new ZipFile(sourceFile, Charset.forName("GBK"));
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = (ZipEntry) entries.nextElement();
|
||||
|
||||
String[] nameStrArr = entry.getName().split("/");
|
||||
|
||||
String nameStr = "/";
|
||||
for (int i = 0; i < nameStrArr.length; i++) {
|
||||
if (!"".equals(nameStrArr[i])) {
|
||||
nameStr = nameStr + "/" + nameStrArr[i];
|
||||
set.add(nameStr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logger.info("解压" + entry.getName());
|
||||
String zipPath = "/" + entry.getName();
|
||||
|
||||
|
||||
fileEntryNameList.add(zipPath);
|
||||
//如果是文件夹,就创建个文件夹
|
||||
if (entry.isDirectory()) {
|
||||
String dirPath = destDirPath + File.separator + entry.getName();
|
||||
File dir = FileOperation.newFile(dirPath);
|
||||
|
||||
dir.mkdir();
|
||||
} else {
|
||||
//如果是文件,就先创建一个文件,然后用io流把内容拷过去
|
||||
File targetFile = new File(destDirPath + "/" + entry.getName());
|
||||
// 保证这个文件的父文件夹必须要存在
|
||||
if (!targetFile.getParentFile().exists()) {
|
||||
targetFile.getParentFile().mkdirs();
|
||||
}
|
||||
targetFile.createNewFile();
|
||||
// 将压缩文件内容写入到这个文件中
|
||||
InputStream is = null;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
is = zipFile.getInputStream(entry);
|
||||
fos = new FileOutputStream(targetFile);
|
||||
int len;
|
||||
byte[] buf = new byte[2048];
|
||||
while ((len = is.read(buf)) != -1) {
|
||||
fos.write(buf, 0, len);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 关流顺序,先打开的后关闭
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (Exception e1) {
|
||||
log.error("关闭流失败:" + e1);
|
||||
}
|
||||
|
||||
}
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (Exception e2) {
|
||||
log.error("关闭流失败:" + e2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("unzip error from ZipUtils", e);
|
||||
} finally {
|
||||
if (zipFile != null) {
|
||||
try {
|
||||
zipFile.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String zipPath : fileEntryNameList) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (FileUtil.isImageFile(FileUtil.getFileExtendName(zipPath))) {
|
||||
File file = new File(destDirPath + zipPath);
|
||||
File minFile = new File(destDirPath + FileUtil.getFileNameNotExtend(zipPath) + "_min." + FileUtil.getFileExtendName(zipPath));
|
||||
try {
|
||||
ImageOperation.thumbnailsImage(file, minFile, 300);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
List<String> res = new ArrayList<>(set);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解压rar
|
||||
*
|
||||
* @param sourceFile 需要解压的文件
|
||||
* @param destDirPath 目的路径
|
||||
* @throws Exception
|
||||
*/
|
||||
public static List<String> unrar(File sourceFile, String destDirPath) throws Exception {
|
||||
File destDir = new File(destDirPath);
|
||||
Set<String> set = new HashSet<String>();
|
||||
Archive archive = null;
|
||||
FileOutputStream fos = null;
|
||||
System.out.println("Starting 开始解压...");
|
||||
try {
|
||||
archive = new Archive(sourceFile);
|
||||
FileHeader fh = archive.nextFileHeader();
|
||||
int count = 0;
|
||||
File destFileName = null;
|
||||
while (fh != null) {
|
||||
set.add("/" + fh.getFileName());
|
||||
System.out.println((++count) + ") " + fh.getFileName());
|
||||
String compressFileName = fh.getFileName().trim();
|
||||
destFileName = new File(destDir.getAbsolutePath() + "/" + compressFileName);
|
||||
if (fh.isDirectory()) {
|
||||
if (!destFileName.exists()) {
|
||||
destFileName.mkdirs();
|
||||
}
|
||||
fh = archive.nextFileHeader();
|
||||
continue;
|
||||
}
|
||||
if (!destFileName.getParentFile().exists()) {
|
||||
destFileName.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
|
||||
fos = new FileOutputStream(destFileName);
|
||||
archive.extractFile(fh, fos);
|
||||
fos.close();
|
||||
fos = null;
|
||||
fh = archive.nextFileHeader();
|
||||
}
|
||||
|
||||
archive.close();
|
||||
archive = null;
|
||||
System.out.println("Finished 解压完成!");
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (Exception e) {
|
||||
log.error("关闭流失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
if (archive != null) {
|
||||
try {
|
||||
archive.close();
|
||||
} catch (Exception e) {
|
||||
log.error("关闭流失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (String zipPath : set) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (FileUtil.isImageFile(FileUtil.getFileExtendName(zipPath))) {
|
||||
File file = new File(destDirPath + zipPath);
|
||||
File minFile = new File(destDirPath + FileUtil.getFileNameNotExtend(zipPath) + "_min." + FileUtil.getFileExtendName(zipPath));
|
||||
try {
|
||||
ImageOperation.thumbnailsImage(file, minFile, 300);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
List<String> res = new ArrayList<>(set);
|
||||
return res;
|
||||
}
|
||||
|
||||
public static long deleteFileFromDisk(String fileurl) {
|
||||
String fileUrl = PathUtil.getStaticPath() + fileurl;
|
||||
String extendName = FileUtil.getFileExtendName(fileUrl);
|
||||
String minFileUrl = fileUrl.replace("." + extendName, "_min." + extendName);
|
||||
long filesize = getFileSize(fileUrl);
|
||||
|
||||
FileOperation.deleteFile(fileUrl);
|
||||
FileOperation.deleteFile(minFileUrl);
|
||||
|
||||
return filesize;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.qiwenshare.common.operation;
|
||||
|
||||
import net.coobird.thumbnailator.Thumbnails;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ImageOperation {
|
||||
/**
|
||||
* 左旋
|
||||
* @param inFile 源文件
|
||||
* @param outFile 目的文件
|
||||
* @param angle 角度
|
||||
* @throws IOException io异常
|
||||
*/
|
||||
public static void leftTotation(File inFile, File outFile, int angle) throws IOException {
|
||||
Thumbnails.of(inFile).scale(1).outputQuality(1).rotate(-angle).toFile(outFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 右旋
|
||||
* @param inFile 源文件
|
||||
* @param outFile 目的文件
|
||||
* @param angle 角度
|
||||
* @throws IOException io异常
|
||||
*/
|
||||
public static void rightTotation(File inFile, File outFile, int angle) throws IOException {
|
||||
Thumbnails.of(inFile).scale(1).outputQuality(1).rotate(angle).toFile(outFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 压缩
|
||||
* @param inFile 源文件
|
||||
* @param outFile 目的文件
|
||||
* @throws IOException io异常
|
||||
*/
|
||||
public static void thumbnailsImage(File inFile, File outFile, int imageSize) throws IOException {
|
||||
|
||||
Thumbnails.of(inFile).size(imageSize, imageSize)
|
||||
.toFile(outFile);
|
||||
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.qiwenshare.common.operation.delete;
|
||||
|
||||
import com.qiwenshare.common.operation.delete.domain.DeleteFile;
|
||||
|
||||
public abstract class Deleter {
|
||||
public abstract void delete(DeleteFile deleteFile);
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.qiwenshare.common.operation.delete.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DeleteFile {
|
||||
private String fileUrl;
|
||||
private String timeStampName;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package com.qiwenshare.common.operation.delete.product;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.qiwenshare.common.config.QiwenFileConfig;
|
||||
import com.qiwenshare.common.operation.delete.Deleter;
|
||||
import com.qiwenshare.common.operation.delete.domain.DeleteFile;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Component
|
||||
public class AliyunOSSDeleter extends Deleter {
|
||||
@Resource
|
||||
QiwenFileConfig qiwenFileConfig;
|
||||
@Override
|
||||
public void delete(DeleteFile deleteFile) {
|
||||
String endpoint = qiwenFileConfig.getAliyun().getOss().getEndpoint();
|
||||
String accessKeyId = qiwenFileConfig.getAliyun().getOss().getAccessKeyId();
|
||||
String accessKeySecret = qiwenFileConfig.getAliyun().getOss().getAccessKeySecret();
|
||||
String bucketName = qiwenFileConfig.getAliyun().getOss().getBucketName();
|
||||
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
|
||||
|
||||
ossClient.deleteObject(bucketName, deleteFile.getFileUrl().substring(1));
|
||||
|
||||
|
||||
|
||||
// 关闭OSSClient。
|
||||
ossClient.shutdown();
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.qiwenshare.common.operation.delete.product;
|
||||
|
||||
import com.github.tobato.fastdfs.service.FastFileStorageClient;
|
||||
import com.qiwenshare.common.operation.delete.Deleter;
|
||||
import com.qiwenshare.common.operation.delete.domain.DeleteFile;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class FastDFSDeleter extends Deleter {
|
||||
@Autowired
|
||||
private FastFileStorageClient fastFileStorageClient;
|
||||
@Override
|
||||
public void delete(DeleteFile deleteFile) {
|
||||
fastFileStorageClient.deleteFile(deleteFile.getFileUrl().replace("M00", "group1"));
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.qiwenshare.common.operation.delete.product;
|
||||
|
||||
import com.qiwenshare.common.operation.delete.Deleter;
|
||||
import com.qiwenshare.common.operation.delete.domain.DeleteFile;
|
||||
import com.qiwenshare.common.operation.FileOperation;
|
||||
import com.qiwenshare.common.util.FileUtil;
|
||||
import com.qiwenshare.common.util.PathUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class LocalStorageDeleter extends Deleter {
|
||||
@Override
|
||||
public void delete(DeleteFile deleteFile) {
|
||||
FileOperation.deleteFile(PathUtil.getStaticPath() + deleteFile.getFileUrl());
|
||||
if (FileUtil.isImageFile(FileUtil.getFileExtendName(deleteFile.getFileUrl()))) {
|
||||
FileOperation.deleteFile(PathUtil.getStaticPath() + deleteFile.getFileUrl().replace(deleteFile.getTimeStampName(), deleteFile.getTimeStampName() + "_min"));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.qiwenshare.common.operation.download;
|
||||
|
||||
import com.qiwenshare.common.operation.download.domain.DownloadFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.InputStream;
|
||||
|
||||
public abstract class Downloader {
|
||||
public abstract void download(HttpServletResponse httpServletResponse, DownloadFile uploadFile);
|
||||
public abstract InputStream getInputStream(DownloadFile downloadFile);
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.qiwenshare.common.operation.download.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DownloadFile {
|
||||
private String fileUrl;
|
||||
// private String timeStampName;
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
package com.qiwenshare.common.operation.download.product;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.model.OSSObject;
|
||||
import com.qiwenshare.common.config.QiwenFileConfig;
|
||||
import com.qiwenshare.common.domain.AliyunOSS;
|
||||
import com.qiwenshare.common.operation.download.domain.DownloadFile;
|
||||
import com.qiwenshare.common.operation.download.Downloader;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
@Component
|
||||
public class AliyunOSSDownloader extends Downloader {
|
||||
@Resource
|
||||
QiwenFileConfig qiwenFileConfig;
|
||||
@Override
|
||||
public void download(HttpServletResponse httpServletResponse, DownloadFile downloadFile) {
|
||||
|
||||
BufferedInputStream bis = null;
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
OSS ossClient = createOSSClient(qiwenFileConfig.getAliyun().getOss());
|
||||
OSSObject ossObject = ossClient.getObject(qiwenFileConfig.getAliyun().getOss().getBucketName(),
|
||||
downloadFile.getFileUrl().substring(1));
|
||||
InputStream inputStream = ossObject.getObjectContent();
|
||||
try {
|
||||
bis = new BufferedInputStream(inputStream);
|
||||
OutputStream os = httpServletResponse.getOutputStream();
|
||||
int i = bis.read(buffer);
|
||||
while (i != -1) {
|
||||
os.write(buffer, 0, i);
|
||||
i = bis.read(buffer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (bis != null) {
|
||||
try {
|
||||
bis.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ossClient.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream(DownloadFile downloadFile) {
|
||||
OSS ossClient = createOSSClient(qiwenFileConfig.getAliyun().getOss());
|
||||
OSSObject ossObject = ossClient.getObject(qiwenFileConfig.getAliyun().getOss().getBucketName(),
|
||||
downloadFile.getFileUrl().substring(1));
|
||||
InputStream inputStream = ossObject.getObjectContent();
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
public OSS createOSSClient(AliyunOSS aliyunOSS) {
|
||||
String endpoint = aliyunOSS.getEndpoint();
|
||||
String accessKeyId = aliyunOSS.getAccessKeyId();
|
||||
String accessKeySecret = aliyunOSS.getAccessKeySecret();
|
||||
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
|
||||
return ossClient;
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package com.qiwenshare.common.operation.download.product;
|
||||
|
||||
import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
|
||||
import com.github.tobato.fastdfs.service.FastFileStorageClient;
|
||||
import com.qiwenshare.common.operation.download.domain.DownloadFile;
|
||||
import com.qiwenshare.common.operation.download.Downloader;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@Component
|
||||
public class FastDFSDownloader extends Downloader {
|
||||
@Autowired
|
||||
private FastFileStorageClient fastFileStorageClient;
|
||||
@Override
|
||||
public void download(HttpServletResponse httpServletResponse, DownloadFile downloadFile) {
|
||||
String group = downloadFile.getFileUrl().substring(0, downloadFile.getFileUrl().indexOf("/"));
|
||||
group = "group1";
|
||||
String path = downloadFile.getFileUrl().substring(downloadFile.getFileUrl().indexOf("/") + 1);
|
||||
DownloadByteArray downloadByteArray = new DownloadByteArray();
|
||||
|
||||
|
||||
ServletOutputStream outputStream = null;
|
||||
try {
|
||||
outputStream = httpServletResponse.getOutputStream();
|
||||
byte[] bytes = fastFileStorageClient.downloadFile(group, path, downloadByteArray);
|
||||
outputStream.write(bytes);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (outputStream != null) {
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream(DownloadFile downloadFile) {
|
||||
String group = downloadFile.getFileUrl().substring(0, downloadFile.getFileUrl().indexOf("/"));
|
||||
group = "group1";
|
||||
String path = downloadFile.getFileUrl().substring(downloadFile.getFileUrl().indexOf("/") + 1);
|
||||
DownloadByteArray downloadByteArray = new DownloadByteArray();
|
||||
byte[] bytes = fastFileStorageClient.downloadFile(group, path, downloadByteArray);
|
||||
InputStream inputStream = new ByteArrayInputStream(bytes);
|
||||
return inputStream;
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package com.qiwenshare.common.operation.download.product;
|
||||
|
||||
import com.qiwenshare.common.operation.download.domain.DownloadFile;
|
||||
import com.qiwenshare.common.operation.FileOperation;
|
||||
import com.qiwenshare.common.operation.download.Downloader;
|
||||
import com.qiwenshare.common.util.PathUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
|
||||
@Component
|
||||
public class LocalStorageDownloader extends Downloader {
|
||||
@Override
|
||||
public void download(HttpServletResponse httpServletResponse, DownloadFile downloadFile) {
|
||||
BufferedInputStream bis = null;
|
||||
byte[] buffer = new byte[1024];
|
||||
//设置文件路径
|
||||
File file = FileOperation.newFile(PathUtil.getStaticPath() + downloadFile.getFileUrl());
|
||||
if (file.exists()) {
|
||||
|
||||
|
||||
FileInputStream fis = null;
|
||||
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
bis = new BufferedInputStream(fis);
|
||||
OutputStream os = httpServletResponse.getOutputStream();
|
||||
int i = bis.read(buffer);
|
||||
while (i != -1) {
|
||||
os.write(buffer, 0, i);
|
||||
i = bis.read(buffer);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (bis != null) {
|
||||
try {
|
||||
bis.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream(DownloadFile downloadFile) {
|
||||
//设置文件路径
|
||||
File file = FileOperation.newFile(PathUtil.getStaticPath() + downloadFile.getFileUrl());
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(file);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return inputStream;
|
||||
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package com.qiwenshare.common.operation.upload;
|
||||
|
||||
import com.qiwenshare.common.operation.upload.domain.UploadFile;
|
||||
import com.qiwenshare.common.util.PathUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public abstract class Uploader {
|
||||
|
||||
|
||||
public static final String ROOT_PATH = "upload";
|
||||
public static final String FILE_SEPARATOR = "/";
|
||||
// 文件大小限制,单位KB
|
||||
public final int maxSize = 10000000;
|
||||
|
||||
public abstract List<UploadFile> upload(HttpServletRequest request, UploadFile uploadFile);
|
||||
|
||||
/**
|
||||
* 获取本地文件保存路径
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected String getLocalFileSavePath() {
|
||||
|
||||
String path = ROOT_PATH;
|
||||
SimpleDateFormat formater = new SimpleDateFormat("yyyyMMdd");
|
||||
path = FILE_SEPARATOR + path + FILE_SEPARATOR + formater.format(new Date());
|
||||
|
||||
String staticPath = PathUtil.getStaticPath();
|
||||
|
||||
File dir = new File(staticPath + path);
|
||||
//LOG.error(PathUtil.getStaticPath() + path);
|
||||
if (!dir.exists()) {
|
||||
try {
|
||||
boolean isSuccessMakeDir = dir.mkdirs();
|
||||
if (!isSuccessMakeDir) {
|
||||
log.error("目录创建失败:" + PathUtil.getStaticPath() + path);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("目录创建失败" + PathUtil.getStaticPath() + path);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 依据原始文件名生成新文件名
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected String getTimeStampName() {
|
||||
try {
|
||||
SecureRandom number = SecureRandom.getInstance("SHA1PRNG");
|
||||
return "" + number.nextInt(10000)
|
||||
+ System.currentTimeMillis();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
log.error("生成安全随机数失败");
|
||||
}
|
||||
return ""
|
||||
+ System.currentTimeMillis();
|
||||
|
||||
}
|
||||
|
||||
public synchronized boolean checkUploadStatus(UploadFile param, File confFile) throws IOException {
|
||||
RandomAccessFile confAccessFile = new RandomAccessFile(confFile, "rw");
|
||||
//设置文件长度
|
||||
confAccessFile.setLength(param.getTotalChunks());
|
||||
//设置起始偏移量
|
||||
confAccessFile.seek(param.getChunkNumber() - 1);
|
||||
//将指定的一个字节写入文件中 127,
|
||||
confAccessFile.write(Byte.MAX_VALUE);
|
||||
byte[] completeStatusList = FileUtils.readFileToByteArray(confFile);
|
||||
confAccessFile.close();//不关闭会造成无法占用
|
||||
//创建conf文件文件长度为总分片数,每上传一个分块即向conf文件中写入一个127,那么没上传的位置就是默认的0,已上传的就是127
|
||||
for (int i = 0; i < completeStatusList.length; i++) {
|
||||
if (completeStatusList[i] != Byte.MAX_VALUE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
confFile.delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected String getFileName(String fileName){
|
||||
if (!fileName.contains(".")) {
|
||||
return fileName;
|
||||
}
|
||||
return fileName.substring(0, fileName.lastIndexOf("."));
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package com.qiwenshare.common.operation.upload.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UploadFile {
|
||||
private String fileName;
|
||||
private String fileType;
|
||||
private long fileSize;
|
||||
private String timeStampName;
|
||||
private int success;
|
||||
private String message;
|
||||
private String url;
|
||||
@Deprecated
|
||||
private Integer isOSS;
|
||||
private Integer storageType;
|
||||
//切片上传相关参数
|
||||
private String taskId;
|
||||
private int chunkNumber;
|
||||
private long chunkSize;
|
||||
private int totalChunks;
|
||||
private String identifier;
|
||||
private long totalSize;
|
||||
private long currentChunkSize;
|
||||
|
||||
|
||||
}
|
@ -1,224 +0,0 @@
|
||||
package com.qiwenshare.common.operation.upload.product;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.model.*;
|
||||
import com.qiwenshare.common.config.QiwenFileConfig;
|
||||
import com.qiwenshare.common.operation.upload.domain.UploadFile;
|
||||
import com.qiwenshare.common.exception.UploadGeneralException;
|
||||
import com.qiwenshare.common.operation.upload.Uploader;
|
||||
import com.qiwenshare.common.util.FileUtil;
|
||||
import com.qiwenshare.common.util.PathUtil;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
//import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AliyunOSSUploader extends Uploader {
|
||||
@Resource
|
||||
QiwenFileConfig qiwenFileConfig;
|
||||
|
||||
|
||||
// partETags是PartETag的集合。PartETag由分片的ETag和分片号组成。
|
||||
public static Map<String, List<PartETag>> partETagsMap = new HashMap<String, List<PartETag>>();
|
||||
public static Map<String, UploadFileInfo> uploadPartRequestMap = new HashMap<>();
|
||||
|
||||
public static Map<String, OSS> ossMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public List<UploadFile> upload(HttpServletRequest httpServletRequest, UploadFile uploadFile) {
|
||||
log.info("开始上传upload");
|
||||
|
||||
List<UploadFile> saveUploadFileList = new ArrayList<>();
|
||||
StandardMultipartHttpServletRequest request = (StandardMultipartHttpServletRequest) httpServletRequest;
|
||||
|
||||
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
|
||||
if (!isMultipart) {
|
||||
throw new UploadGeneralException("未包含文件上传域");
|
||||
}
|
||||
|
||||
Iterator<String> iter = request.getFileNames();
|
||||
while (iter.hasNext()) {
|
||||
|
||||
saveUploadFileList = doUpload(request, iter, uploadFile);
|
||||
}
|
||||
|
||||
|
||||
log.info("结束上传");
|
||||
return saveUploadFileList;
|
||||
}
|
||||
|
||||
private List<UploadFile> doUpload(StandardMultipartHttpServletRequest standardMultipartHttpServletRequest, Iterator<String> iter, UploadFile uploadFile) {
|
||||
String savePath = getLocalFileSavePath();
|
||||
OSS ossClient = getClient(uploadFile);
|
||||
|
||||
List<UploadFile> saveUploadFileList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
MultipartFile multipartfile = standardMultipartHttpServletRequest.getFile(iter.next());
|
||||
|
||||
String timeStampName = getTimeStampName();
|
||||
String originalName = multipartfile.getOriginalFilename();
|
||||
String fileName = getFileName(originalName);
|
||||
String fileType = FileUtil.getFileExtendName(originalName);
|
||||
uploadFile.setFileName(fileName);
|
||||
uploadFile.setFileType(fileType);
|
||||
uploadFile.setTimeStampName(timeStampName);
|
||||
|
||||
String ossFilePath = savePath + FILE_SEPARATOR + timeStampName + FILE_SEPARATOR + fileName + "." + fileType;
|
||||
String confFilePath = savePath + FILE_SEPARATOR + uploadFile.getIdentifier() + "." + "conf";
|
||||
File confFile = new File(PathUtil.getStaticPath() + FILE_SEPARATOR + confFilePath);
|
||||
|
||||
synchronized (AliyunOSSUploader.class) {
|
||||
if (uploadPartRequestMap.get(uploadFile.getIdentifier()) == null) {
|
||||
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(qiwenFileConfig.getAliyun().getOss().getBucketName(), ossFilePath.substring(1));
|
||||
InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
|
||||
String uploadId = upresult.getUploadId();
|
||||
|
||||
UploadFileInfo uploadPartRequest = new UploadFileInfo();
|
||||
uploadPartRequest.setBucketName(qiwenFileConfig.getAliyun().getOss().getBucketName());
|
||||
uploadPartRequest.setKey(ossFilePath.substring(1));
|
||||
uploadPartRequest.setUploadId(uploadId);
|
||||
uploadPartRequestMap.put(uploadFile.getIdentifier(), uploadPartRequest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UploadFileInfo uploadFileInfo = uploadPartRequestMap.get(uploadFile.getIdentifier());
|
||||
UploadPartRequest uploadPartRequest = new UploadPartRequest();
|
||||
uploadPartRequest.setBucketName(uploadFileInfo.getBucketName());
|
||||
uploadPartRequest.setKey(uploadFileInfo.getKey());
|
||||
uploadPartRequest.setUploadId(uploadFileInfo.getUploadId());
|
||||
uploadPartRequest.setInputStream(multipartfile.getInputStream());
|
||||
uploadPartRequest.setPartSize(uploadFile.getCurrentChunkSize());
|
||||
uploadPartRequest.setPartNumber(uploadFile.getChunkNumber());
|
||||
log.info(JSON.toJSONString(uploadPartRequest));
|
||||
|
||||
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
|
||||
synchronized (AliyunOSSUploader.class) {
|
||||
log.info("上传结果:" + JSON.toJSONString(uploadPartResult));
|
||||
if (partETagsMap.get(uploadFile.getIdentifier()) == null) {
|
||||
List<PartETag> partETags = new ArrayList<PartETag>();
|
||||
partETags.add(uploadPartResult.getPartETag());
|
||||
partETagsMap.put(uploadFile.getIdentifier(), partETags);
|
||||
} else {
|
||||
partETagsMap.get(uploadFile.getIdentifier()).add(uploadPartResult.getPartETag());
|
||||
}
|
||||
}
|
||||
|
||||
boolean isComplete = checkUploadStatus(uploadFile, confFile);
|
||||
if (isComplete) {
|
||||
log.info("分片上传完成");
|
||||
completeMultipartUpload(uploadFile);
|
||||
|
||||
uploadFile.setUrl("/" + uploadPartRequestMap.get(uploadFile.getIdentifier()).getKey());
|
||||
uploadFile.setSuccess(1);
|
||||
uploadFile.setMessage("上传成功");
|
||||
partETagsMap.remove(uploadFile.getIdentifier());
|
||||
uploadPartRequestMap.remove(uploadFile.getIdentifier());
|
||||
ossMap.remove(uploadFile.getIdentifier());
|
||||
} else {
|
||||
uploadFile.setSuccess(0);
|
||||
uploadFile.setMessage("未完成");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("上传出错:" + e);
|
||||
throw new UploadGeneralException(e);
|
||||
}
|
||||
|
||||
uploadFile.setIsOSS(1);
|
||||
uploadFile.setStorageType(1);
|
||||
|
||||
uploadFile.setFileSize(uploadFile.getTotalSize());
|
||||
saveUploadFileList.add(uploadFile);
|
||||
return saveUploadFileList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文件分块进行升序排序并执行文件上传。
|
||||
*/
|
||||
protected void completeMultipartUpload(UploadFile uploadFile) {
|
||||
|
||||
List<PartETag> partETags = partETagsMap.get(uploadFile.getIdentifier());
|
||||
Collections.sort(partETags, Comparator.comparingInt(PartETag::getPartNumber));
|
||||
UploadFileInfo uploadFileInfo = uploadPartRequestMap.get(uploadFile.getIdentifier());
|
||||
CompleteMultipartUploadRequest completeMultipartUploadRequest =
|
||||
new CompleteMultipartUploadRequest(qiwenFileConfig.getAliyun().getOss().getBucketName(),
|
||||
uploadFileInfo.getKey(),
|
||||
uploadFileInfo.getUploadId(),
|
||||
partETags);
|
||||
log.info("----:" + JSON.toJSONString(partETags));
|
||||
// 完成上传。
|
||||
CompleteMultipartUploadResult completeMultipartUploadResult = getClient(uploadFile).completeMultipartUpload(completeMultipartUploadRequest);
|
||||
log.info("----:" + JSON.toJSONString(completeMultipartUploadRequest));
|
||||
getClient(uploadFile).shutdown();
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
private void listFile(UploadFile uploadFile) {
|
||||
// 列举已上传的分片,其中uploadId来自于InitiateMultipartUpload返回的结果。
|
||||
ListPartsRequest listPartsRequest = new ListPartsRequest(qiwenFileConfig.getAliyun().getOss().getBucketName(), uploadPartRequestMap.get(uploadFile.getIdentifier()).getKey(), uploadPartRequestMap.get(uploadFile.getIdentifier()).getUploadId());
|
||||
// 设置uploadId。
|
||||
//listPartsRequest.setUploadId(uploadId);
|
||||
// 设置分页时每一页中分片数量为100个。默认列举1000个分片。
|
||||
listPartsRequest.setMaxParts(100);
|
||||
// 指定List的起始位置。只有分片号大于此参数值的分片会被列举。
|
||||
// listPartsRequest.setPartNumberMarker(1);
|
||||
PartListing partListing = getClient(uploadFile).listParts(listPartsRequest);
|
||||
|
||||
for (PartSummary part : partListing.getParts()) {
|
||||
log.info("分片号:"+part.getPartNumber() + ", 分片数据大小: "+
|
||||
part.getSize() + ",分片的ETag:"+part.getETag()
|
||||
+ ", 分片最后修改时间:"+ part.getLastModified());
|
||||
// 获取分片号。
|
||||
part.getPartNumber();
|
||||
// 获取分片数据大小。
|
||||
part.getSize();
|
||||
// 获取分片的ETag。
|
||||
part.getETag();
|
||||
// 获取分片的最后修改时间。
|
||||
part.getLastModified();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消上传
|
||||
*/
|
||||
private void cancelUpload(UploadFile uploadFile) {
|
||||
AbortMultipartUploadRequest abortMultipartUploadRequest =
|
||||
new AbortMultipartUploadRequest(qiwenFileConfig.getAliyun().getOss().getBucketName(), uploadPartRequestMap.get(uploadFile.getIdentifier()).getKey(), uploadPartRequestMap.get(uploadFile.getIdentifier()).getUploadId());
|
||||
getClient(uploadFile).abortMultipartUpload(abortMultipartUploadRequest);
|
||||
}
|
||||
|
||||
private synchronized OSS getClient(UploadFile uploadFile) {
|
||||
OSS ossClient = null;
|
||||
if (ossMap.get(uploadFile.getIdentifier()) == null) {
|
||||
ossClient = new OSSClientBuilder().build(qiwenFileConfig.getAliyun().getOss().getEndpoint(), qiwenFileConfig.getAliyun().getOss().getAccessKeyId(), qiwenFileConfig.getAliyun().getOss().getAccessKeySecret());
|
||||
ossMap.put(uploadFile.getIdentifier(), ossClient);
|
||||
} else {
|
||||
ossClient = ossMap.get(uploadFile.getIdentifier());
|
||||
}
|
||||
return ossClient;
|
||||
}
|
||||
|
||||
@Data
|
||||
public class UploadFileInfo {
|
||||
private String bucketName;
|
||||
private String key;
|
||||
private String uploadId;
|
||||
}
|
||||
|
||||
}
|
@ -1,186 +0,0 @@
|
||||
package com.qiwenshare.common.operation.upload.product;
|
||||
|
||||
import com.github.tobato.fastdfs.domain.StorePath;
|
||||
import com.github.tobato.fastdfs.service.AppendFileStorageClient;
|
||||
import com.qiwenshare.common.exception.UploadGeneralException;
|
||||
import com.qiwenshare.common.operation.upload.Uploader;
|
||||
import com.qiwenshare.common.operation.upload.domain.UploadFile;
|
||||
import com.qiwenshare.common.util.FileUtil;
|
||||
import com.qiwenshare.common.util.PathUtil;
|
||||
import com.qiwenshare.common.util.concurrent.locks.RedisLock;
|
||||
import com.qiwenshare.common.util.RedisUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FastDFSUploader extends Uploader {
|
||||
|
||||
@Resource
|
||||
AppendFileStorageClient defaultAppendFileStorageClient;
|
||||
@Resource
|
||||
RedisLock redisLock;
|
||||
@Resource
|
||||
RedisUtil redisUtil;
|
||||
|
||||
@Override
|
||||
public List<UploadFile> upload(HttpServletRequest request, UploadFile uploadFile) {
|
||||
|
||||
List<UploadFile> saveUploadFileList = new ArrayList<>();
|
||||
StandardMultipartHttpServletRequest standardMultipartHttpServletRequest = (StandardMultipartHttpServletRequest) request;
|
||||
|
||||
boolean isMultipart = ServletFileUpload.isMultipartContent(standardMultipartHttpServletRequest);
|
||||
if (!isMultipart) {
|
||||
throw new UploadGeneralException("未包含文件上传域");
|
||||
}
|
||||
|
||||
String savePath = getLocalFileSavePath();
|
||||
|
||||
try {
|
||||
|
||||
Iterator<String> iter = standardMultipartHttpServletRequest.getFileNames();
|
||||
while (iter.hasNext()) {
|
||||
saveUploadFileList = doUpload(standardMultipartHttpServletRequest, savePath, iter, uploadFile);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new UploadGeneralException(e);
|
||||
}
|
||||
|
||||
log.info("结束上传");
|
||||
return saveUploadFileList;
|
||||
}
|
||||
|
||||
|
||||
private List<UploadFile> doUpload(StandardMultipartHttpServletRequest standardMultipartHttpServletRequest, String savePath, Iterator<String> iter, UploadFile uploadFile) {
|
||||
|
||||
List<UploadFile> saveUploadFileList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
MultipartFile multipartfile = standardMultipartHttpServletRequest.getFile(iter.next());
|
||||
|
||||
uploadFileChunk(multipartfile, uploadFile);
|
||||
|
||||
String timeStampName = getTimeStampName();
|
||||
String originalName = multipartfile.getOriginalFilename();
|
||||
|
||||
String fileName = getFileName(originalName);
|
||||
|
||||
String fileType = FileUtil.getFileExtendName(originalName);
|
||||
uploadFile.setFileName(fileName);
|
||||
uploadFile.setFileType(fileType);
|
||||
uploadFile.setTimeStampName(timeStampName);
|
||||
|
||||
|
||||
String confFilePath = savePath + FILE_SEPARATOR + uploadFile.getIdentifier() + "." + "conf";
|
||||
File confFile = new File(PathUtil.getStaticPath() + FILE_SEPARATOR + confFilePath);
|
||||
|
||||
|
||||
boolean isComplete = checkUploadStatus(uploadFile, confFile);
|
||||
if (isComplete) {
|
||||
log.info("分片上传完成");
|
||||
String path = redisUtil.getObject(uploadFile.getIdentifier() + "_storage_path");
|
||||
uploadFile.setUrl(path);
|
||||
uploadFile.setSuccess(1);
|
||||
uploadFile.setMessage("上传成功");
|
||||
} else {
|
||||
uploadFile.setSuccess(0);
|
||||
uploadFile.setMessage("未完成");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new UploadGeneralException(e);
|
||||
}
|
||||
|
||||
uploadFile.setIsOSS(0);
|
||||
uploadFile.setStorageType(2);
|
||||
uploadFile.setFileSize(uploadFile.getTotalSize());
|
||||
saveUploadFileList.add(uploadFile);
|
||||
return saveUploadFileList;
|
||||
}
|
||||
|
||||
public void uploadFileChunk(MultipartFile multipartFile, UploadFile uploadFile) {
|
||||
redisLock.lock(uploadFile.getIdentifier());
|
||||
try {
|
||||
|
||||
if (redisUtil.getObject(uploadFile.getIdentifier() + "_current_upload_chunk_number") == null) {
|
||||
redisUtil.set(uploadFile.getIdentifier() + "_current_upload_chunk_number", 1, 1000 * 60 * 60);
|
||||
}
|
||||
|
||||
String currentUploadChunkNumber = redisUtil.getObject(uploadFile.getIdentifier() + "_current_upload_chunk_number");
|
||||
if (uploadFile.getChunkNumber() != Integer.parseInt(currentUploadChunkNumber)) {
|
||||
redisLock.unlock(uploadFile.getIdentifier());
|
||||
while (redisLock.tryLock(uploadFile.getIdentifier(), 300, TimeUnit.SECONDS)) {
|
||||
if (uploadFile.getChunkNumber() == Integer.parseInt(redisUtil.getObject(uploadFile.getIdentifier() + "_current_upload_chunk_number"))) {
|
||||
break;
|
||||
} else {
|
||||
redisLock.unlock(uploadFile.getIdentifier());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("***********开始上传第{}块**********", uploadFile.getChunkNumber());
|
||||
StorePath storePath = null;
|
||||
redisUtil.getIncr(uploadFile.getIdentifier() + "_current_upload_chunk_number");
|
||||
|
||||
if (uploadFile.getChunkNumber() <= 1) {
|
||||
log.info("上传第一块");
|
||||
|
||||
storePath = defaultAppendFileStorageClient.uploadAppenderFile("group1", multipartFile.getInputStream(),
|
||||
multipartFile.getSize(), FileUtil.getFileExtendName(multipartFile.getOriginalFilename()));
|
||||
// 记录第一个分片上传的大小
|
||||
redisUtil.set(uploadFile.getIdentifier() + "_uploaded_size", uploadFile.getCurrentChunkSize(), 1000 * 60 * 60);
|
||||
|
||||
log.info("第一块上传完成");
|
||||
if (storePath == null) {
|
||||
redisUtil.set(uploadFile.getIdentifier() + "_current_upload_chunk_number", uploadFile.getChunkNumber(), 1000 * 60 * 60);
|
||||
|
||||
log.info("获取远程文件路径出错");
|
||||
throw new UploadGeneralException("获取远程文件路径出错");
|
||||
}
|
||||
|
||||
redisUtil.set(uploadFile.getIdentifier() + "_storage_path", storePath.getPath(), 1000 * 60 * 60);
|
||||
|
||||
log.info("上传文件 result = {}", storePath.getPath());
|
||||
} else {
|
||||
log.info("正在上传第{}块:" , uploadFile.getChunkNumber());
|
||||
|
||||
String path = redisUtil.getObject(uploadFile.getIdentifier() + "_storage_path");
|
||||
|
||||
if (path == null) {
|
||||
log.error("无法获取已上传服务器文件地址");
|
||||
throw new UploadGeneralException("无法获取已上传服务器文件地址");
|
||||
}
|
||||
|
||||
String uploadedSizeStr = redisUtil.getObject(uploadFile.getIdentifier() + "_uploaded_size");
|
||||
Long alreadySize = Long.parseLong(uploadedSizeStr);
|
||||
|
||||
// 追加方式实际实用如果中途出错多次,可能会出现重复追加情况,这里改成修改模式,即时多次传来重复文件块,依然可以保证文件拼接正确
|
||||
defaultAppendFileStorageClient.modifyFile("group1", path, multipartFile.getInputStream(),
|
||||
multipartFile.getSize(), alreadySize);
|
||||
// 记录分片上传的大小
|
||||
redisUtil.set(uploadFile.getIdentifier() + "_uploaded_size", alreadySize + multipartFile.getSize(), 1000 * 60 * 60);
|
||||
|
||||
}
|
||||
log.info("***********第{}块上传成功**********", uploadFile.getChunkNumber());
|
||||
} catch (Exception e) {
|
||||
log.error("***********第{}块上传失败,自动重试**********", uploadFile.getChunkNumber());
|
||||
redisUtil.set(uploadFile.getIdentifier() + "_current_upload_chunk_number", uploadFile.getChunkNumber(), 1000 * 60 * 60);
|
||||
throw new UploadGeneralException("更新远程文件出错", e);
|
||||
} finally {
|
||||
redisLock.unlock(uploadFile.getIdentifier());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
package com.qiwenshare.common.operation.upload.product;
|
||||
|
||||
import com.qiwenshare.common.exception.NotSameFileExpection;
|
||||
import com.qiwenshare.common.operation.upload.domain.UploadFile;
|
||||
import com.qiwenshare.common.exception.UploadGeneralException;
|
||||
import com.qiwenshare.common.operation.ImageOperation;
|
||||
import com.qiwenshare.common.operation.upload.Uploader;
|
||||
import com.qiwenshare.common.util.FileUtil;
|
||||
import com.qiwenshare.common.util.PathUtil;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
//import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@Component
|
||||
public class LocalStorageUploader extends Uploader {
|
||||
|
||||
@Override
|
||||
public List<UploadFile> upload(HttpServletRequest httpServletRequest,UploadFile uploadFile) {
|
||||
List<UploadFile> saveUploadFileList = new ArrayList<UploadFile>();
|
||||
StandardMultipartHttpServletRequest standardMultipartHttpServletRequest = (StandardMultipartHttpServletRequest) httpServletRequest;
|
||||
boolean isMultipart = ServletFileUpload.isMultipartContent(standardMultipartHttpServletRequest);
|
||||
if (!isMultipart) {
|
||||
throw new UploadGeneralException("未包含文件上传域");
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Iterator<String> iter = standardMultipartHttpServletRequest.getFileNames();
|
||||
while (iter.hasNext()) {
|
||||
saveUploadFileList = doUpload(standardMultipartHttpServletRequest, iter, uploadFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UploadGeneralException("未包含文件上传域");
|
||||
} catch (NotSameFileExpection notSameFileExpection) {
|
||||
notSameFileExpection.printStackTrace();
|
||||
}
|
||||
return saveUploadFileList;
|
||||
}
|
||||
|
||||
private List<UploadFile> doUpload(StandardMultipartHttpServletRequest standardMultipartHttpServletRequest, Iterator<String> iter, UploadFile uploadFile) throws IOException, NotSameFileExpection {
|
||||
String savePath = getLocalFileSavePath();
|
||||
List<UploadFile> saveUploadFileList = new ArrayList<UploadFile>();
|
||||
MultipartFile multipartfile = standardMultipartHttpServletRequest.getFile(iter.next());
|
||||
|
||||
String timeStampName = uploadFile.getIdentifier();
|
||||
|
||||
String originalName = multipartfile.getOriginalFilename();
|
||||
|
||||
String fileName = getFileName(originalName);
|
||||
String fileType = FileUtil.getFileExtendName(originalName);
|
||||
uploadFile.setFileName(fileName);
|
||||
uploadFile.setFileType(fileType);
|
||||
uploadFile.setTimeStampName(timeStampName);
|
||||
|
||||
String saveFilePath = savePath + FILE_SEPARATOR + timeStampName + "." + fileType;
|
||||
String tempFilePath = savePath + FILE_SEPARATOR + timeStampName + "." + fileType + "_tmp";
|
||||
String minFilePath = savePath + FILE_SEPARATOR + timeStampName + "_min" + "." + fileType;
|
||||
String confFilePath = savePath + FILE_SEPARATOR + timeStampName + "." + "conf";
|
||||
File file = new File(PathUtil.getStaticPath() + FILE_SEPARATOR + saveFilePath);
|
||||
File tempFile = new File(PathUtil.getStaticPath() + FILE_SEPARATOR + tempFilePath);
|
||||
File minFile = new File(PathUtil.getStaticPath() + FILE_SEPARATOR + minFilePath);
|
||||
File confFile = new File(PathUtil.getStaticPath() + FILE_SEPARATOR + confFilePath);
|
||||
uploadFile.setIsOSS(0);
|
||||
uploadFile.setStorageType(0);
|
||||
uploadFile.setUrl(saveFilePath);
|
||||
|
||||
if (StringUtils.isEmpty(uploadFile.getTaskId())) {
|
||||
uploadFile.setTaskId(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
//第一步 打开将要写入的文件
|
||||
RandomAccessFile raf = new RandomAccessFile(tempFile, "rw");
|
||||
//第二步 打开通道
|
||||
FileChannel fileChannel = raf.getChannel();
|
||||
//第三步 计算偏移量
|
||||
long position = (uploadFile.getChunkNumber() - 1) * uploadFile.getChunkSize();
|
||||
//第四步 获取分片数据
|
||||
byte[] fileData = multipartfile.getBytes();
|
||||
//第五步 写入数据
|
||||
fileChannel.position(position);
|
||||
fileChannel.write(ByteBuffer.wrap(fileData));
|
||||
fileChannel.force(true);
|
||||
fileChannel.close();
|
||||
raf.close();
|
||||
//判断是否完成文件的传输并进行校验与重命名
|
||||
boolean isComplete = checkUploadStatus(uploadFile, confFile);
|
||||
if (isComplete) {
|
||||
FileInputStream fileInputStream = new FileInputStream(tempFile.getPath());
|
||||
String md5 = DigestUtils.md5Hex(fileInputStream);
|
||||
fileInputStream.close();
|
||||
if (StringUtils.isNotBlank(md5) && !md5.equals(uploadFile.getIdentifier())) {
|
||||
throw new NotSameFileExpection();
|
||||
}
|
||||
tempFile.renameTo(file);
|
||||
if (FileUtil.isImageFile(uploadFile.getFileType())){
|
||||
ImageOperation.thumbnailsImage(file, minFile, 300);
|
||||
}
|
||||
|
||||
uploadFile.setSuccess(1);
|
||||
uploadFile.setMessage("上传成功");
|
||||
} else {
|
||||
uploadFile.setSuccess(0);
|
||||
uploadFile.setMessage("未完成");
|
||||
}
|
||||
uploadFile.setFileSize(uploadFile.getTotalSize());
|
||||
saveUploadFileList.add(uploadFile);
|
||||
|
||||
return saveUploadFileList;
|
||||
}
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.qiwenshare.common.result;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 统一结果返回
|
||||
* @param <T>
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "统一结果返回",required = true)
|
||||
public class RestResult<T> {
|
||||
@Schema(description = "请求是否成功", example = "true")
|
||||
private Boolean success = true;
|
||||
@Schema(description = "返回码", example = "20000")
|
||||
private Integer code;
|
||||
@Schema(description = "返回信息", example = "成功")
|
||||
private String message;
|
||||
@Schema(description = "返回数据")
|
||||
private T data;
|
||||
|
||||
// 通用返回成功
|
||||
public static RestResult success() {
|
||||
RestResult r = new RestResult();
|
||||
r.setSuccess(ResultCodeEnum.SUCCESS.getSuccess());
|
||||
r.setCode(ResultCodeEnum.SUCCESS.getCode());
|
||||
r.setMessage(ResultCodeEnum.SUCCESS.getMessage());
|
||||
return r;
|
||||
}
|
||||
|
||||
// 通用返回失败,未知错误
|
||||
public static RestResult fail() {
|
||||
RestResult r = new RestResult();
|
||||
r.setSuccess(ResultCodeEnum.UNKNOWN_ERROR.getSuccess());
|
||||
r.setCode(ResultCodeEnum.UNKNOWN_ERROR.getCode());
|
||||
r.setMessage(ResultCodeEnum.UNKNOWN_ERROR.getMessage());
|
||||
return r;
|
||||
}
|
||||
|
||||
// 设置结果,形参为结果枚举
|
||||
public static RestResult setResult(ResultCodeEnum result) {
|
||||
RestResult r = new RestResult();
|
||||
r.setSuccess(result.getSuccess());
|
||||
r.setCode(result.getCode());
|
||||
r.setMessage(result.getMessage());
|
||||
return r;
|
||||
}
|
||||
|
||||
// 自定义返回数据
|
||||
public RestResult data(T param) {
|
||||
this.setData(param);
|
||||
return this;
|
||||
}
|
||||
|
||||
// 自定义状态信息
|
||||
public RestResult message(String message) {
|
||||
this.setMessage(message);
|
||||
return this;
|
||||
}
|
||||
|
||||
// 自定义状态码
|
||||
public RestResult code(Integer code) {
|
||||
this.setCode(code);
|
||||
return this;
|
||||
}
|
||||
|
||||
// 自定义返回结果
|
||||
public RestResult success(Boolean success) {
|
||||
this.setSuccess(success);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package com.qiwenshare.common.result;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 结果类枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum ResultCodeEnum {
|
||||
SUCCESS(true,20000,"成功"),
|
||||
UNKNOWN_ERROR(false,20001,"未知错误"),
|
||||
PARAM_ERROR(false,20002,"参数错误"),
|
||||
NULL_POINT(false, 20003, "空指针异常"),
|
||||
INDEX_OUT_OF_BOUNDS(false, 20004, "下标越界异常"),
|
||||
REQUEST_TIMEOUT(false, 20005, "请求超时"),
|
||||
NOT_LOGIN_ERROR(false, 20006, "未登录异常"),
|
||||
;
|
||||
|
||||
// 响应是否成功
|
||||
private Boolean success;
|
||||
// 响应状态码
|
||||
private Integer code;
|
||||
// 响应信息
|
||||
private String message;
|
||||
|
||||
ResultCodeEnum(boolean success, Integer code, String message) {
|
||||
this.success = success;
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.qiwenshare.common.util;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* 通信工具类
|
||||
*
|
||||
* @author ma116
|
||||
*/
|
||||
public class CollectUtil {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CollectUtil.class);
|
||||
|
||||
/**
|
||||
* java 后台获取访问客户端ip地址
|
||||
*
|
||||
* @param request HttpServletRequest请求
|
||||
* @return IP地址
|
||||
*/
|
||||
public String getClientIpAddress(HttpServletRequest request) {
|
||||
String clientIp = request.getHeader("x-forwarded-for");
|
||||
if (clientIp == null || clientIp.length() == 0
|
||||
|| "unknown".equalsIgnoreCase(clientIp)) {
|
||||
clientIp = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (clientIp == null || clientIp.length() == 0
|
||||
|| "unknown".equalsIgnoreCase(clientIp)) {
|
||||
clientIp = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (clientIp == null || clientIp.length() == 0
|
||||
|| "unknown".equalsIgnoreCase(clientIp)) {
|
||||
clientIp = request.getRemoteAddr();
|
||||
}
|
||||
return clientIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本地IP
|
||||
*
|
||||
* @return IP地址
|
||||
*/
|
||||
public String getLocalIp() {
|
||||
InetAddress addr = null;
|
||||
String ip = "";
|
||||
try {
|
||||
addr = InetAddress.getLocalHost();
|
||||
} catch (UnknownHostException e) {
|
||||
LOG.error("获取本地IP失败");
|
||||
}
|
||||
if (addr != null) {
|
||||
ip = addr.getHostAddress().toString();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
package com.qiwenshare.common.util;
|
||||
|
||||
import cn.hutool.captcha.generator.RandomGenerator;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateUtil {
|
||||
|
||||
/**
|
||||
* 获取系统当前时间
|
||||
*
|
||||
* @return 系统当前时间
|
||||
*/
|
||||
public static String getCurrentTime() {
|
||||
Date date = new Date();
|
||||
String stringDate = String.format("%tF %<tT", date);
|
||||
return stringDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stringDate 日期字符串,如"2000-03-19"
|
||||
* @param formatString 格式,如"yyyy-MM-dd"
|
||||
* @return 日期
|
||||
* @throws ParseException 解析异常
|
||||
*/
|
||||
public static Date getDateByFormatString(String stringDate, String formatString) throws ParseException {
|
||||
DateFormat dateFormat = new SimpleDateFormat(formatString);
|
||||
Date date = dateFormat.parse(stringDate);
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* 两个日期相差天数
|
||||
*
|
||||
* @param preDate 第一个时间日期
|
||||
* @param afterDate 第二个时间十七
|
||||
* @return 相差的天数
|
||||
*/
|
||||
public static int getDifferentDays(Date preDate, Date afterDate) {
|
||||
|
||||
int preYear = getYear(preDate);
|
||||
int afterYear = getYear(afterDate);
|
||||
int preDayOfYear = getDayOfYear(preDate);
|
||||
int afterDayOfYear = getDayOfYear(afterDate);
|
||||
|
||||
if (afterYear - preYear == 0) {
|
||||
return afterDayOfYear - preDayOfYear;
|
||||
} else {
|
||||
int diffDay = 0;
|
||||
while (preYear < afterYear) {
|
||||
if (diffDay == 0 && isLeapYear(preYear)) {
|
||||
diffDay = 366 - preDayOfYear;
|
||||
} else if (diffDay == 0 && !isLeapYear(preYear)) {
|
||||
diffDay = 365 - preDayOfYear;
|
||||
} else if (isLeapYear(preYear)) {
|
||||
diffDay += 366;
|
||||
} else {
|
||||
diffDay += 365;
|
||||
}
|
||||
preYear++;
|
||||
}
|
||||
|
||||
diffDay += afterDayOfYear;
|
||||
return diffDay;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 一年中的第几天
|
||||
*
|
||||
* @param date 日期
|
||||
* @return 第几天
|
||||
*/
|
||||
public static int getDayOfYear(Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
int day = cal.get(Calendar.DAY_OF_YEAR);
|
||||
return day;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取年份
|
||||
* jdk推荐写法,date.getYear()已被废弃
|
||||
*
|
||||
* @param date 日期
|
||||
* @return 年份
|
||||
*/
|
||||
public static int getYear(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
return year;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是闰年
|
||||
*
|
||||
* @param year 年,如2010
|
||||
* @return 是否闰年
|
||||
*/
|
||||
public static boolean isLeapYear(int year) {
|
||||
if ((year % 4 == 0 && year % 100 != 0)
|
||||
|| year % 400 == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static long getTime() {
|
||||
long time = new Date().getTime();
|
||||
return time;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(RandomUtil.randomInt(6));
|
||||
}
|
||||
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
package com.qiwenshare.common.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
public static final String[] IMG_FILE = {"bmp", "jpg", "png", "tif", "gif", "jpeg"};
|
||||
public static final String[] DOC_FILE = {"doc", "docx", "ppt", "pptx", "xls", "xlsx", "txt", "hlp", "wps", "rtf", "html", "pdf"};
|
||||
public static final String[] VIDEO_FILE = {"avi", "mp4", "mpg", "mov", "swf"};
|
||||
public static final String[] MUSIC_FILE = {"wav", "aif", "au", "mp3", "ram", "wma", "mmf", "amr", "aac", "flac"};
|
||||
public static final int IMAGE_TYPE = 1;
|
||||
public static final int DOC_TYPE = 2;
|
||||
public static final int VIDEO_TYPE = 3;
|
||||
public static final int MUSIC_TYPE = 4;
|
||||
public static final int OTHER_TYPE = 5;
|
||||
public static final int SHARE_FILE = 6;
|
||||
public static final int RECYCLE_FILE = 7;
|
||||
|
||||
public static List<String> getFileExtendsByType(int fileType) {
|
||||
|
||||
List<String> fileExtends;
|
||||
switch (fileType) {
|
||||
case IMAGE_TYPE:
|
||||
fileExtends = Arrays.asList(IMG_FILE);
|
||||
break;
|
||||
case DOC_TYPE:
|
||||
fileExtends = Arrays.asList(DOC_FILE);
|
||||
break;
|
||||
case VIDEO_TYPE:
|
||||
fileExtends = Arrays.asList(VIDEO_FILE);
|
||||
break;
|
||||
case MUSIC_TYPE:
|
||||
fileExtends = Arrays.asList(MUSIC_FILE);
|
||||
break;
|
||||
default:
|
||||
fileExtends = new ArrayList<>();
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
return fileExtends;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为图片文件
|
||||
*
|
||||
* @param extendName 文件扩展名
|
||||
* @return 是否为图片文件
|
||||
*/
|
||||
public static boolean isImageFile(String extendName) {
|
||||
for (int i = 0; i < IMG_FILE.length; i++) {
|
||||
if (extendName.equalsIgnoreCase(IMG_FILE[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String pathSplitFormat(String filePath) {
|
||||
String path = filePath.replace("///", "/")
|
||||
.replace("//", "/")
|
||||
.replace("\\\\\\", "\\")
|
||||
.replace("\\\\", "\\");
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件扩展名
|
||||
* @param fileName 文件名
|
||||
* @return 文件扩展名
|
||||
*/
|
||||
public static String getFileExtendName(String fileName) {
|
||||
if (fileName.lastIndexOf(".") == -1) {
|
||||
return "";
|
||||
}
|
||||
return fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取不包含扩展名的文件名
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return 文件名(不带扩展名)
|
||||
*/
|
||||
public static String getFileNameNotExtend(String fileName) {
|
||||
String fileType = getFileExtendName(fileName);
|
||||
return fileName.replace("." + fileType, "");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
package com.qiwenshare.common.util;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwtBuilder;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
//import org.apache.commons.net.util.Base64;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class JjwtUtil {
|
||||
|
||||
// jti:jwt的唯一身份标识
|
||||
public static final String JWT_ID = UUID.randomUUID().toString();
|
||||
|
||||
// 加密密文,私钥
|
||||
public static final String JWT_SECRET = "jiamimiwen";
|
||||
|
||||
// 过期时间,单位毫秒
|
||||
public static final int EXPIRE_TIME = 60 * 60 * 1000 * 24 * 7; // 一个星期
|
||||
|
||||
// 由字符串生成加密key
|
||||
public static SecretKey generalKey() {
|
||||
String secret = JWT_SECRET;
|
||||
// 本地的密码解码
|
||||
byte[] encodedKey = Base64.decodeBase64(JWT_SECRET);
|
||||
// 根据给定的字节数组使用AES加密算法构造一个密钥
|
||||
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
|
||||
return key;
|
||||
}
|
||||
|
||||
// 创建jwt
|
||||
public static String createJWT(String issuer, String audience, String subject) throws Exception {
|
||||
// 设置头部信息
|
||||
// Map<String, Object> header = new HashMap<String, Object>();
|
||||
// header.put("typ", "JWT");
|
||||
// header.put("alg", "HS256");
|
||||
// 或
|
||||
// 指定header那部分签名的时候使用的签名算法,jjwt已经将这部分内容封装好了,只有{"alg":"HS256"}
|
||||
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
|
||||
// 创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证的方式)
|
||||
Map<String, Object> claims = new HashMap<>(2);
|
||||
claims.put("username", "admin");
|
||||
claims.put("password", "010203");
|
||||
// jti用户id,例如:20da39f8-b74e-4a9b-9a0f-a39f1f73fe64
|
||||
String jwtId = JWT_ID;
|
||||
// 生成JWT的时间
|
||||
long nowTime = System.currentTimeMillis();
|
||||
Date issuedAt = new Date(nowTime);
|
||||
// 生成签名的时候使用的秘钥secret,切记这个秘钥不能外露,是你服务端的私钥,在任何场景都不应该流露出去,一旦客户端得知这个secret,那就意味着客户端是可以自我签发jwt的
|
||||
SecretKey key = generalKey();
|
||||
// 为payload添加各种标准声明和私有声明
|
||||
JwtBuilder builder = Jwts.builder() // 表示new一个JwtBuilder,设置jwt的body
|
||||
// .setHeader(header) // 设置头部信息
|
||||
.setClaims(claims) // 如果有私有声明,一定要先设置自己创建的这个私有声明,这是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明
|
||||
.setId(jwtId) // jti(JWT ID):jwt的唯一身份标识,根据业务需要,可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击
|
||||
.setIssuedAt(issuedAt) // iat(issuedAt):jwt的签发时间
|
||||
.setIssuer(issuer) // iss(issuer):jwt签发者
|
||||
.setSubject(subject) // sub(subject):jwt所面向的用户,放登录的用户名,一个json格式的字符串,可存放userid,roldid之类,作为用户的唯一标志
|
||||
.signWith(signatureAlgorithm, key); // 设置签名,使用的是签名算法和签名使用的秘钥
|
||||
// 设置过期时间
|
||||
long expTime = EXPIRE_TIME;
|
||||
if (expTime >= 0) {
|
||||
long exp = nowTime + expTime;
|
||||
builder.setExpiration(new Date(exp));
|
||||
}
|
||||
// 设置jwt接收者
|
||||
if (audience == null || "".equals(audience)) {
|
||||
builder.setAudience("Tom");
|
||||
} else {
|
||||
builder.setAudience(audience);
|
||||
}
|
||||
return builder.compact();
|
||||
}
|
||||
|
||||
// 解密jwt
|
||||
public static Claims parseJWT(String jwt) throws Exception {
|
||||
SecretKey key = generalKey(); // 签名秘钥,和生成的签名的秘钥一模一样
|
||||
Claims claims = Jwts.parser() // 得到DefaultJwtParser
|
||||
.setSigningKey(key) // 设置签名的秘钥
|
||||
.parseClaimsJws(jwt).getBody(); // 设置需要解析的jwt
|
||||
return claims;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,202 +0,0 @@
|
||||
package com.qiwenshare.common.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MimeUtils {
|
||||
|
||||
public static String getMime(String suffix){
|
||||
return map.get(suffix);
|
||||
}
|
||||
private static Map<String,String> map=new HashMap<String,String>();
|
||||
static{
|
||||
map.put("323","text/h323");
|
||||
map.put("acx","application/internet-property-stream");
|
||||
map.put("ai","application/postscript");
|
||||
map.put("aif","audio/x-aiff");
|
||||
map.put("aifc","audio/x-aiff");
|
||||
map.put("aiff","audio/x-aiff");
|
||||
map.put("asf","video/x-ms-asf");
|
||||
map.put("asr","video/x-ms-asf");
|
||||
map.put("asx","video/x-ms-asf");
|
||||
map.put("au","audio/basic");
|
||||
map.put("avi","video/x-msvideo");
|
||||
map.put("axs","application/olescript");
|
||||
map.put("bas","text/plain");
|
||||
map.put("bcpio","application/x-bcpio");
|
||||
map.put("bin","application/octet-stream");
|
||||
map.put("bmp","image/bmp");
|
||||
map.put("c","text/plain");
|
||||
map.put("cat","application/vnd.ms-pkiseccat");
|
||||
map.put("cdf","application/x-cdf");
|
||||
map.put("cer","application/x-x509-ca-cert");
|
||||
map.put("class","application/octet-stream");
|
||||
map.put("clp","application/x-msclip");
|
||||
map.put("cmx","image/x-cmx");
|
||||
map.put("cod","image/cis-cod");
|
||||
map.put("cpio","application/x-cpio");
|
||||
map.put("crd","application/x-mscardfile");
|
||||
map.put("crl","application/pkix-crl");
|
||||
map.put("crt","application/x-x509-ca-cert");
|
||||
map.put("csh","application/x-csh");
|
||||
map.put("css","text/css");
|
||||
map.put("dcr","application/x-director");
|
||||
map.put("der","application/x-x509-ca-cert");
|
||||
map.put("dir","application/x-director");
|
||||
map.put("dll","application/x-msdownload");
|
||||
map.put("dms","application/octet-stream");
|
||||
map.put("doc","application/msword");
|
||||
map.put("dot","application/msword");
|
||||
map.put("dvi","application/x-dvi");
|
||||
map.put("dxr","application/x-director");
|
||||
map.put("eps","application/postscript");
|
||||
map.put("etx","text/x-setext");
|
||||
map.put("evy","application/envoy");
|
||||
map.put("exe","application/octet-stream");
|
||||
map.put("fif","application/fractals");
|
||||
map.put("flr","x-world/x-vrml");
|
||||
map.put("gif","image/gif");
|
||||
map.put("gtar","application/x-gtar");
|
||||
map.put("gz","application/x-gzip");
|
||||
map.put("h","text/plain");
|
||||
map.put("hdf","application/x-hdf");
|
||||
map.put("hlp","application/winhlp");
|
||||
map.put("hqx","application/mac-binhex40");
|
||||
map.put("hta","application/hta");
|
||||
map.put("htc","text/x-component");
|
||||
map.put("htm","text/plain");
|
||||
map.put("html","text/plain");
|
||||
map.put("htt","text/webviewhtml");
|
||||
map.put("ico","image/x-icon");
|
||||
map.put("ief","image/ief");
|
||||
map.put("iii","application/x-iphone");
|
||||
map.put("ins","application/x-internet-signup");
|
||||
map.put("isp","application/x-internet-signup");
|
||||
map.put("jfif","image/pipeg");
|
||||
map.put("jpe","image/jpeg");
|
||||
map.put("jpeg","image/jpeg");
|
||||
map.put("jpg","image/jpeg");
|
||||
map.put("js","application/x-javascript");
|
||||
map.put("latex","application/x-latex");
|
||||
map.put("lha","application/octet-stream");
|
||||
map.put("lsf","video/x-la-asf");
|
||||
map.put("lsx","video/x-la-asf");
|
||||
map.put("lzh","application/octet-stream");
|
||||
map.put("m13","application/x-msmediaview");
|
||||
map.put("m14","application/x-msmediaview");
|
||||
map.put("m3u","audio/x-mpegurl");
|
||||
map.put("man","application/x-troff-man");
|
||||
map.put("mdb","application/x-msaccess");
|
||||
map.put("me","application/x-troff-me");
|
||||
map.put("mht","message/rfc822");
|
||||
map.put("mhtml","message/rfc822");
|
||||
map.put("mid","audio/mid");
|
||||
map.put("mny","application/x-msmoney");
|
||||
map.put("mov","video/quicktime");
|
||||
map.put("movie","video/x-sgi-movie");
|
||||
map.put("mp2","video/mpeg");
|
||||
map.put("mp3","audio/mpeg");
|
||||
map.put("mp4","video/mp4");
|
||||
map.put("mpa","video/mpeg");
|
||||
map.put("mpe","video/mpeg");
|
||||
map.put("mpeg","video/mpeg");
|
||||
map.put("mpg","video/mpeg");
|
||||
map.put("mpp","application/vnd.ms-project");
|
||||
map.put("mpv2","video/mpeg");
|
||||
map.put("ms","application/x-troff-ms");
|
||||
map.put("mvb","application/x-msmediaview");
|
||||
map.put("nws","message/rfc822");
|
||||
map.put("oda","application/oda");
|
||||
map.put("p10","application/pkcs10");
|
||||
map.put("p12","application/x-pkcs12");
|
||||
map.put("p7b","application/x-pkcs7-certificates");
|
||||
map.put("p7c","application/x-pkcs7-mime");
|
||||
map.put("p7m","application/x-pkcs7-mime");
|
||||
map.put("p7r","application/x-pkcs7-certreqresp");
|
||||
map.put("p7s","application/x-pkcs7-signature");
|
||||
map.put("pbm","image/x-portable-bitmap");
|
||||
map.put("pdf","application/pdf");
|
||||
map.put("pfx","application/x-pkcs12");
|
||||
map.put("pgm","image/x-portable-graymap");
|
||||
map.put("pko","application/ynd.ms-pkipko");
|
||||
map.put("pma","application/x-perfmon");
|
||||
map.put("pmc","application/x-perfmon");
|
||||
map.put("pml","application/x-perfmon");
|
||||
map.put("pmr","application/x-perfmon");
|
||||
map.put("pmw","application/x-perfmon");
|
||||
map.put("pnm","image/x-portable-anymap");
|
||||
map.put("pot,","application/vnd.ms-powerpoint");
|
||||
map.put("ppm","image/x-portable-pixmap");
|
||||
map.put("pps","application/vnd.ms-powerpoint");
|
||||
map.put("ppt","application/vnd.ms-powerpoint");
|
||||
map.put("prf","application/pics-rules");
|
||||
map.put("ps","application/postscript");
|
||||
map.put("pub","application/x-mspublisher");
|
||||
map.put("qt","video/quicktime");
|
||||
map.put("ra","audio/x-pn-realaudio");
|
||||
map.put("ram","audio/x-pn-realaudio");
|
||||
map.put("ras","image/x-cmu-raster");
|
||||
map.put("rgb","image/x-rgb");
|
||||
map.put("rmi","audio/mid");
|
||||
map.put("roff","application/x-troff");
|
||||
map.put("rtf","application/rtf");
|
||||
map.put("rtx","text/richtext");
|
||||
map.put("scd","application/x-msschedule");
|
||||
map.put("sct","text/scriptlet");
|
||||
map.put("setpay","application/set-payment-initiation");
|
||||
map.put("setreg","application/set-registration-initiation");
|
||||
map.put("sh","application/x-sh");
|
||||
map.put("shar","application/x-shar");
|
||||
map.put("sit","application/x-stuffit");
|
||||
map.put("snd","audio/basic");
|
||||
map.put("spc","application/x-pkcs7-certificates");
|
||||
map.put("spl","application/futuresplash");
|
||||
map.put("src","application/x-wais-source");
|
||||
map.put("sst","application/vnd.ms-pkicertstore");
|
||||
map.put("stl","application/vnd.ms-pkistl");
|
||||
map.put("stm","text/html");
|
||||
map.put("svg","image/svg+xml");
|
||||
map.put("sv4cpio","application/x-sv4cpio");
|
||||
map.put("sv4crc","application/x-sv4crc");
|
||||
map.put("swf","application/x-shockwave-flash");
|
||||
map.put("t","application/x-troff");
|
||||
map.put("tar","application/x-tar");
|
||||
map.put("tcl","application/x-tcl");
|
||||
map.put("tex","application/x-tex");
|
||||
map.put("texi","application/x-texinfo");
|
||||
map.put("texinfo","application/x-texinfo");
|
||||
map.put("tgz","application/x-compressed");
|
||||
map.put("tif","image/tiff");
|
||||
map.put("tiff","image/tiff");
|
||||
map.put("tr","application/x-troff");
|
||||
map.put("trm","application/x-msterminal");
|
||||
map.put("tsv","text/tab-separated-values");
|
||||
map.put("txt","text/plain");
|
||||
map.put("uls","text/iuls");
|
||||
map.put("ustar","application/x-ustar");
|
||||
map.put("vcf","text/x-vcard");
|
||||
map.put("vrml","x-world/x-vrml");
|
||||
map.put("wav","audio/x-wav");
|
||||
map.put("wcm","application/vnd.ms-works");
|
||||
map.put("wdb","application/vnd.ms-works");
|
||||
map.put("wks","application/vnd.ms-works");
|
||||
map.put("wmf","application/x-msmetafile");
|
||||
map.put("wps","application/vnd.ms-works");
|
||||
map.put("wri","application/x-mswrite");
|
||||
map.put("wrl","x-world/x-vrml");
|
||||
map.put("wrz","x-world/x-vrml");
|
||||
map.put("xaf","x-world/x-vrml");
|
||||
map.put("xbm","image/x-xbitmap");
|
||||
map.put("xla","application/vnd.ms-excel");
|
||||
map.put("xlc","application/vnd.ms-excel");
|
||||
map.put("xlm","application/vnd.ms-excel");
|
||||
map.put("xls","application/vnd.ms-excel");
|
||||
map.put("xlt","application/vnd.ms-excel");
|
||||
map.put("xlw","application/vnd.ms-excel");
|
||||
map.put("xof","x-world/x-vrml");
|
||||
map.put("xpm","image/x-xpixmap");
|
||||
map.put("xwd","image/x-xwindowdump");
|
||||
map.put("z","application/x-compress");
|
||||
map.put("zip","application/zip");
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.qiwenshare.common.util;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class PasswordUtil {
|
||||
public static String getSaltValue() {
|
||||
Random r = new Random();
|
||||
StringBuilder sb = new StringBuilder(16);
|
||||
sb.append(r.nextInt(99999999)).append(r.nextInt(99999999));
|
||||
int len = sb.length();
|
||||
if (len < 16) {
|
||||
for (int i = 0; i < 16 - len; i++) {
|
||||
sb.append("0");
|
||||
}
|
||||
}
|
||||
String salt = sb.toString();
|
||||
return salt;
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package com.qiwenshare.common.util;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.qiwenshare.common.constant.FileConstant;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
|
||||
public class PathUtil {
|
||||
/**
|
||||
* 获取项目所在的根目录路径 resources路径
|
||||
* @return
|
||||
*/
|
||||
public static String getProjectRootPath() {
|
||||
String absolutePath = null;
|
||||
try {
|
||||
String url = ResourceUtils.getURL("classpath:").getPath();
|
||||
absolutePath = urlDecode(new File(url).getAbsolutePath()) + File.separator;
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return absolutePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 路径解码
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
public static String urlDecode(String url){
|
||||
String decodeUrl = null;
|
||||
try {
|
||||
decodeUrl = URLDecoder.decode(url, "utf-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return decodeUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到static路径
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getStaticPath() {
|
||||
String localStoragePath = PropertiesUtil.getProperty("qiwen-file.local-storage-path");
|
||||
if (StringUtils.isNotEmpty(localStoragePath)) {
|
||||
return localStoragePath;
|
||||
}else {
|
||||
String projectRootAbsolutePath = getProjectRootPath();
|
||||
|
||||
int index = projectRootAbsolutePath.indexOf("file:");
|
||||
if (index != -1) {
|
||||
projectRootAbsolutePath = projectRootAbsolutePath.substring(0, index);
|
||||
}
|
||||
|
||||
return projectRootAbsolutePath + "static" + File.separator;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String getParentPath(String path) {
|
||||
return path.substring(0, path.lastIndexOf(FileConstant.pathSeparator));
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(RandomUtil.randomLong(999999));
|
||||
// String path = "aaa/bbb/ccc/";
|
||||
// System.out.println(getParentPath(path));
|
||||
// String fileName = path.substring(path.lastIndexOf("/"));
|
||||
// System.out.println(fileName);
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.qiwenshare.common.util;
|
||||
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
public class PropertiesUtil {
|
||||
|
||||
private static Environment env = null;
|
||||
|
||||
public static void setEnvironment(Environment env) {
|
||||
PropertiesUtil.env = env;
|
||||
}
|
||||
|
||||
public static String getProperty(String key) {
|
||||
return PropertiesUtil.env.getProperty(key);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
package com.qiwenshare.common.util;
|
||||
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.SessionCallback;
|
||||
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RedisUtil {
|
||||
|
||||
@Resource
|
||||
RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 将值放入缓存
|
||||
*/
|
||||
public void set(String key, Object value) {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串:取对象
|
||||
*/
|
||||
public <T> T getObject(String key) {
|
||||
Object o = redisTemplate.opsForValue().get(key);
|
||||
if (o != null) {
|
||||
return (T) o;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将值放入缓存并设置时间-秒
|
||||
*/
|
||||
public void set(String key, Object value, long time) {
|
||||
if (time > 0) {
|
||||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||
} else {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除key
|
||||
*/
|
||||
public void deleteKey(String key) {
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建锁
|
||||
* @param key 锁的Key
|
||||
* @param value 值(随便写毫无意义)
|
||||
* @param releaseTime 锁过期时间 防止死锁
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean lock(String key, int value, long releaseTime) {
|
||||
// 尝试获取锁
|
||||
Boolean boo = redisTemplate.opsForValue().setIfAbsent(key, value, releaseTime, TimeUnit.SECONDS);
|
||||
// 判断结果
|
||||
return boo != null && boo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据key删除锁
|
||||
*/
|
||||
public void deleteLock(String key) {
|
||||
// 删除key即可释放锁
|
||||
deleteKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description: 获取自增长值
|
||||
* @param key key
|
||||
* @return
|
||||
*/
|
||||
public Long getIncr(String key) {
|
||||
Long count = redisTemplate.opsForValue().increment(key, 1);
|
||||
return count;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// Lock
|
||||
// }
|
||||
|
||||
|
||||
}
|
@ -1,240 +0,0 @@
|
||||
package com.qiwenshare.common.util.concurrent.locks;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.redis.connection.RedisStringCommands;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.types.Expiration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
|
||||
/**
|
||||
* redis实现分布式锁
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class RedisLock{
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RedisLock.class);
|
||||
|
||||
/**
|
||||
* 默认轮休获取锁间隔时间, 单位:毫秒
|
||||
*/
|
||||
private static final int DEFAULT_ACQUIRE_RESOLUTION_MILLIS = 100;
|
||||
|
||||
private static final String UNLOCK_LUA;
|
||||
|
||||
private static final long LOCK_EXPIRE_TIME = 60 * 15; //获取锁最大15分钟就会过期
|
||||
|
||||
|
||||
@Resource
|
||||
RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
static {
|
||||
StringBuilder lua = new StringBuilder();
|
||||
lua.append("if redis.call(\"get\",KEYS[1]) == ARGV[1] ");
|
||||
lua.append("then ");
|
||||
lua.append(" return redis.call(\"del\",KEYS[1]) ");
|
||||
lua.append("else ");
|
||||
lua.append(" return 0 ");
|
||||
lua.append("end ");
|
||||
UNLOCK_LUA = lua.toString();
|
||||
}
|
||||
|
||||
private final ThreadLocal<Map<String, LockVO>> lockMap = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 获取锁,没有获取到则一直等待
|
||||
*
|
||||
* @param key redis key
|
||||
*/
|
||||
public void lock(final String key) {
|
||||
|
||||
try {
|
||||
acquireLock(key, LOCK_EXPIRE_TIME, -1);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("acquire lock exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放锁
|
||||
*
|
||||
* @param key redis key
|
||||
*/
|
||||
public void unlock(String key) {
|
||||
try {
|
||||
release(key);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("release lock exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean tryLock(final String key) {
|
||||
try {
|
||||
return acquireLock(key, LOCK_EXPIRE_TIME, -1);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("acquire lock exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取锁,指定时间内没有获取到,返回false。否则 返回true
|
||||
*
|
||||
* @param key redis key
|
||||
* @param waitTime 获取锁超时时间, -1代表永不超时, 单位 秒
|
||||
*/
|
||||
public boolean tryLock(String key, long time, TimeUnit unit) {
|
||||
try {
|
||||
return acquireLock(key, LOCK_EXPIRE_TIME, unit.toSeconds(time));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("acquire lock exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key redis key
|
||||
* @param expire 锁过期时间, 单位 秒
|
||||
* @param waitTime 获取锁超时时间, -1代表永不超时, 单位 秒
|
||||
* @return if true success else fail
|
||||
* @throws InterruptedException 阻塞方法收到中断请求
|
||||
*/
|
||||
private boolean acquireLock(String key, long expire, long waitTime) throws InterruptedException {
|
||||
//如果之前获取到了并且没有超时,则返回获取成功
|
||||
boolean acquired = acquired(key);
|
||||
if (acquired) {
|
||||
return true;
|
||||
}
|
||||
long acquireTime = waitTime == -1 ? -1 : waitTime * 1000 + System.currentTimeMillis();
|
||||
//同一个进程,对于同一个key锁,只允许先到的去尝试获取。
|
||||
// key.intern() 如果常量池中存在当前字符串, 就会直接返回当前字符串.
|
||||
// 如果常量池中没有此字符串, 会将此字符串放入常量池中后, 再返回
|
||||
synchronized (key.intern()) {
|
||||
String lockId = UUID.randomUUID().toString();
|
||||
do {
|
||||
long before = System.currentTimeMillis();
|
||||
boolean hasLock = tryLock(key, expire, lockId);
|
||||
//获取锁成功
|
||||
if (hasLock) {
|
||||
long after = System.currentTimeMillis();
|
||||
Map<String, LockVO> map = lockMap.get();
|
||||
if (map == null) {
|
||||
map = new HashMap<>(2);
|
||||
lockMap.set(map);
|
||||
}
|
||||
map.put(key, new LockVO(1, lockId, expire * 1000 + before, expire * 1000 + after));
|
||||
log.debug("acquire lock {} {} ", key, 1);
|
||||
return true;
|
||||
}
|
||||
Thread.sleep(DEFAULT_ACQUIRE_RESOLUTION_MILLIS);
|
||||
} while (acquireTime == -1 || acquireTime > System.currentTimeMillis());
|
||||
}
|
||||
log.debug("acquire lock {} fail,because timeout ", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 释放锁
|
||||
*
|
||||
* @param key redis key
|
||||
*/
|
||||
private void release(String key) {
|
||||
Map<String, LockVO> map = lockMap.get();
|
||||
if (map == null || map.size() == 0 || !map.containsKey(key)) {
|
||||
return;
|
||||
}
|
||||
LockVO vo = map.get(key);
|
||||
if (vo.afterExpireTime < System.currentTimeMillis()) {
|
||||
log.debug("release lock {}, because timeout ", key);
|
||||
map.remove(key);
|
||||
return;
|
||||
}
|
||||
int after = --vo.count;
|
||||
log.debug("release lock {} {} ", key, after);
|
||||
if (after > 0) {
|
||||
return;
|
||||
}
|
||||
map.remove(key);
|
||||
RedisCallback<Boolean> callback = (connection) ->
|
||||
connection.eval(UNLOCK_LUA.getBytes(StandardCharsets.UTF_8), ReturnType.BOOLEAN, 1,
|
||||
(key).getBytes(StandardCharsets.UTF_8), vo.lockId.getBytes(StandardCharsets.UTF_8));
|
||||
redisTemplate.execute(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key 锁的key
|
||||
* @param expire 锁的超时时间 秒
|
||||
* @param lockId 获取锁后,UUID生成的唯一ID
|
||||
* @return if true success else fail
|
||||
*/
|
||||
private boolean tryLock(String key, long expire, String lockId) {
|
||||
try{
|
||||
RedisCallback<Boolean> callback = (connection) ->
|
||||
connection.set(
|
||||
(key).getBytes(StandardCharsets.UTF_8),
|
||||
lockId.getBytes(StandardCharsets.UTF_8),
|
||||
Expiration.seconds(expire),
|
||||
RedisStringCommands.SetOption.SET_IF_ABSENT);
|
||||
return (Boolean) redisTemplate.execute(callback);
|
||||
} catch (Exception e) {
|
||||
log.error("redis lock error.", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class LockVO {
|
||||
/**
|
||||
* 锁重入的次数
|
||||
*/
|
||||
private int count;
|
||||
|
||||
/**
|
||||
* 获取锁后,UUID生成的唯一ID
|
||||
*/
|
||||
private String lockId;
|
||||
/**
|
||||
* 获取锁之前的时间戳
|
||||
*/
|
||||
private long beforeExpireTime;
|
||||
/**
|
||||
* 获取到锁的时间戳
|
||||
*/
|
||||
private long afterExpireTime;
|
||||
|
||||
LockVO(int count, String lockId, long beforeExpireTime, long afterExpireTime) {
|
||||
this.count = count;
|
||||
this.lockId = lockId;
|
||||
this.beforeExpireTime = beforeExpireTime;
|
||||
this.afterExpireTime = afterExpireTime;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean acquired(String key) {
|
||||
Map<String, LockVO> map = lockMap.get();
|
||||
if (map == null || map.size() == 0 || !map.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LockVO vo = map.get(key);
|
||||
if (vo.beforeExpireTime < System.currentTimeMillis()) {
|
||||
log.debug("lock {} maybe release, because timeout ", key);
|
||||
return false;
|
||||
}
|
||||
int after = ++vo.count;
|
||||
log.debug("acquire lock {} {} ", key, after);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
|
||||
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
|
||||
-->
|
||||
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
|
||||
|
||||
<id>file-common</id>
|
||||
|
||||
<classpath>
|
||||
<dir name="E:/workspace/qiwen-file/file-common/target/classes">
|
||||
</dir>
|
||||
</classpath>
|
||||
|
||||
</application>
|
29
file-web/.gitignore
vendored
29
file-web/.gitignore
vendored
@ -1,29 +0,0 @@
|
||||
HELP.md
|
||||
/target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
171
file-web/pom.xml
171
file-web/pom.xml
@ -1,171 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.qiwenshare</groupId>
|
||||
<artifactId>file</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>com.qiwenshare</groupId>
|
||||
<artifactId>file-web</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>file-web</name>
|
||||
<description>fileos.qiwenshare.com</description>
|
||||
<packaging>jar</packaging>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
|
||||
<skipTests>true</skipTests>
|
||||
<docker.image.prefix>scp</docker.image.prefix>
|
||||
<release-path>target/../../release</release-path>
|
||||
<app-name>${project.artifactId}-${project.version}</app-name>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.cloud</groupId>-->
|
||||
<!-- <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!--mybatis end-->
|
||||
|
||||
|
||||
<!-- spring boot依赖包 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-starter-web</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
|
||||
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!--登陆认证和权限管理-->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.qiwenshare</groupId>
|
||||
<artifactId>file-common</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
|
||||
<!-- </plugin>-->
|
||||
<!--排除静态文件-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<!-- 添加index则不从mainfest中读取classpath,而是从Index.list中读取 -->
|
||||
<!-- <index>true</index> -->
|
||||
<manifest>
|
||||
<mainClass>com.qiwenshare.file.FileApplication</mainClass>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>lib/</classpathPrefix>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Class-Path>./</Class-Path>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
|
||||
<excludes>
|
||||
<exclude>static/**</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- not append assembly id in release file name -->
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<descriptors>
|
||||
<descriptor>../file-common/src/main/resources/conf/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
<!--ant插件执行自定义动作-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<target>
|
||||
<copy todir="${release-path}" >
|
||||
<fileset dir="target/${app-name}/${app-name}">
|
||||
</fileset>
|
||||
</copy>
|
||||
<!-- <copy file="target/classes/script/startup.bat" tofile="${release-path}/startup.bat"/>-->
|
||||
<!-- <copy file="target/classes/script/startup.sh" tofile="${release-path}/startup.sh"/>-->
|
||||
<!-- <copy file="target/classes/script/stop.sh" tofile="${release-path}/stop.sh"/>-->
|
||||
<!-- <copy todir="${release-path}">-->
|
||||
<!-- <fileset dir="target/classes">-->
|
||||
<!-- <include name="**/static/**" />-->
|
||||
<!-- </fileset>-->
|
||||
<!-- </copy>-->
|
||||
</target>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
|
||||
|
||||
</build>
|
||||
|
||||
</project>
|
@ -1,4 +1,4 @@
|
||||
set settingDir=file-common/src/main/resources/conf/settings.xml
|
||||
set settingDir=src/main/resources/build/settings.xml
|
||||
|
||||
mvn clean install -s %settingDir%
|
||||
pause
|
183
pom.xml
183
pom.xml
@ -1,25 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.4.1</version>
|
||||
<groupId>com.qiwenshare</groupId>
|
||||
<artifactId>qiwenshare</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.qiwenshare</groupId>
|
||||
<artifactId>file</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<artifactId>qiwen-file</artifactId>
|
||||
<version>1.0.1-SNAPSHOT</version>
|
||||
<name>qiwen-file</name>
|
||||
<description>fileos.qiwenshare.com</description>
|
||||
<packaging>jar</packaging>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<!-- <spring-cloud.version>Hoxton.SR9</spring-cloud.version>-->
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
|
||||
<skipTests>true</skipTests>
|
||||
<docker.image.prefix>scp</docker.image.prefix>
|
||||
<release-path>target/../release</release-path>
|
||||
<app-name>${project.artifactId}-${project.version}</app-name>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -31,11 +33,7 @@
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springdoc</groupId>-->
|
||||
<!-- <artifactId>springdoc-openapi-ui</artifactId>-->
|
||||
<!-- <version>1.5.4</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
@ -52,7 +50,6 @@
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.75</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 导入Mysql数据库链接jar包-->
|
||||
@ -73,38 +70,134 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!--mybatis end-->
|
||||
|
||||
<!--登陆认证和权限管理-->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.qiwenshare</groupId>
|
||||
<artifactId>ufo-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.cloud</groupId>-->
|
||||
<!-- <artifactId>spring-cloud-dependencies</artifactId>-->
|
||||
<!-- <version>${spring-cloud.version}</version>-->
|
||||
<!-- <type>pom</type>-->
|
||||
<!-- <scope>import</scope>-->
|
||||
<!-- </dependency>-->
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
|
||||
<!-- </plugin>-->
|
||||
<!--排除静态文件-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<!-- 添加index则不从mainfest中读取classpath,而是从Index.list中读取 -->
|
||||
<!-- <index>true</index> -->
|
||||
<manifest>
|
||||
<mainClass>com.qiwenshare.file.FileApplication</mainClass>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>lib/</classpathPrefix>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Class-Path>./</Class-Path>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>1.4.0</version>
|
||||
</dependency>
|
||||
<excludes>
|
||||
<exclude>static/**</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<modules>
|
||||
<module>file-common</module>
|
||||
<module>file-web</module>
|
||||
</modules>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- not append assembly id in release file name -->
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<descriptors>
|
||||
<descriptor>src/main/resources/build/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
</project>
|
||||
<!--ant插件执行自定义动作-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<target>
|
||||
<copy todir="${release-path}" >
|
||||
<fileset dir="target/${app-name}/${app-name}">
|
||||
</fileset>
|
||||
</copy>
|
||||
<!-- <copy file="target/classes/script/startup.bat" tofile="${release-path}/startup.bat"/>-->
|
||||
<!-- <copy file="target/classes/script/startup.sh" tofile="${release-path}/startup.sh"/>-->
|
||||
<!-- <copy file="target/classes/script/stop.sh" tofile="${release-path}/stop.sh"/>-->
|
||||
<!-- <copy todir="${release-path}">-->
|
||||
<!-- <fileset dir="target/classes">-->
|
||||
<!-- <include name="**/static/**" />-->
|
||||
<!-- </fileset>-->
|
||||
<!-- </copy>-->
|
||||
</target>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
|
||||
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
@ -16,13 +16,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.qiwenshare.file.mapper")
|
||||
@EnableScheduling
|
||||
//@EnableDiscoveryClient
|
||||
@EnableTransactionManagement
|
||||
@ComponentScan(value = "com.qiwenshare", excludeFilters = @ComponentScan.Filter(
|
||||
type = FilterType.ASSIGNABLE_TYPE,
|
||||
classes = {
|
||||
}
|
||||
))
|
||||
public class FileApplication {
|
||||
|
||||
public static void main(String[] args) {
|
@ -3,7 +3,8 @@ package com.qiwenshare.file.advice;
|
||||
import com.qiwenshare.common.exception.NotLoginException;
|
||||
import com.qiwenshare.common.result.RestResult;
|
||||
import com.qiwenshare.common.result.ResultCodeEnum;
|
||||
import com.qiwenshare.common.exception.UploadGeneralException;
|
||||
|
||||
import com.qiwenshare.ufo.exception.UploadException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
@ -50,10 +51,10 @@ public class GlobalExceptionHandlerAdvice {
|
||||
return RestResult.setResult(ResultCodeEnum.INDEX_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
@ExceptionHandler(UploadGeneralException.class)
|
||||
@ExceptionHandler(UploadException.class)
|
||||
@ResponseBody
|
||||
@ResponseStatus(HttpStatus.REQUEST_TIMEOUT)
|
||||
public RestResult error(UploadGeneralException e) {
|
||||
public RestResult error(UploadException e) {
|
||||
e.printStackTrace();
|
||||
log.error("全局异常捕获:" + e);
|
||||
return RestResult.setResult(ResultCodeEnum.REQUEST_TIMEOUT);
|
@ -1,17 +1,24 @@
|
||||
package com.qiwenshare.file.component;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.qiwenshare.common.constant.FileConstant;
|
||||
import com.qiwenshare.common.util.DateUtil;
|
||||
import com.qiwenshare.common.util.PathUtil;
|
||||
import com.qiwenshare.file.api.IElasticSearchService;
|
||||
import com.qiwenshare.file.config.es.FileSearch;
|
||||
import com.qiwenshare.file.domain.TreeNode;
|
||||
import com.qiwenshare.file.domain.UserFile;
|
||||
import com.qiwenshare.file.mapper.UserFileMapper;
|
||||
import com.qiwenshare.file.vo.file.FileListVo;
|
||||
import com.qiwenshare.ufo.util.PathUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* 文件逻辑处理组件
|
||||
@ -20,6 +27,8 @@ import java.util.Queue;
|
||||
public class FileDealComp {
|
||||
@Resource
|
||||
UserFileMapper userFileMapper;
|
||||
@Autowired
|
||||
private IElasticSearchService elasticSearchService;
|
||||
|
||||
/**
|
||||
* 获取重复文件名
|
||||
@ -209,4 +218,23 @@ public class FileDealComp {
|
||||
|
||||
return isExistPath;
|
||||
}
|
||||
|
||||
|
||||
public void uploadESByUserFileId(Long userFileId) {
|
||||
|
||||
UserFile userFile = new UserFile();
|
||||
userFile.setUserFileId(userFileId);
|
||||
List<FileListVo> userfileResult = userFileMapper.userFileList(userFile, null, null);
|
||||
if (userfileResult != null && userfileResult.size() > 0) {
|
||||
FileSearch fileSearch = new FileSearch();
|
||||
BeanUtil.copyProperties(userfileResult.get(0), fileSearch);
|
||||
elasticSearchService.save(fileSearch);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void deleteESByUserFileId(Long userFileId) {
|
||||
elasticSearchService.deleteById(userFileId);
|
||||
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.qiwenshare.common.config;
|
||||
package com.qiwenshare.file.config;
|
||||
|
||||
import com.github.tobato.fastdfs.FdfsClientConfig;
|
||||
import org.springframework.context.annotation.Configuration;
|
@ -1,4 +1,4 @@
|
||||
package com.qiwenshare.common.config;
|
||||
package com.qiwenshare.file.config;
|
||||
|
||||
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
@ -29,8 +29,8 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||
}
|
||||
/**
|
||||
* 设置 redisTemplate 的序列化设置
|
||||
* @param redisConnectionFactory
|
||||
* @return
|
||||
* @param redisConnectionFactory redis连接工厂
|
||||
* @return redisTemplate
|
||||
*/
|
||||
@Bean
|
||||
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
@ -1,28 +1,25 @@
|
||||
package com.qiwenshare.file.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.model.CopyObjectResult;
|
||||
import com.aliyun.oss.model.ObjectMetadata;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.qiwenshare.common.exception.NotLoginException;
|
||||
import com.qiwenshare.common.util.DateUtil;
|
||||
import com.qiwenshare.common.result.RestResult;
|
||||
import com.qiwenshare.common.domain.AliyunOSS;
|
||||
import com.qiwenshare.common.operation.FileOperation;
|
||||
import com.qiwenshare.common.util.FileUtil;
|
||||
import com.qiwenshare.common.util.PathUtil;
|
||||
import com.qiwenshare.file.anno.MyLog;
|
||||
import com.qiwenshare.file.api.*;
|
||||
import com.qiwenshare.common.config.QiwenFileConfig;
|
||||
import com.qiwenshare.file.component.FileDealComp;
|
||||
import com.qiwenshare.file.config.es.FileSearch;
|
||||
import com.qiwenshare.file.domain.*;
|
||||
import com.qiwenshare.file.dto.*;
|
||||
import com.qiwenshare.file.dto.file.*;
|
||||
import com.qiwenshare.file.vo.file.FileListVo;
|
||||
import com.qiwenshare.ufo.factory.UFOFactory;
|
||||
import com.qiwenshare.ufo.operation.rename.domain.RenameFile;
|
||||
import com.qiwenshare.ufo.util.PathUtil;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -57,14 +54,14 @@ public class FileController {
|
||||
IUserService userService;
|
||||
@Resource
|
||||
IUserFileService userFileService;
|
||||
@Resource
|
||||
UFOFactory ufoFactory;
|
||||
|
||||
@Autowired
|
||||
private ElasticsearchRestTemplate elasticsearchRestTemplate;
|
||||
@Resource
|
||||
FileDealComp fileDealComp;
|
||||
|
||||
@Resource
|
||||
QiwenFileConfig qiwenFileConfig;
|
||||
public static Executor executor = Executors.newFixedThreadPool(20);
|
||||
|
||||
public static final String CURRENT_MODULE = "文件接口";
|
||||
@ -97,6 +94,7 @@ public class FileController {
|
||||
userFile.setUploadTime(DateUtil.getCurrentTime());
|
||||
|
||||
userFileService.save(userFile);
|
||||
fileDealComp.uploadESByUserFileId(userFile.getUserFileId());
|
||||
return RestResult.success();
|
||||
}
|
||||
|
||||
@ -170,14 +168,14 @@ public class FileController {
|
||||
userFile.getFilePath() + userFile.getFileName() + "/", sessionUserBean.getUserId());
|
||||
} else {
|
||||
FileBean file = fileService.getById(userFile.getFileId());
|
||||
if (file.getIsOSS() == 1 || file.getStorageType() == 1) {
|
||||
if (file.getStorageType() == 1) {
|
||||
|
||||
String fileUrl = file.getFileUrl();
|
||||
String newFileUrl = fileUrl.replace(userFile.getFileName(), renameFileDto.getFileName());
|
||||
|
||||
rename(qiwenFileConfig.getAliyun().getOss(),
|
||||
fileUrl.substring(1),
|
||||
newFileUrl.substring(1));
|
||||
RenameFile renameFile = new RenameFile();
|
||||
renameFile.setSrcName(fileUrl.substring(1));
|
||||
renameFile.setDestName(newFileUrl.substring(1));
|
||||
ufoFactory.getRenamer(2).rename(renameFile);
|
||||
LambdaUpdateWrapper<FileBean> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
||||
lambdaUpdateWrapper
|
||||
.set(FileBean::getFileUrl, newFileUrl)
|
||||
@ -199,30 +197,11 @@ public class FileController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fileDealComp.uploadESByUserFileId(renameFileDto.getUserFileId());
|
||||
return RestResult.success();
|
||||
}
|
||||
|
||||
private void rename(AliyunOSS aliyunOSS, String sourceObjectName, String destinationObjectName) {
|
||||
String endpoint = aliyunOSS.getEndpoint();
|
||||
String accessKeyId = aliyunOSS.getAccessKeyId();
|
||||
String accessKeySecret = aliyunOSS.getAccessKeySecret();
|
||||
String bucketName = aliyunOSS.getBucketName();
|
||||
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
|
||||
CopyObjectResult result = ossClient.copyObject(bucketName, sourceObjectName, bucketName, destinationObjectName);
|
||||
|
||||
ossClient.deleteObject(bucketName, sourceObjectName);
|
||||
ObjectMetadata metadata = new ObjectMetadata();
|
||||
// if ("pdf".equals(FileUtil.getFileType(objectName))) {
|
||||
// metadata.setContentDisposition("attachment");
|
||||
// }
|
||||
|
||||
// ossClient.putObject(bucketName, objectName, inputStream, metadata);
|
||||
|
||||
|
||||
// 关闭OSSClient。
|
||||
ossClient.shutdown();
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "获取文件列表", description = "用来做前台列表展示", tags = {"file"})
|
||||
@ -231,19 +210,17 @@ public class FileController {
|
||||
public RestResult getFileList(FileListDTO fileListDto, @RequestHeader("token") String token){
|
||||
|
||||
UserFile userFile = new UserFile();
|
||||
if(qiwenFileConfig.isShareMode()){
|
||||
userFile.setUserId(2L);
|
||||
}else {
|
||||
UserBean sessionUserBean = userService.getUserBeanByToken(token);
|
||||
if (sessionUserBean == null) {
|
||||
throw new NotLoginException();
|
||||
}
|
||||
if (userFile == null) {
|
||||
return RestResult.fail();
|
||||
|
||||
}
|
||||
userFile.setUserId(sessionUserBean.getUserId());
|
||||
UserBean sessionUserBean = userService.getUserBeanByToken(token);
|
||||
if (sessionUserBean == null) {
|
||||
throw new NotLoginException();
|
||||
}
|
||||
if (userFile == null) {
|
||||
return RestResult.fail();
|
||||
|
||||
}
|
||||
userFile.setUserId(sessionUserBean.getUserId());
|
||||
|
||||
|
||||
List<FileListVo> fileList = null;
|
||||
userFile.setFilePath(PathUtil.urlDecode(fileListDto.getFilePath()));
|
||||
@ -290,6 +267,7 @@ public class FileController {
|
||||
|
||||
//userFile.setDeleteBatchNum(uuid);
|
||||
userFileService.deleteUserFile(userFile.getUserFileId(),sessionUserBean.getUserId());
|
||||
fileDealComp.deleteESByUserFileId(userFile.getUserFileId());
|
||||
}
|
||||
|
||||
return RestResult.success().message("批量删除文件成功");
|
||||
@ -310,7 +288,7 @@ public class FileController {
|
||||
throw new NotLoginException();
|
||||
}
|
||||
userFileService.deleteUserFile(deleteFileDto.getUserFileId(), sessionUserBean.getUserId());
|
||||
|
||||
fileDealComp.deleteESByUserFileId(deleteFileDto.getUserFileId());
|
||||
|
||||
return RestResult.success();
|
||||
|
||||
@ -459,13 +437,7 @@ public class FileController {
|
||||
result.setMessage("未登录");
|
||||
return result;
|
||||
}
|
||||
if (qiwenFileConfig.isShareMode()){
|
||||
if (sessionUserBean.getUserId() > 2){
|
||||
result.setSuccess(false);
|
||||
result.setMessage("没权限,请联系管理员!");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result.setSuccess(true);
|
||||
return result;
|
||||
}
|
||||
@ -480,9 +452,7 @@ public class FileController {
|
||||
throw new NotLoginException();
|
||||
}
|
||||
long userId = sessionUserBean.getUserId();
|
||||
if (qiwenFileConfig.isShareMode()){
|
||||
userId = 2;
|
||||
}
|
||||
|
||||
List<FileListVo> fileList = new ArrayList<>();
|
||||
Long beginCount = 0L;
|
||||
if (pageCount == null || currentPage == null) {
|
@ -1,6 +1,5 @@
|
||||
package com.qiwenshare.file.controller;
|
||||
|
||||
import com.qiwenshare.common.config.QiwenFileConfig;
|
||||
import com.qiwenshare.common.exception.NotLoginException;
|
||||
import com.qiwenshare.common.result.RestResult;
|
||||
import com.qiwenshare.common.util.DateUtil;
|
||||
@ -11,6 +10,7 @@ import com.qiwenshare.file.api.IFileService;
|
||||
import com.qiwenshare.file.api.IFiletransferService;
|
||||
import com.qiwenshare.file.api.IUserFileService;
|
||||
import com.qiwenshare.file.api.IUserService;
|
||||
import com.qiwenshare.file.component.FileDealComp;
|
||||
import com.qiwenshare.file.domain.FileBean;
|
||||
import com.qiwenshare.file.domain.StorageBean;
|
||||
import com.qiwenshare.file.domain.UserBean;
|
||||
@ -19,14 +19,10 @@ import com.qiwenshare.file.dto.DownloadFileDTO;
|
||||
import com.qiwenshare.file.dto.UploadFileDTO;
|
||||
import com.qiwenshare.file.dto.file.PreviewDTO;
|
||||
import com.qiwenshare.file.vo.file.UploadFileVo;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -49,14 +45,14 @@ public class FiletransferController {
|
||||
@Resource
|
||||
FileController fileController;
|
||||
|
||||
@Autowired
|
||||
QiwenFileConfig qiwenFileConfig;
|
||||
@Resource
|
||||
IFileService fileService;
|
||||
@Resource
|
||||
IUserService userService;
|
||||
@Resource
|
||||
IUserFileService userFileService;
|
||||
@Resource
|
||||
FileDealComp fileDealComp;
|
||||
public static final String CURRENT_MODULE = "文件传输接口";
|
||||
|
||||
@Operation(summary = "极速上传", description = "校验文件MD5判断文件是否存在,如果存在直接上传成功并返回skipUpload=true,如果不存在返回skipUpload=false需要再次调用该接口的POST方法", tags = {"filetransfer"})
|
||||
@ -95,7 +91,7 @@ public class FiletransferController {
|
||||
userFileService.save(userFile);
|
||||
fileService.increaseFilePointCount(file.getFileId());
|
||||
uploadFileVo.setSkipUpload(true);
|
||||
|
||||
fileDealComp.uploadESByUserFileId(userFile.getUserFileId());
|
||||
} else {
|
||||
uploadFileVo.setSkipUpload(false);
|
||||
|
||||
@ -121,6 +117,7 @@ public class FiletransferController {
|
||||
}
|
||||
|
||||
filetransferService.uploadFile(request, uploadFileDto, sessionUserBean.getUserId());
|
||||
|
||||
UploadFileVo uploadFileVo = new UploadFileVo();
|
||||
return RestResult.success().data(uploadFileVo);
|
||||
|
||||
@ -180,7 +177,8 @@ public class FiletransferController {
|
||||
filetransferService.downloadFile(httpServletResponse, downloadFileDTO);
|
||||
}catch (Exception e){
|
||||
//org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
|
||||
log.error("该异常忽略不做处理");
|
||||
e.printStackTrace();
|
||||
log.error("该异常忽略不做处理:" + e);
|
||||
}
|
||||
|
||||
}
|
||||
@ -195,11 +193,9 @@ public class FiletransferController {
|
||||
throw new NotLoginException();
|
||||
}
|
||||
StorageBean storageBean = new StorageBean();
|
||||
if (qiwenFileConfig.isShareMode()){
|
||||
storageBean.setUserId(2L);
|
||||
}else{
|
||||
storageBean.setUserId(sessionUserBean.getUserId());
|
||||
}
|
||||
|
||||
storageBean.setUserId(sessionUserBean.getUserId());
|
||||
|
||||
|
||||
Long storageSize = filetransferService.selectStorageSizeByUserId(sessionUserBean.getUserId());
|
||||
StorageBean storage = new StorageBean();
|
@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.qiwenshare.common.exception.NotLoginException;
|
||||
import com.qiwenshare.common.util.DateUtil;
|
||||
import com.qiwenshare.common.result.RestResult;
|
||||
import com.qiwenshare.common.util.PathUtil;
|
||||
import com.qiwenshare.file.anno.MyLog;
|
||||
import com.qiwenshare.file.api.IRecoveryFileService;
|
||||
import com.qiwenshare.file.api.IUserFileService;
|
@ -3,11 +3,9 @@ package com.qiwenshare.file.controller;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.qiwenshare.common.result.RestResult;
|
||||
import com.qiwenshare.common.domain.AliyunOSS;
|
||||
import com.qiwenshare.common.util.JjwtUtil;
|
||||
import com.qiwenshare.file.anno.MyLog;
|
||||
import com.qiwenshare.file.api.IUserService;
|
||||
import com.qiwenshare.common.config.QiwenFileConfig;
|
||||
import com.qiwenshare.file.domain.UserBean;
|
||||
import com.qiwenshare.file.dto.user.RegisterDTO;
|
||||
import com.qiwenshare.file.vo.user.UserLoginVo;
|
||||
@ -17,7 +15,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.crypto.hash.SimpleHash;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -34,8 +31,6 @@ public class UserController {
|
||||
@Resource
|
||||
IUserService userService;
|
||||
|
||||
@Autowired
|
||||
QiwenFileConfig qiwenFileConfig;
|
||||
|
||||
|
||||
public static Map<String, String> verificationCodeMap = new HashMap<>();
|
||||
@ -43,7 +38,6 @@ public class UserController {
|
||||
|
||||
public static final String CURRENT_MODULE = "用户管理";
|
||||
|
||||
|
||||
@Operation(summary = "用户注册", description = "注册账号", tags = {"user"})
|
||||
@PostMapping(value = "/register")
|
||||
@MyLog(operation = "用户注册", module = CURRENT_MODULE)
|
||||
@ -101,9 +95,6 @@ public class UserController {
|
||||
UserBean sessionUserBean = userService.getUserBeanByToken(token);
|
||||
if (sessionUserBean != null) {
|
||||
|
||||
AliyunOSS oss = qiwenFileConfig.getAliyun().getOss();
|
||||
String domain = oss.getDomain();
|
||||
sessionUserBean.setViewDomain(domain);
|
||||
return RestResult.success().data(sessionUserBean);
|
||||
|
||||
} else {
|
@ -33,9 +33,9 @@ public class FileBean {
|
||||
@Column(columnDefinition="bigint(10)")
|
||||
private Long fileSize;
|
||||
|
||||
@Column(columnDefinition="int(1)")
|
||||
@Deprecated
|
||||
private Integer isOSS;
|
||||
// @Column(columnDefinition="int(1)")
|
||||
// @Deprecated
|
||||
// private Integer isOSS;
|
||||
|
||||
@Column(columnDefinition="int(1)")
|
||||
private Integer storageType;
|
@ -7,4 +7,5 @@ import lombok.Data;
|
||||
@Schema(name = "下载文件DTO",required = true)
|
||||
public class DownloadFileDTO {
|
||||
private Long userFileId;
|
||||
private boolean isMin;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user