diff --git a/file-common/src/main/java/com/qiwenshare/common/operation/download/Downloader.java b/file-common/src/main/java/com/qiwenshare/common/operation/download/Downloader.java index ab67fa8..61bf66d 100644 --- a/file-common/src/main/java/com/qiwenshare/common/operation/download/Downloader.java +++ b/file-common/src/main/java/com/qiwenshare/common/operation/download/Downloader.java @@ -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); } diff --git a/file-common/src/main/java/com/qiwenshare/common/operation/download/product/AliyunOSSDownloader.java b/file-common/src/main/java/com/qiwenshare/common/operation/download/product/AliyunOSSDownloader.java index 3284ad8..c5c430c 100644 --- a/file-common/src/main/java/com/qiwenshare/common/operation/download/product/AliyunOSSDownloader.java +++ b/file-common/src/main/java/com/qiwenshare/common/operation/download/product/AliyunOSSDownloader.java @@ -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(); diff --git a/file-common/src/main/java/com/qiwenshare/common/operation/download/product/FastDFSDownloader.java b/file-common/src/main/java/com/qiwenshare/common/operation/download/product/FastDFSDownloader.java index 37afcc7..19e6c3e 100644 --- a/file-common/src/main/java/com/qiwenshare/common/operation/download/product/FastDFSDownloader.java +++ b/file-common/src/main/java/com/qiwenshare/common/operation/download/product/FastDFSDownloader.java @@ -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; + } } diff --git a/file-common/src/main/java/com/qiwenshare/common/operation/download/product/LocalStorageDownloader.java b/file-common/src/main/java/com/qiwenshare/common/operation/download/product/LocalStorageDownloader.java index f424c9d..f08f855 100644 --- a/file-common/src/main/java/com/qiwenshare/common/operation/download/product/LocalStorageDownloader.java +++ b/file-common/src/main/java/com/qiwenshare/common/operation/download/product/LocalStorageDownloader.java @@ -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; + + } } diff --git a/file-common/src/main/java/com/qiwenshare/common/util/MimeUtils.java b/file-common/src/main/java/com/qiwenshare/common/util/MimeUtils.java index 4b02c0c..6ca33df 100644 --- a/file-common/src/main/java/com/qiwenshare/common/util/MimeUtils.java +++ b/file-common/src/main/java/com/qiwenshare/common/util/MimeUtils.java @@ -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"); diff --git a/file-web/src/main/java/com/qiwenshare/file/controller/FiletransferController.java b/file-web/src/main/java/com/qiwenshare/file/controller/FiletransferController.java index 9e191a7..0a24514 100644 --- a/file-web/src/main/java/com/qiwenshare/file/controller/FiletransferController.java +++ b/file-web/src/main/java/com/qiwenshare/file/controller/FiletransferController.java @@ -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("该异常忽略不做处理"); + } } diff --git a/file-web/src/main/java/com/qiwenshare/file/dto/file/PreviewDTO.java b/file-web/src/main/java/com/qiwenshare/file/dto/file/PreviewDTO.java new file mode 100644 index 0000000..529dfa3 --- /dev/null +++ b/file-web/src/main/java/com/qiwenshare/file/dto/file/PreviewDTO.java @@ -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; +} diff --git a/file-web/src/main/java/com/qiwenshare/file/service/FiletransferService.java b/file-web/src/main/java/com/qiwenshare/file/service/FiletransferService.java index 55cf1ca..e492643 100644 --- a/file-web/src/main/java/com/qiwenshare/file/service/FiletransferService.java +++ b/file-web/src/main/java/com/qiwenshare/file/service/FiletransferService.java @@ -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 lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.likeRight(UserFile::getFilePath, userFile.getFilePath()) + .eq(UserFile::getUserId, userFile.getUserId()) + .eq(UserFile::getIsDir, 0) + .eq(UserFile::getDeleteFlag, 0); + List 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 diff --git a/pom.xml b/pom.xml index 0a30ed3..fa44a75 100644 --- a/pom.xml +++ b/pom.xml @@ -92,25 +92,6 @@ mybatis-plus-boot-starter 3.4.1 - - - - - - - - - - - - - - - - - - - org.apache.shiro shiro-core @@ -123,7 +104,6 @@ file-common file-web -