文件预览实现

This commit is contained in:
马超 2021-04-15 23:58:26 +08:00
parent b1e7033f05
commit e0d874706a
9 changed files with 192 additions and 57 deletions

View File

@ -3,7 +3,9 @@ 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);
}

View File

@ -53,6 +53,15 @@ public class AliyunOSSDownloader extends Downloader {
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();

View File

@ -4,12 +4,15 @@ 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 com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
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 {
@ -22,9 +25,6 @@ public class FastDFSDownloader extends Downloader {
DownloadByteArray downloadByteArray = new DownloadByteArray();
byte[] bytes = fastFileStorageClient.downloadFile(group, path, downloadByteArray);
// // 这里只是为了整合fastdfs所以写死了文件格式需要在上传的时候保存文件名下载的时候使用对应的格式
// response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("sb.xlsx", "UTF-8"));
// response.setCharacterEncoding("UTF-8");
ServletOutputStream outputStream = null;
try {
outputStream = httpServletResponse.getOutputStream();
@ -42,4 +42,14 @@ public class FastDFSDownloader extends Downloader {
}
}
}
@Override
public InputStream getInputStream(DownloadFile downloadFile) {
String group = downloadFile.getFileUrl().substring(0, downloadFile.getFileUrl().indexOf("/"));
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;
}
}

View File

@ -45,4 +45,18 @@ public class LocalStorageDownloader extends Downloader {
}
}
}
@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;
}
}

View File

@ -64,8 +64,8 @@ public class MimeUtils {
map.put("hqx","application/mac-binhex40");
map.put("hta","application/hta");
map.put("htc","text/x-component");
map.put("htm","text/html");
map.put("html","text/html");
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");
@ -96,6 +96,7 @@ public class MimeUtils {
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");

View File

@ -17,23 +17,27 @@ import com.qiwenshare.file.domain.UserBean;
import com.qiwenshare.file.domain.UserFile;
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.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Tag(name = "filetransfer", description = "该接口为文件传输接口,主要用来做文件的上传和下载")
@RestController
@RequestMapping("/filetransfer")
@ -138,17 +142,51 @@ public class FiletransferController {
@RequestMapping(value = "/downloadfile", method = RequestMethod.GET)
public void downloadFile(HttpServletResponse httpServletResponse, DownloadFileDTO downloadFileDTO) {
httpServletResponse.setContentType("application/force-download");// 设置强制下载不打开
UserFile userFile = userFileService.getById(downloadFileDTO.getUserFileId());
String fileName = userFile.getFileName() + "." + userFile.getExtendName();
try {
fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
httpServletResponse.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
filetransferService.downloadFile(httpServletResponse, downloadFileDTO);
}
@Operation(summary="预览文件", description="用于文件预览", tags = {"filetransfer"})
@GetMapping("/preview")
public void preview(HttpServletResponse httpServletResponse, DownloadFileDTO downloadFileDTO){
public void preview(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, PreviewDTO previewDTO){
UserFile userFile = userFileService.getById(downloadFileDTO.getUserFileId());
UserFile userFile = userFileService.getById(previewDTO.getUserFileId());
FileBean fileBean = fileService.getById(userFile.getFileId());
String mime= MimeUtils.getMime(userFile.getExtendName());
httpServletResponse.setContentType(mime);
filetransferService.downloadFile(httpServletResponse, downloadFileDTO);
// httpServletResponse.setContentType(mime);
httpServletResponse.setHeader("Content-Type", mime);
String rangeString = httpServletRequest.getHeader("Range");//如果是video标签发起的请求就不会为null
if (StringUtils.isNotEmpty(rangeString)) {
long range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));
httpServletResponse.setContentLength(Math.toIntExact(fileBean.getFileSize()));
httpServletResponse.setHeader("Content-Range", String.valueOf(range + (Math.toIntExact(fileBean.getFileSize()) - 1)));
}
httpServletResponse.setHeader("Accept-Ranges", "bytes");
String fileName = userFile.getFileName() + "." + userFile.getExtendName();
try {
fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
httpServletResponse.addHeader("Content-Disposition", "fileName=" + fileName);// 设置文件名
DownloadFileDTO downloadFileDTO = new DownloadFileDTO();
downloadFileDTO.setUserFileId(previewDTO.getUserFileId());
try {
filetransferService.downloadFile(httpServletResponse, downloadFileDTO);
}catch (Exception e){
//org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接
log.error("该异常忽略不做处理");
}
}

View File

@ -0,0 +1,10 @@
package com.qiwenshare.file.dto.file;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(name = "预览文件DTO",required = true)
public class PreviewDTO {
private Long userFileId;
}

View File

@ -1,7 +1,11 @@
package com.qiwenshare.file.service;
import java.io.UnsupportedEncodingException;
import java.io.*;
import java.util.List;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@ -20,6 +24,7 @@ import com.qiwenshare.common.operation.download.Downloader;
import com.qiwenshare.common.factory.FileOperationFactory;
import com.qiwenshare.common.operation.upload.Uploader;
import com.qiwenshare.common.util.PathUtil;
import com.qiwenshare.file.api.IFiletransferService;
import com.qiwenshare.common.config.QiwenFileConfig;
@ -130,35 +135,101 @@ public class FiletransferService implements IFiletransferService {
public void downloadFile(HttpServletResponse httpServletResponse, DownloadFileDTO downloadFileDTO) {
UserFile userFile = userFileMapper.selectById(downloadFileDTO.getUserFileId());
String fileName = userFile.getFileName() + "." + userFile.getExtendName();
try {
fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
httpServletResponse.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
if (userFile.getIsDir() == 0) {
FileBean fileBean = fileMapper.selectById(userFile.getFileId());
Downloader downloader = null;
if (fileBean.getIsOSS() != null && fileBean.getIsOSS() == 1) {
downloader = aliyunOSSOperationFactory.getDownloader();
} else if (fileBean.getStorageType() == 0) {
downloader = localStorageOperationFactory.getDownloader();
} else if (fileBean.getStorageType() == 1) {
downloader = aliyunOSSOperationFactory.getDownloader();
} else if (fileBean.getStorageType() == 2) {
downloader = fastDFSOperationFactory.getDownloader();
}
if (downloader == null) {
log.error("下载失败文件存储类型不支持下载storageType:{}, isOSS:{}", fileBean.getStorageType(), fileBean.getIsOSS());
throw new UploadGeneralException("下载失败");
}
DownloadFile uploadFile = new DownloadFile();
uploadFile.setFileUrl(fileBean.getFileUrl());
FileBean fileBean = fileMapper.selectById(userFile.getFileId());
Downloader downloader = null;
if (fileBean.getIsOSS() != null && fileBean.getIsOSS() == 1) {
downloader = aliyunOSSOperationFactory.getDownloader();
} else if (fileBean.getStorageType() == 0) {
downloader = localStorageOperationFactory.getDownloader();
} else if (fileBean.getStorageType() == 1) {
downloader = aliyunOSSOperationFactory.getDownloader();
} else if (fileBean.getStorageType() == 2) {
downloader = fastDFSOperationFactory.getDownloader();
}
if (downloader == null) {
log.error("下载失败文件存储类型不支持下载storageType:{}, isOSS:{}", fileBean.getStorageType(), fileBean.getIsOSS());
throw new UploadGeneralException("下载失败");
}
DownloadFile uploadFile = new DownloadFile();
uploadFile.setFileUrl(fileBean.getFileUrl());
// uploadFile.setTimeStampName(fileBean.getTimeStampName());
downloader.download(httpServletResponse, uploadFile);
downloader.download(httpServletResponse, uploadFile);
} else {
LambdaQueryWrapper<UserFile> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.likeRight(UserFile::getFilePath, userFile.getFilePath())
.eq(UserFile::getUserId, userFile.getUserId())
.eq(UserFile::getIsDir, 0)
.eq(UserFile::getDeleteFlag, 0);
List<UserFile> userFileList = userFileMapper.selectList(lambdaQueryWrapper);
String staticPath = PathUtil.getStaticPath();
String tempPath = staticPath + "temp" + File.separator;
File tempFile = new File(tempPath);
if (!tempFile.exists()) {
tempFile.mkdirs();
}
FileOutputStream f = null;
try {
f = new FileOutputStream(tempPath + userFile.getFileName() + ".zip");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
ZipOutputStream zos = new ZipOutputStream(csum);
BufferedOutputStream out = new BufferedOutputStream(zos);
zos.setComment("A test of Java Zipping");
for (UserFile userFile1 : userFileList) {
FileBean fileBean = fileMapper.selectById(userFile.getFileId());
Downloader downloader = null;
if (fileBean.getIsOSS() != null && fileBean.getIsOSS() == 1) {
downloader = aliyunOSSOperationFactory.getDownloader();
} else if (fileBean.getStorageType() == 0) {
downloader = localStorageOperationFactory.getDownloader();
} else if (fileBean.getStorageType() == 1) {
downloader = aliyunOSSOperationFactory.getDownloader();
} else if (fileBean.getStorageType() == 2) {
downloader = fastDFSOperationFactory.getDownloader();
}
if (downloader == null) {
log.error("下载失败文件存储类型不支持下载storageType:{}, isOSS:{}", fileBean.getStorageType(), fileBean.getIsOSS());
throw new UploadGeneralException("下载失败");
}
DownloadFile downloadFile = new DownloadFile();
downloadFile.setFileUrl(fileBean.getFileUrl());
InputStream inputStream = downloader.getInputStream(downloadFile);
BufferedInputStream bis = new BufferedInputStream(inputStream);
try {
zos.putNextEntry(new ZipEntry(userFile1.getFilePath()));
byte[] buffer = new byte[1024];
int i = bis.read(buffer);
while (i != -1) {
out.write(buffer, 0, i);
i = bis.read(buffer);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
@Override

20
pom.xml
View File

@ -92,25 +92,6 @@
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>fastjson</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.hibernate</groupId>-->
<!-- <artifactId>hibernate-core</artifactId>-->
<!-- <version>5.4.1.Final</version>-->
<!-- </dependency>-->
<!--阿里云短信验证服务-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>aliyun-java-sdk-core</artifactId>-->
<!-- <version>4.0.3</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
@ -123,7 +104,6 @@
<modules>
<module>file-common</module>
<module>file-web</module>
<!-- <module>file-office</module>-->
</modules>